diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-06-05 10:31:33 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:24 -0400 |
commit | 4a35bd41aff5714deb41c8f14766df3871e2e8f7 (patch) | |
tree | 3542c76b1e0aabcd0ee6bb76fdd8228e6f3b5479 /fs/nfs/inode.c | |
parent | ad389da79f7bf9dc12dbc79c9c2740f9ed2f13d1 (diff) |
NFSv4: Ensure that nfs4_do_close() doesn't race with umount
nfs4_do_close() does not currently have any way to ensure that the user
won't attempt to unmount the partition while the asynchronous RPC call
is completing. This again may cause Oopses in nfs_update_inode().
Add a vfsmount argument to nfs4_close_state to ensure that the partition
remains mounted while we're closing the file.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 19 |
1 files changed, 1 insertions, 18 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index cc7a9064be90..23ecf0334a18 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -490,7 +490,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
490 | spin_unlock(&inode->i_lock); | 490 | spin_unlock(&inode->i_lock); |
491 | } | 491 | } |
492 | if (ctx->state != NULL) | 492 | if (ctx->state != NULL) |
493 | nfs4_close_state(ctx->state, ctx->mode); | 493 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); |
494 | if (ctx->cred != NULL) | 494 | if (ctx->cred != NULL) |
495 | put_rpccred(ctx->cred); | 495 | put_rpccred(ctx->cred); |
496 | dput(ctx->path.dentry); | 496 | dput(ctx->path.dentry); |
@@ -1103,27 +1103,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1103 | */ | 1103 | */ |
1104 | void nfs4_clear_inode(struct inode *inode) | 1104 | void nfs4_clear_inode(struct inode *inode) |
1105 | { | 1105 | { |
1106 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1107 | |||
1108 | /* If we are holding a delegation, return it! */ | 1106 | /* If we are holding a delegation, return it! */ |
1109 | nfs_inode_return_delegation(inode); | 1107 | nfs_inode_return_delegation(inode); |
1110 | /* First call standard NFS clear_inode() code */ | 1108 | /* First call standard NFS clear_inode() code */ |
1111 | nfs_clear_inode(inode); | 1109 | nfs_clear_inode(inode); |
1112 | /* Now clear out any remaining state */ | ||
1113 | while (!list_empty(&nfsi->open_states)) { | ||
1114 | struct nfs4_state *state; | ||
1115 | |||
1116 | state = list_entry(nfsi->open_states.next, | ||
1117 | struct nfs4_state, | ||
1118 | inode_states); | ||
1119 | dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n", | ||
1120 | __FUNCTION__, | ||
1121 | inode->i_sb->s_id, | ||
1122 | (long long)NFS_FILEID(inode), | ||
1123 | state); | ||
1124 | BUG_ON(atomic_read(&state->count) != 1); | ||
1125 | nfs4_close_state(state, state->state); | ||
1126 | } | ||
1127 | } | 1110 | } |
1128 | #endif | 1111 | #endif |
1129 | 1112 | ||