aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:03 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:03 -0500
commitb92dccf65bab3b6b7deb79ff3321dc256eb0f53b (patch)
tree78a1436441bdfc1c2cc7928d9fdff50c0579013f /fs/nfs
parent7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff)
NFS: Fix a busy inodes issue...
The nfs_open_context may live longer than the file descriptor that spawned it, so it needs to carry a reference to the vfsmount. If not, then generic_shutdown_super() may end up being called before reads and writes have been flushed out. Make a couple of functions static while we're at it... Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/inode.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a77ee95b7efb..8d5b6691ae3d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -973,7 +973,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
973 return err; 973 return err;
974} 974}
975 975
976struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred) 976static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred)
977{ 977{
978 struct nfs_open_context *ctx; 978 struct nfs_open_context *ctx;
979 979
@@ -981,6 +981,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp
981 if (ctx != NULL) { 981 if (ctx != NULL) {
982 atomic_set(&ctx->count, 1); 982 atomic_set(&ctx->count, 1);
983 ctx->dentry = dget(dentry); 983 ctx->dentry = dget(dentry);
984 ctx->vfsmnt = mntget(mnt);
984 ctx->cred = get_rpccred(cred); 985 ctx->cred = get_rpccred(cred);
985 ctx->state = NULL; 986 ctx->state = NULL;
986 ctx->lockowner = current->files; 987 ctx->lockowner = current->files;
@@ -1011,6 +1012,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
1011 if (ctx->cred != NULL) 1012 if (ctx->cred != NULL)
1012 put_rpccred(ctx->cred); 1013 put_rpccred(ctx->cred);
1013 dput(ctx->dentry); 1014 dput(ctx->dentry);
1015 mntput(ctx->vfsmnt);
1014 kfree(ctx); 1016 kfree(ctx);
1015 } 1017 }
1016} 1018}
@@ -1019,7 +1021,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
1019 * Ensure that mmap has a recent RPC credential for use when writing out 1021 * Ensure that mmap has a recent RPC credential for use when writing out
1020 * shared pages 1022 * shared pages
1021 */ 1023 */
1022void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) 1024static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
1023{ 1025{
1024 struct inode *inode = filp->f_dentry->d_inode; 1026 struct inode *inode = filp->f_dentry->d_inode;
1025 struct nfs_inode *nfsi = NFS_I(inode); 1027 struct nfs_inode *nfsi = NFS_I(inode);
@@ -1051,7 +1053,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
1051 return ctx; 1053 return ctx;
1052} 1054}
1053 1055
1054void nfs_file_clear_open_context(struct file *filp) 1056static void nfs_file_clear_open_context(struct file *filp)
1055{ 1057{
1056 struct inode *inode = filp->f_dentry->d_inode; 1058 struct inode *inode = filp->f_dentry->d_inode;
1057 struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; 1059 struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data;
@@ -1076,7 +1078,7 @@ int nfs_open(struct inode *inode, struct file *filp)
1076 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); 1078 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
1077 if (IS_ERR(cred)) 1079 if (IS_ERR(cred))
1078 return PTR_ERR(cred); 1080 return PTR_ERR(cred);
1079 ctx = alloc_nfs_open_context(filp->f_dentry, cred); 1081 ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
1080 put_rpccred(cred); 1082 put_rpccred(cred);
1081 if (ctx == NULL) 1083 if (ctx == NULL)
1082 return -ENOMEM; 1084 return -ENOMEM;