提交 b92dccf6 编写于 作者: T Trond Myklebust

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: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 7705a879
...@@ -973,7 +973,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ...@@ -973,7 +973,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
return err; return err;
} }
struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred) static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred)
{ {
struct nfs_open_context *ctx; struct nfs_open_context *ctx;
...@@ -981,6 +981,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp ...@@ -981,6 +981,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp
if (ctx != NULL) { if (ctx != NULL) {
atomic_set(&ctx->count, 1); atomic_set(&ctx->count, 1);
ctx->dentry = dget(dentry); ctx->dentry = dget(dentry);
ctx->vfsmnt = mntget(mnt);
ctx->cred = get_rpccred(cred); ctx->cred = get_rpccred(cred);
ctx->state = NULL; ctx->state = NULL;
ctx->lockowner = current->files; ctx->lockowner = current->files;
...@@ -1011,6 +1012,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) ...@@ -1011,6 +1012,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
if (ctx->cred != NULL) if (ctx->cred != NULL)
put_rpccred(ctx->cred); put_rpccred(ctx->cred);
dput(ctx->dentry); dput(ctx->dentry);
mntput(ctx->vfsmnt);
kfree(ctx); kfree(ctx);
} }
} }
...@@ -1019,7 +1021,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) ...@@ -1019,7 +1021,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
* Ensure that mmap has a recent RPC credential for use when writing out * Ensure that mmap has a recent RPC credential for use when writing out
* shared pages * shared pages
*/ */
void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct nfs_inode *nfsi = NFS_I(inode); 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,7 +1053,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
return ctx; return ctx;
} }
void nfs_file_clear_open_context(struct file *filp) static void nfs_file_clear_open_context(struct file *filp)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; 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,7 +1078,7 @@ int nfs_open(struct inode *inode, struct file *filp)
cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
if (IS_ERR(cred)) if (IS_ERR(cred))
return PTR_ERR(cred); return PTR_ERR(cred);
ctx = alloc_nfs_open_context(filp->f_dentry, cred); ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
put_rpccred(cred); put_rpccred(cred);
if (ctx == NULL) if (ctx == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -78,6 +78,7 @@ struct nfs_access_entry { ...@@ -78,6 +78,7 @@ struct nfs_access_entry {
struct nfs4_state; struct nfs4_state;
struct nfs_open_context { struct nfs_open_context {
atomic_t count; atomic_t count;
struct vfsmount *vfsmnt;
struct dentry *dentry; struct dentry *dentry;
struct rpc_cred *cred; struct rpc_cred *cred;
struct nfs4_state *state; struct nfs4_state *state;
...@@ -311,12 +312,9 @@ extern void nfs_begin_attr_update(struct inode *); ...@@ -311,12 +312,9 @@ extern void nfs_begin_attr_update(struct inode *);
extern void nfs_end_attr_update(struct inode *); extern void nfs_end_attr_update(struct inode *);
extern void nfs_begin_data_update(struct inode *); extern void nfs_begin_data_update(struct inode *);
extern void nfs_end_data_update(struct inode *); extern void nfs_end_data_update(struct inode *);
extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred);
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
extern void put_nfs_open_context(struct nfs_open_context *ctx); extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode); extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
extern void nfs_file_clear_open_context(struct file *filp);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */ /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/ extern u32 root_nfs_parse_addr(char *name); /*__init*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册