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>
This commit is contained in:
parent
7705a8792b
commit
b92dccf65b
@ -973,7 +973,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||
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;
|
||||
|
||||
@ -981,6 +981,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp
|
||||
if (ctx != NULL) {
|
||||
atomic_set(&ctx->count, 1);
|
||||
ctx->dentry = dget(dentry);
|
||||
ctx->vfsmnt = mntget(mnt);
|
||||
ctx->cred = get_rpccred(cred);
|
||||
ctx->state = NULL;
|
||||
ctx->lockowner = current->files;
|
||||
@ -1011,6 +1012,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
|
||||
if (ctx->cred != NULL)
|
||||
put_rpccred(ctx->cred);
|
||||
dput(ctx->dentry);
|
||||
mntput(ctx->vfsmnt);
|
||||
kfree(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
|
||||
* 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 nfs_inode *nfsi = NFS_I(inode);
|
||||
@ -1051,7 +1053,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
|
||||
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 nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data;
|
||||
@ -1076,7 +1078,7 @@ int nfs_open(struct inode *inode, struct file *filp)
|
||||
cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
|
||||
if (IS_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);
|
||||
if (ctx == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -78,6 +78,7 @@ struct nfs_access_entry {
|
||||
struct nfs4_state;
|
||||
struct nfs_open_context {
|
||||
atomic_t count;
|
||||
struct vfsmount *vfsmnt;
|
||||
struct dentry *dentry;
|
||||
struct rpc_cred *cred;
|
||||
struct nfs4_state *state;
|
||||
@ -311,12 +312,9 @@ extern void nfs_begin_attr_update(struct inode *);
|
||||
extern void nfs_end_attr_update(struct inode *);
|
||||
extern void nfs_begin_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 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 void nfs_file_clear_open_context(struct file *filp);
|
||||
|
||||
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
|
||||
extern u32 root_nfs_parse_addr(char *name); /*__init*/
|
||||
|
Loading…
Reference in New Issue
Block a user