mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
NFSv4: Close another NFSv4 recovery race
State recovery currently relies on being able to find a valid nfs_open_context in the inode->open_files list. We therefore need to put the nfs_open_context on the list while we're still protected by the sp->so_reclaim_seqcount in order to avoid reboot races. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
275bb30786
commit
c45ffdd269
3 changed files with 18 additions and 6 deletions
|
@ -713,16 +713,23 @@ EXPORT_SYMBOL_GPL(put_nfs_open_context);
|
||||||
* 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)
|
void nfs_inode_attach_open_context(struct nfs_open_context *ctx)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = ctx->dentry->d_inode;
|
||||||
struct nfs_inode *nfsi = NFS_I(inode);
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
|
|
||||||
filp->private_data = get_nfs_open_context(ctx);
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
list_add(&ctx->list, &nfsi->open_files);
|
list_add(&ctx->list, &nfsi->open_files);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nfs_inode_attach_open_context);
|
||||||
|
|
||||||
|
void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
|
||||||
|
{
|
||||||
|
filp->private_data = get_nfs_open_context(ctx);
|
||||||
|
if (list_empty(&ctx->list))
|
||||||
|
nfs_inode_attach_open_context(ctx);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
|
EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -748,10 +755,11 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
|
||||||
|
|
||||||
static void nfs_file_clear_open_context(struct file *filp)
|
static void nfs_file_clear_open_context(struct file *filp)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filp);
|
|
||||||
struct nfs_open_context *ctx = nfs_file_open_context(filp);
|
struct nfs_open_context *ctx = nfs_file_open_context(filp);
|
||||||
|
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
|
struct inode *inode = ctx->dentry->d_inode;
|
||||||
|
|
||||||
filp->private_data = NULL;
|
filp->private_data = NULL;
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
|
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
|
||||||
|
|
|
@ -2002,8 +2002,11 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ctx->state = state;
|
ctx->state = state;
|
||||||
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
|
if (dentry->d_inode == state->inode) {
|
||||||
nfs4_schedule_stateid_recovery(server, state);
|
nfs_inode_attach_open_context(ctx);
|
||||||
|
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
|
||||||
|
nfs4_schedule_stateid_recovery(server, state);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,6 +356,7 @@ extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ct
|
||||||
extern void put_nfs_open_context(struct nfs_open_context *ctx);
|
extern void put_nfs_open_context(struct nfs_open_context *ctx);
|
||||||
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
|
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
|
||||||
extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode);
|
extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode);
|
||||||
|
extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
|
||||||
extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
|
extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
|
||||||
extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
|
extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
|
||||||
extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
|
extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue