diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-18 18:03:27 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-19 17:19:25 -0400 |
commit | a49c3c7736a2e77931dabc5bc4a83fb4b2da013e (patch) | |
tree | 1921900be210540ee53a4011c9e8f781deb0367e /fs/nfs/inode.c | |
parent | 565277f63c616e11c37309a1e98c052d18ebbb55 (diff) |
NFSv4: Ensure that we wait for the CLOSE request to complete
Otherwise, we do end up breaking close-to-open semantics. We also end up
breaking some of the silly-rename tests in Connectathon on some setups.
Please refer to the bug-report at
http://bugzilla.linux-nfs.org/show_bug.cgi?id=150
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 173e294dffc5..db5d96dc6107 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -514,7 +514,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | |||
514 | return ctx; | 514 | return ctx; |
515 | } | 515 | } |
516 | 516 | ||
517 | void put_nfs_open_context(struct nfs_open_context *ctx) | 517 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) |
518 | { | 518 | { |
519 | struct inode *inode = ctx->path.dentry->d_inode; | 519 | struct inode *inode = ctx->path.dentry->d_inode; |
520 | 520 | ||
@@ -522,8 +522,12 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
522 | return; | 522 | return; |
523 | list_del(&ctx->list); | 523 | list_del(&ctx->list); |
524 | spin_unlock(&inode->i_lock); | 524 | spin_unlock(&inode->i_lock); |
525 | if (ctx->state != NULL) | 525 | if (ctx->state != NULL) { |
526 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); | 526 | if (wait) |
527 | nfs4_close_sync(&ctx->path, ctx->state, ctx->mode); | ||
528 | else | ||
529 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); | ||
530 | } | ||
527 | if (ctx->cred != NULL) | 531 | if (ctx->cred != NULL) |
528 | put_rpccred(ctx->cred); | 532 | put_rpccred(ctx->cred); |
529 | dput(ctx->path.dentry); | 533 | dput(ctx->path.dentry); |
@@ -531,6 +535,16 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
531 | kfree(ctx); | 535 | kfree(ctx); |
532 | } | 536 | } |
533 | 537 | ||
538 | void put_nfs_open_context(struct nfs_open_context *ctx) | ||
539 | { | ||
540 | __put_nfs_open_context(ctx, 0); | ||
541 | } | ||
542 | |||
543 | static void put_nfs_open_context_sync(struct nfs_open_context *ctx) | ||
544 | { | ||
545 | __put_nfs_open_context(ctx, 1); | ||
546 | } | ||
547 | |||
534 | /* | 548 | /* |
535 | * Ensure that mmap has a recent RPC credential for use when writing out | 549 | * Ensure that mmap has a recent RPC credential for use when writing out |
536 | * shared pages | 550 | * shared pages |
@@ -577,7 +591,7 @@ static void nfs_file_clear_open_context(struct file *filp) | |||
577 | spin_lock(&inode->i_lock); | 591 | spin_lock(&inode->i_lock); |
578 | list_move_tail(&ctx->list, &NFS_I(inode)->open_files); | 592 | list_move_tail(&ctx->list, &NFS_I(inode)->open_files); |
579 | spin_unlock(&inode->i_lock); | 593 | spin_unlock(&inode->i_lock); |
580 | put_nfs_open_context(ctx); | 594 | put_nfs_open_context_sync(ctx); |
581 | } | 595 | } |
582 | } | 596 | } |
583 | 597 | ||