aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/pohmelfs
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/pohmelfs')
-rw-r--r--drivers/staging/pohmelfs/config.c101
-rw-r--r--drivers/staging/pohmelfs/crypto.c4
-rw-r--r--drivers/staging/pohmelfs/dir.c27
-rw-r--r--drivers/staging/pohmelfs/inode.c24
-rw-r--r--drivers/staging/pohmelfs/net.c20
-rw-r--r--drivers/staging/pohmelfs/netfs.h5
-rw-r--r--drivers/staging/pohmelfs/trans.c3
7 files changed, 140 insertions, 44 deletions
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index a6eaa42fb669..90f962ee5fd8 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -284,9 +284,91 @@ static int pohmelfs_cn_disp(struct cn_msg *msg)
i += 1;
}
+ out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_cn_dump(struct cn_msg *msg)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0, i = 1;
+ int total_msg = 0;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+ if (g)
+ total_msg += g->num_entry;
+ }
+ if (total_msg == 0) {
+ if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+ if (g) {
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+ if (pohmelfs_send_reply(err, total_msg - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ i += 1;
+ }
+ }
+ }
+
out_unlock:
- mutex_unlock(&pohmelfs_config_lock);
- return err;
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_cn_flush(struct cn_msg *msg)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ if (ctl->idx != POHMELFS_NULL_IDX) {
+ g = pohmelfs_find_config_group(ctl->idx);
+
+ if (!g)
+ goto out_unlock;
+
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ list_del(&c->config_entry);
+ g->num_entry--;
+ kfree(c);
+ }
+ } else {
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+ if (g) {
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ list_del(&c->config_entry);
+ g->num_entry--;
+ kfree(c);
+ }
+ }
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ pohmelfs_cn_dump(msg);
+
+ return err;
}
static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
@@ -350,7 +432,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
list_add_tail(&c->config_entry, &g->config_list);
-out_unlock:
+ out_unlock:
mutex_unlock(&pohmelfs_config_lock);
if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
err = -ENOMEM;
@@ -408,7 +490,6 @@ static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct p
return 0;
}
-
static int pohmelfs_cn_crypto(struct cn_msg *msg)
{
struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
@@ -446,9 +527,8 @@ out_unlock:
return err;
}
-static void pohmelfs_cn_callback(void *data)
+static void pohmelfs_cn_callback(struct cn_msg *msg)
{
- struct cn_msg *msg = data;
int err;
switch (msg->flags) {
@@ -457,9 +537,15 @@ static void pohmelfs_cn_callback(void *data)
case POHMELFS_FLAGS_MODIFY:
err = pohmelfs_cn_ctl(msg, msg->flags);
break;
+ case POHMELFS_FLAGS_FLUSH:
+ err = pohmelfs_cn_flush(msg);
+ break;
case POHMELFS_FLAGS_SHOW:
err = pohmelfs_cn_disp(msg);
break;
+ case POHMELFS_FLAGS_DUMP:
+ err = pohmelfs_cn_dump(msg);
+ break;
case POHMELFS_FLAGS_CRYPTO:
err = pohmelfs_cn_crypto(msg);
break;
@@ -498,7 +584,8 @@ int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
int __init pohmelfs_config_init(void)
{
- return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+ /* XXX remove (void *) cast when vanilla connector got synced */
+ return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
}
void pohmelfs_config_exit(void)
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
index 19781ad782fb..884183c0913a 100644
--- a/drivers/staging/pohmelfs/crypto.c
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -176,7 +176,7 @@ static int pohmelfs_crypto_process(struct ablkcipher_request *req,
timeout);
if (!err)
err = -ETIMEDOUT;
- else
+ else if (err > 0)
err = complete.error;
break;
default:
@@ -738,7 +738,7 @@ static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
psb->wait_on_page_timeout);
if (!err)
err = -ETIMEDOUT;
- else
+ else if (err > 0)
err = -psb->flags;
if (!err)
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
index 4c58e22c1fbe..6c5b261e9f06 100644
--- a/drivers/staging/pohmelfs/dir.c
+++ b/drivers/staging/pohmelfs/dir.c
@@ -352,7 +352,9 @@ static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
if (ret <= 0) {
- err = -ETIMEDOUT;
+ err = ret;
+ if (!err)
+ err = -ETIMEDOUT;
goto err_out_exit;
}
@@ -412,7 +414,7 @@ static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
__func__, file->f_pos, pi->ino, n->data, n->len,
n->ino, n->mode, mode, file->f_pos, n->hash);
- file->private_data = (void *)n->hash;
+ file->private_data = (void *)(unsigned long)n->hash;
len = n->len;
err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
@@ -472,10 +474,11 @@ static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
err = 0;
ret = wait_event_interruptible_timeout(psb->wait,
!test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
- if (ret == 0)
- err = -ETIMEDOUT;
- else if (signal_pending(current))
- err = -EINTR;
+ if (ret <= 0) {
+ err = ret;
+ if (!err)
+ err = -ETIMEDOUT;
+ }
if (err)
goto err_out_exit;
@@ -505,13 +508,21 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
struct pohmelfs_name *n;
struct inode *inode = NULL;
unsigned long ino = 0;
- int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+ int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1;
struct qstr str = dentry->d_name;
if ((nd->intent.open.flags & O_ACCMODE) > 1)
lock_type = POHMELFS_WRITE_LOCK;
- need_lock = pohmelfs_need_lock(parent, lock_type);
+ if (test_bit(NETFS_INODE_OWNED, &parent->state)) {
+ if (lock_type == parent->lock_type)
+ need_lock = 0;
+ if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK))
+ need_lock = 0;
+ }
+
+ if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state))
+ need_lock = 1;
str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index 7b605795b770..c94de3139223 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -921,16 +921,16 @@ ssize_t pohmelfs_write(struct file *file, const char __user *buf,
if (ret)
goto err_out_unlock;
- ret = generic_file_aio_write_nolock(&kiocb, &iov, 1, pos);
+ ret = __generic_file_aio_write(&kiocb, &iov, 1, &kiocb.ki_pos);
*ppos = kiocb.ki_pos;
mutex_unlock(&inode->i_mutex);
WARN_ON(ret < 0);
- if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+ if (ret > 0) {
ssize_t err;
- err = sync_page_range(inode, mapping, pos, ret);
+ err = generic_write_sync(file, pos, ret);
if (err < 0)
ret = err;
WARN_ON(ret < 0);
@@ -1504,7 +1504,9 @@ static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
inode->i_sb->s_op->write_inode(inode, 0);
}
+#ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH
truncate_inode_pages(inode->i_mapping, 0);
+#endif
pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
mutex_unlock(&inode->i_mutex);
@@ -1743,11 +1745,10 @@ static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
err = wait_event_interruptible_timeout(psb->wait,
(psb->flags != ~0),
psb->wait_on_page_timeout);
- if (!err) {
+ if (!err)
err = -ETIMEDOUT;
- } else {
+ else if (err > 0)
err = -psb->flags;
- }
if (err)
goto err_out_exit;
@@ -1865,7 +1866,7 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
INIT_LIST_HEAD(&psb->crypto_active_list);
atomic_set(&psb->trans_gen, 1);
- atomic_set(&psb->total_inodes, 0);
+ atomic_long_set(&psb->total_inodes, 0);
mutex_init(&psb->state_lock);
INIT_LIST_HEAD(&psb->state_list);
@@ -1950,14 +1951,7 @@ static int pohmelfs_get_sb(struct file_system_type *fs_type,
*/
static void pohmelfs_kill_super(struct super_block *sb)
{
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
- .range_start = 0,
- .range_end = LLONG_MAX,
- .nr_to_write = LONG_MAX,
- };
- generic_sync_sb_inodes(sb, &wbc);
-
+ sync_inodes_sb(sb);
kill_anon_super(sb);
}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
index 5f312c91aab6..af7f262e68c2 100644
--- a/drivers/staging/pohmelfs/net.c
+++ b/drivers/staging/pohmelfs/net.c
@@ -680,7 +680,7 @@ static int pohmelfs_root_cap_response(struct netfs_state *st)
printk(KERN_INFO "Mounting POHMELFS (%d) "
"with extended attributes support.\n", psb->idx);
- if (atomic_read(&psb->total_inodes) <= 1)
+ if (atomic_long_read(&psb->total_inodes) <= 1)
atomic_long_set(&psb->total_inodes, cap->nr_files);
dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
@@ -1005,13 +1005,12 @@ int netfs_state_init(struct netfs_state *st)
if (st->socket->ops->family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
- printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
- NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
+ &sin->sin_addr.s_addr, ntohs(sin->sin_port));
} else if (st->socket->ops->family == AF_INET6) {
struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
- printk(KERN_INFO "%s: (re)connected to peer "
- "%pi6:%d",
- __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
+ &sin->sin6_addr, ntohs(sin->sin6_port));
}
return 0;
@@ -1031,13 +1030,12 @@ void netfs_state_exit(struct netfs_state *st)
if (st->socket->ops->family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
- printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
- NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
+ &sin->sin_addr.s_addr, ntohs(sin->sin_port));
} else if (st->socket->ops->family == AF_INET6) {
struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
- printk("%s: disconnected from peer "
- "%pi6:%d",
- __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
+ &sin->sin6_addr, ntohs(sin->sin6_port));
}
sock_release(st->socket);
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
index 3b60c611ba80..623a07d29dea 100644
--- a/drivers/staging/pohmelfs/netfs.h
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -25,6 +25,7 @@
#define POHMELFS_CTLINFO_ACK 1
#define POHMELFS_NOINFO_ACK 2
+#define POHMELFS_NULL_IDX 65535
/*
* Network command structure.
@@ -87,6 +88,8 @@ enum {
POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */
POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */
POHMELFS_FLAGS_MODIFY, /* Network state modification message */
+ POHMELFS_FLAGS_DUMP, /* Network state control message for SHOW ALL */
+ POHMELFS_FLAGS_FLUSH, /* Network state control message for FLUSH */
};
/*
@@ -905,6 +908,8 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
pohmelfs_mcache_free(psb, m);
}
+//#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
+
#endif /* __KERNEL__*/
#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
index 4587f6d546aa..36a253582565 100644
--- a/drivers/staging/pohmelfs/trans.c
+++ b/drivers/staging/pohmelfs/trans.c
@@ -468,7 +468,8 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
continue;
}
- if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio))
+ if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) &&
+ (t->flags & NETFS_TRANS_SINGLE_DST))
st = &psb->active_state->state;
err = netfs_trans_push(t, st);