diff options
author | Evgeniy Polyakov <zbr@ioremap.net> | 2009-08-28 09:57:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 15:02:30 -0400 |
commit | 2d7cf8ef75abbe0d33d9115872d4545e9cefced2 (patch) | |
tree | 3446950a70190ec909b6a447e9a0e714004956d5 | |
parent | 252a1b9162b6dbac7324854eb4137404932b574d (diff) |
Staging: pohmelfs: sync with the development tree
* cache coherency protocol fix
* proper timeout handling
* implement dump/del all config group command
(Signed-off-by: Pierpaolo Giacomin <yrz@anche.no>)
Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/pohmelfs/config.c | 98 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/crypto.c | 4 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/dir.c | 25 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/inode.c | 7 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/net.c | 18 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/netfs.h | 5 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/trans.c | 3 |
7 files changed, 132 insertions, 28 deletions
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 99ae1d9649a0..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) | |||
284 | i += 1; | 284 | i += 1; |
285 | } | 285 | } |
286 | 286 | ||
287 | out_unlock: | ||
288 | mutex_unlock(&pohmelfs_config_lock); | ||
289 | return err; | ||
290 | } | ||
291 | |||
292 | static int pohmelfs_cn_dump(struct cn_msg *msg) | ||
293 | { | ||
294 | struct pohmelfs_config_group *g; | ||
295 | struct pohmelfs_config *c, *tmp; | ||
296 | int err = 0, i = 1; | ||
297 | int total_msg = 0; | ||
298 | |||
299 | if (msg->len != sizeof(struct pohmelfs_ctl)) | ||
300 | return -EBADMSG; | ||
301 | |||
302 | mutex_lock(&pohmelfs_config_lock); | ||
303 | |||
304 | list_for_each_entry(g, &pohmelfs_config_list, group_entry) { | ||
305 | if (g) | ||
306 | total_msg += g->num_entry; | ||
307 | } | ||
308 | if (total_msg == 0) { | ||
309 | if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL)) | ||
310 | err = -ENOMEM; | ||
311 | goto out_unlock; | ||
312 | } | ||
313 | |||
314 | list_for_each_entry(g, &pohmelfs_config_list, group_entry) { | ||
315 | if (g) { | ||
316 | list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) { | ||
317 | struct pohmelfs_ctl *sc = &c->state.ctl; | ||
318 | if (pohmelfs_send_reply(err, total_msg - i, POHMELFS_CTLINFO_ACK, msg, sc)) { | ||
319 | err = -ENOMEM; | ||
320 | goto out_unlock; | ||
321 | } | ||
322 | i += 1; | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
287 | out_unlock: | 327 | out_unlock: |
288 | mutex_unlock(&pohmelfs_config_lock); | 328 | mutex_unlock(&pohmelfs_config_lock); |
289 | return err; | 329 | return err; |
330 | } | ||
331 | |||
332 | static int pohmelfs_cn_flush(struct cn_msg *msg) | ||
333 | { | ||
334 | struct pohmelfs_config_group *g; | ||
335 | struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data; | ||
336 | struct pohmelfs_config *c, *tmp; | ||
337 | int err = 0; | ||
338 | |||
339 | if (msg->len != sizeof(struct pohmelfs_ctl)) | ||
340 | return -EBADMSG; | ||
341 | |||
342 | mutex_lock(&pohmelfs_config_lock); | ||
343 | |||
344 | if (ctl->idx != POHMELFS_NULL_IDX) { | ||
345 | g = pohmelfs_find_config_group(ctl->idx); | ||
346 | |||
347 | if (!g) | ||
348 | goto out_unlock; | ||
349 | |||
350 | list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) { | ||
351 | list_del(&c->config_entry); | ||
352 | g->num_entry--; | ||
353 | kfree(c); | ||
354 | } | ||
355 | } else { | ||
356 | list_for_each_entry(g, &pohmelfs_config_list, group_entry) { | ||
357 | if (g) { | ||
358 | list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) { | ||
359 | list_del(&c->config_entry); | ||
360 | g->num_entry--; | ||
361 | kfree(c); | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | out_unlock: | ||
368 | mutex_unlock(&pohmelfs_config_lock); | ||
369 | pohmelfs_cn_dump(msg); | ||
370 | |||
371 | return err; | ||
290 | } | 372 | } |
291 | 373 | ||
292 | static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new) | 374 | 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) | |||
350 | 432 | ||
351 | list_add_tail(&c->config_entry, &g->config_list); | 433 | list_add_tail(&c->config_entry, &g->config_list); |
352 | 434 | ||
353 | out_unlock: | 435 | out_unlock: |
354 | mutex_unlock(&pohmelfs_config_lock); | 436 | mutex_unlock(&pohmelfs_config_lock); |
355 | if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL)) | 437 | if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL)) |
356 | err = -ENOMEM; | 438 | err = -ENOMEM; |
@@ -408,7 +490,6 @@ static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct p | |||
408 | return 0; | 490 | return 0; |
409 | } | 491 | } |
410 | 492 | ||
411 | |||
412 | static int pohmelfs_cn_crypto(struct cn_msg *msg) | 493 | static int pohmelfs_cn_crypto(struct cn_msg *msg) |
413 | { | 494 | { |
414 | struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data; | 495 | struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data; |
@@ -456,9 +537,15 @@ static void pohmelfs_cn_callback(struct cn_msg *msg) | |||
456 | case POHMELFS_FLAGS_MODIFY: | 537 | case POHMELFS_FLAGS_MODIFY: |
457 | err = pohmelfs_cn_ctl(msg, msg->flags); | 538 | err = pohmelfs_cn_ctl(msg, msg->flags); |
458 | break; | 539 | break; |
540 | case POHMELFS_FLAGS_FLUSH: | ||
541 | err = pohmelfs_cn_flush(msg); | ||
542 | break; | ||
459 | case POHMELFS_FLAGS_SHOW: | 543 | case POHMELFS_FLAGS_SHOW: |
460 | err = pohmelfs_cn_disp(msg); | 544 | err = pohmelfs_cn_disp(msg); |
461 | break; | 545 | break; |
546 | case POHMELFS_FLAGS_DUMP: | ||
547 | err = pohmelfs_cn_dump(msg); | ||
548 | break; | ||
462 | case POHMELFS_FLAGS_CRYPTO: | 549 | case POHMELFS_FLAGS_CRYPTO: |
463 | err = pohmelfs_cn_crypto(msg); | 550 | err = pohmelfs_cn_crypto(msg); |
464 | break; | 551 | break; |
@@ -497,7 +584,8 @@ int pohmelfs_config_check(struct pohmelfs_config *config, int idx) | |||
497 | 584 | ||
498 | int __init pohmelfs_config_init(void) | 585 | int __init pohmelfs_config_init(void) |
499 | { | 586 | { |
500 | return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback); | 587 | /* XXX remove (void *) cast when vanilla connector got synced */ |
588 | return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback); | ||
501 | } | 589 | } |
502 | 590 | ||
503 | void pohmelfs_config_exit(void) | 591 | 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, | |||
176 | timeout); | 176 | timeout); |
177 | if (!err) | 177 | if (!err) |
178 | err = -ETIMEDOUT; | 178 | err = -ETIMEDOUT; |
179 | else | 179 | else if (err > 0) |
180 | err = complete.error; | 180 | err = complete.error; |
181 | break; | 181 | break; |
182 | default: | 182 | default: |
@@ -738,7 +738,7 @@ static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb) | |||
738 | psb->wait_on_page_timeout); | 738 | psb->wait_on_page_timeout); |
739 | if (!err) | 739 | if (!err) |
740 | err = -ETIMEDOUT; | 740 | err = -ETIMEDOUT; |
741 | else | 741 | else if (err > 0) |
742 | err = -psb->flags; | 742 | err = -psb->flags; |
743 | 743 | ||
744 | if (!err) | 744 | if (!err) |
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 4c63a4cc1bd4..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) | |||
352 | test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret); | 352 | test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret); |
353 | dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error); | 353 | dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error); |
354 | if (ret <= 0) { | 354 | if (ret <= 0) { |
355 | err = -ETIMEDOUT; | 355 | err = ret; |
356 | if (!err) | ||
357 | err = -ETIMEDOUT; | ||
356 | goto err_out_exit; | 358 | goto err_out_exit; |
357 | } | 359 | } |
358 | 360 | ||
@@ -472,10 +474,11 @@ static int pohmelfs_lookup_single(struct pohmelfs_inode *parent, | |||
472 | err = 0; | 474 | err = 0; |
473 | ret = wait_event_interruptible_timeout(psb->wait, | 475 | ret = wait_event_interruptible_timeout(psb->wait, |
474 | !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret); | 476 | !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret); |
475 | if (ret == 0) | 477 | if (ret <= 0) { |
476 | err = -ETIMEDOUT; | 478 | err = ret; |
477 | else if (signal_pending(current)) | 479 | if (!err) |
478 | err = -EINTR; | 480 | err = -ETIMEDOUT; |
481 | } | ||
479 | 482 | ||
480 | if (err) | 483 | if (err) |
481 | goto err_out_exit; | 484 | goto err_out_exit; |
@@ -505,13 +508,21 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
505 | struct pohmelfs_name *n; | 508 | struct pohmelfs_name *n; |
506 | struct inode *inode = NULL; | 509 | struct inode *inode = NULL; |
507 | unsigned long ino = 0; | 510 | unsigned long ino = 0; |
508 | int err, lock_type = POHMELFS_READ_LOCK, need_lock; | 511 | int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1; |
509 | struct qstr str = dentry->d_name; | 512 | struct qstr str = dentry->d_name; |
510 | 513 | ||
511 | if ((nd->intent.open.flags & O_ACCMODE) > 1) | 514 | if ((nd->intent.open.flags & O_ACCMODE) > 1) |
512 | lock_type = POHMELFS_WRITE_LOCK; | 515 | lock_type = POHMELFS_WRITE_LOCK; |
513 | 516 | ||
514 | need_lock = pohmelfs_need_lock(parent, lock_type); | 517 | if (test_bit(NETFS_INODE_OWNED, &parent->state)) { |
518 | if (lock_type == parent->lock_type) | ||
519 | need_lock = 0; | ||
520 | if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK)) | ||
521 | need_lock = 0; | ||
522 | } | ||
523 | |||
524 | if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state)) | ||
525 | need_lock = 1; | ||
515 | 526 | ||
516 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); | 527 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); |
517 | 528 | ||
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 0b58f1043707..c94de3139223 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c | |||
@@ -1504,7 +1504,9 @@ static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count) | |||
1504 | inode->i_sb->s_op->write_inode(inode, 0); | 1504 | inode->i_sb->s_op->write_inode(inode, 0); |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | #ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH | ||
1507 | truncate_inode_pages(inode->i_mapping, 0); | 1508 | truncate_inode_pages(inode->i_mapping, 0); |
1509 | #endif | ||
1508 | 1510 | ||
1509 | pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK); | 1511 | pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK); |
1510 | mutex_unlock(&inode->i_mutex); | 1512 | mutex_unlock(&inode->i_mutex); |
@@ -1743,11 +1745,10 @@ static int pohmelfs_root_handshake(struct pohmelfs_sb *psb) | |||
1743 | err = wait_event_interruptible_timeout(psb->wait, | 1745 | err = wait_event_interruptible_timeout(psb->wait, |
1744 | (psb->flags != ~0), | 1746 | (psb->flags != ~0), |
1745 | psb->wait_on_page_timeout); | 1747 | psb->wait_on_page_timeout); |
1746 | if (!err) { | 1748 | if (!err) |
1747 | err = -ETIMEDOUT; | 1749 | err = -ETIMEDOUT; |
1748 | } else { | 1750 | else if (err > 0) |
1749 | err = -psb->flags; | 1751 | err = -psb->flags; |
1750 | } | ||
1751 | 1752 | ||
1752 | if (err) | 1753 | if (err) |
1753 | goto err_out_exit; | 1754 | goto err_out_exit; |
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c index bdaab6905fde..af7f262e68c2 100644 --- a/drivers/staging/pohmelfs/net.c +++ b/drivers/staging/pohmelfs/net.c | |||
@@ -1005,13 +1005,12 @@ int netfs_state_init(struct netfs_state *st) | |||
1005 | 1005 | ||
1006 | if (st->socket->ops->family == AF_INET) { | 1006 | if (st->socket->ops->family == AF_INET) { |
1007 | struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr; | 1007 | struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr; |
1008 | printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__, | 1008 | printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__, |
1009 | NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | 1009 | &sin->sin_addr.s_addr, ntohs(sin->sin_port)); |
1010 | } else if (st->socket->ops->family == AF_INET6) { | 1010 | } else if (st->socket->ops->family == AF_INET6) { |
1011 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr; | 1011 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr; |
1012 | printk(KERN_INFO "%s: (re)connected to peer " | 1012 | printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__, |
1013 | "%pi6:%d", | 1013 | &sin->sin6_addr, ntohs(sin->sin6_port)); |
1014 | __func__, &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
1015 | } | 1014 | } |
1016 | 1015 | ||
1017 | return 0; | 1016 | return 0; |
@@ -1031,13 +1030,12 @@ void netfs_state_exit(struct netfs_state *st) | |||
1031 | 1030 | ||
1032 | if (st->socket->ops->family == AF_INET) { | 1031 | if (st->socket->ops->family == AF_INET) { |
1033 | struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; | 1032 | struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; |
1034 | printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__, | 1033 | printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__, |
1035 | NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | 1034 | &sin->sin_addr.s_addr, ntohs(sin->sin_port)); |
1036 | } else if (st->socket->ops->family == AF_INET6) { | 1035 | } else if (st->socket->ops->family == AF_INET6) { |
1037 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; | 1036 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; |
1038 | printk("%s: disconnected from peer " | 1037 | printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__, |
1039 | "%pi6:%d", | 1038 | &sin->sin6_addr, ntohs(sin->sin6_port)); |
1040 | __func__, &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
1041 | } | 1039 | } |
1042 | 1040 | ||
1043 | sock_release(st->socket); | 1041 | 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 @@ | |||
25 | #define POHMELFS_CTLINFO_ACK 1 | 25 | #define POHMELFS_CTLINFO_ACK 1 |
26 | #define POHMELFS_NOINFO_ACK 2 | 26 | #define POHMELFS_NOINFO_ACK 2 |
27 | 27 | ||
28 | #define POHMELFS_NULL_IDX 65535 | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Network command structure. | 31 | * Network command structure. |
@@ -87,6 +88,8 @@ enum { | |||
87 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ | 88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ |
88 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ | 89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ |
89 | POHMELFS_FLAGS_MODIFY, /* Network state modification message */ | 90 | POHMELFS_FLAGS_MODIFY, /* Network state modification message */ |
91 | POHMELFS_FLAGS_DUMP, /* Network state control message for SHOW ALL */ | ||
92 | POHMELFS_FLAGS_FLUSH, /* Network state control message for FLUSH */ | ||
90 | }; | 93 | }; |
91 | 94 | ||
92 | /* | 95 | /* |
@@ -905,6 +908,8 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb, | |||
905 | pohmelfs_mcache_free(psb, m); | 908 | pohmelfs_mcache_free(psb, m); |
906 | } | 909 | } |
907 | 910 | ||
911 | //#define POHMELFS_TRUNCATE_ON_INODE_FLUSH | ||
912 | |||
908 | #endif /* __KERNEL__*/ | 913 | #endif /* __KERNEL__*/ |
909 | 914 | ||
910 | #endif /* __NETFS_H */ | 915 | #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) | |||
468 | continue; | 468 | continue; |
469 | } | 469 | } |
470 | 470 | ||
471 | if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio)) | 471 | if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) && |
472 | (t->flags & NETFS_TRANS_SINGLE_DST)) | ||
472 | st = &psb->active_state->state; | 473 | st = &psb->active_state->state; |
473 | 474 | ||
474 | err = netfs_trans_push(t, st); | 475 | err = netfs_trans_push(t, st); |