aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-13 12:51:01 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-14 15:09:33 -0400
commit8535b2be5181fc3019e4150567ef53210fe3b04f (patch)
treeba366f5304f12876f1e45d3c2b423d12f9ec0c90 /fs/nfs/nfs4proc.c
parent712a4338669d7d57f952244abb608e6ac07e39da (diff)
NFSv4: Don't use GFP_KERNEL allocations in state recovery
We do not want to have the state recovery thread kick off and wait for a memory reclaim, since that may deadlock when the writebacks end up waiting for the state recovery thread to complete. The safe thing is therefore to use GFP_NOFS in all open, close, delegation return, lock, etc. operations that may be called by the state recovery thread. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9998c2958103..70015dd60a98 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -717,17 +717,18 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
717 717
718static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, 718static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
719 struct nfs4_state_owner *sp, fmode_t fmode, int flags, 719 struct nfs4_state_owner *sp, fmode_t fmode, int flags,
720 const struct iattr *attrs) 720 const struct iattr *attrs,
721 gfp_t gfp_mask)
721{ 722{
722 struct dentry *parent = dget_parent(path->dentry); 723 struct dentry *parent = dget_parent(path->dentry);
723 struct inode *dir = parent->d_inode; 724 struct inode *dir = parent->d_inode;
724 struct nfs_server *server = NFS_SERVER(dir); 725 struct nfs_server *server = NFS_SERVER(dir);
725 struct nfs4_opendata *p; 726 struct nfs4_opendata *p;
726 727
727 p = kzalloc(sizeof(*p), GFP_KERNEL); 728 p = kzalloc(sizeof(*p), gfp_mask);
728 if (p == NULL) 729 if (p == NULL)
729 goto err; 730 goto err;
730 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); 731 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
731 if (p->o_arg.seqid == NULL) 732 if (p->o_arg.seqid == NULL)
732 goto err_free; 733 goto err_free;
733 path_get(path); 734 path_get(path);
@@ -1063,7 +1064,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
1063{ 1064{
1064 struct nfs4_opendata *opendata; 1065 struct nfs4_opendata *opendata;
1065 1066
1066 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL); 1067 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS);
1067 if (opendata == NULL) 1068 if (opendata == NULL)
1068 return ERR_PTR(-ENOMEM); 1069 return ERR_PTR(-ENOMEM);
1069 opendata->state = state; 1070 opendata->state = state;
@@ -1651,7 +1652,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
1651 if (path->dentry->d_inode != NULL) 1652 if (path->dentry->d_inode != NULL)
1652 nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); 1653 nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode);
1653 status = -ENOMEM; 1654 status = -ENOMEM;
1654 opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr); 1655 opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL);
1655 if (opendata == NULL) 1656 if (opendata == NULL)
1656 goto err_put_state_owner; 1657 goto err_put_state_owner;
1657 1658
@@ -1926,7 +1927,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
1926 * 1927 *
1927 * NOTE: Caller must be holding the sp->so_owner semaphore! 1928 * NOTE: Caller must be holding the sp->so_owner semaphore!
1928 */ 1929 */
1929int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) 1930int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait)
1930{ 1931{
1931 struct nfs_server *server = NFS_SERVER(state->inode); 1932 struct nfs_server *server = NFS_SERVER(state->inode);
1932 struct nfs4_closedata *calldata; 1933 struct nfs4_closedata *calldata;
@@ -1945,7 +1946,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1945 }; 1946 };
1946 int status = -ENOMEM; 1947 int status = -ENOMEM;
1947 1948
1948 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); 1949 calldata = kzalloc(sizeof(*calldata), gfp_mask);
1949 if (calldata == NULL) 1950 if (calldata == NULL)
1950 goto out; 1951 goto out;
1951 calldata->inode = state->inode; 1952 calldata->inode = state->inode;
@@ -1953,7 +1954,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1953 calldata->arg.fh = NFS_FH(state->inode); 1954 calldata->arg.fh = NFS_FH(state->inode);
1954 calldata->arg.stateid = &state->open_stateid; 1955 calldata->arg.stateid = &state->open_stateid;
1955 /* Serialization for the sequence id */ 1956 /* Serialization for the sequence id */
1956 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1957 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid, gfp_mask);
1957 if (calldata->arg.seqid == NULL) 1958 if (calldata->arg.seqid == NULL)
1958 goto out_free_calldata; 1959 goto out_free_calldata;
1959 calldata->arg.fmode = 0; 1960 calldata->arg.fmode = 0;
@@ -3704,7 +3705,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3704 }; 3705 };
3705 int status = 0; 3706 int status = 0;
3706 3707
3707 data = kzalloc(sizeof(*data), GFP_KERNEL); 3708 data = kzalloc(sizeof(*data), GFP_NOFS);
3708 if (data == NULL) 3709 if (data == NULL)
3709 return -ENOMEM; 3710 return -ENOMEM;
3710 data->args.fhandle = &data->fh; 3711 data->args.fhandle = &data->fh;
@@ -3860,7 +3861,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3860 struct nfs4_unlockdata *p; 3861 struct nfs4_unlockdata *p;
3861 struct inode *inode = lsp->ls_state->inode; 3862 struct inode *inode = lsp->ls_state->inode;
3862 3863
3863 p = kzalloc(sizeof(*p), GFP_KERNEL); 3864 p = kzalloc(sizeof(*p), GFP_NOFS);
3864 if (p == NULL) 3865 if (p == NULL)
3865 return NULL; 3866 return NULL;
3866 p->arg.fh = NFS_FH(inode); 3867 p->arg.fh = NFS_FH(inode);
@@ -3998,7 +3999,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3998 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) 3999 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3999 goto out; 4000 goto out;
4000 lsp = request->fl_u.nfs4_fl.owner; 4001 lsp = request->fl_u.nfs4_fl.owner;
4001 seqid = nfs_alloc_seqid(&lsp->ls_seqid); 4002 seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL);
4002 status = -ENOMEM; 4003 status = -ENOMEM;
4003 if (seqid == NULL) 4004 if (seqid == NULL)
4004 goto out; 4005 goto out;
@@ -4026,22 +4027,23 @@ struct nfs4_lockdata {
4026}; 4027};
4027 4028
4028static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, 4029static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
4029 struct nfs_open_context *ctx, struct nfs4_lock_state *lsp) 4030 struct nfs_open_context *ctx, struct nfs4_lock_state *lsp,
4031 gfp_t gfp_mask)
4030{ 4032{
4031 struct nfs4_lockdata *p; 4033 struct nfs4_lockdata *p;
4032 struct inode *inode = lsp->ls_state->inode; 4034 struct inode *inode = lsp->ls_state->inode;
4033 struct nfs_server *server = NFS_SERVER(inode); 4035 struct nfs_server *server = NFS_SERVER(inode);
4034 4036
4035 p = kzalloc(sizeof(*p), GFP_KERNEL); 4037 p = kzalloc(sizeof(*p), gfp_mask);
4036 if (p == NULL) 4038 if (p == NULL)
4037 return NULL; 4039 return NULL;
4038 4040
4039 p->arg.fh = NFS_FH(inode); 4041 p->arg.fh = NFS_FH(inode);
4040 p->arg.fl = &p->fl; 4042 p->arg.fl = &p->fl;
4041 p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); 4043 p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask);
4042 if (p->arg.open_seqid == NULL) 4044 if (p->arg.open_seqid == NULL)
4043 goto out_free; 4045 goto out_free;
4044 p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); 4046 p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid, gfp_mask);
4045 if (p->arg.lock_seqid == NULL) 4047 if (p->arg.lock_seqid == NULL)
4046 goto out_free_seqid; 4048 goto out_free_seqid;
4047 p->arg.lock_stateid = &lsp->ls_stateid; 4049 p->arg.lock_stateid = &lsp->ls_stateid;
@@ -4195,7 +4197,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4195 4197
4196 dprintk("%s: begin!\n", __func__); 4198 dprintk("%s: begin!\n", __func__);
4197 data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), 4199 data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
4198 fl->fl_u.nfs4_fl.owner); 4200 fl->fl_u.nfs4_fl.owner,
4201 recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS);
4199 if (data == NULL) 4202 if (data == NULL)
4200 return -ENOMEM; 4203 return -ENOMEM;
4201 if (IS_SETLKW(cmd)) 4204 if (IS_SETLKW(cmd))
@@ -4684,7 +4687,7 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
4684 if (max_reqs != tbl->max_slots) { 4687 if (max_reqs != tbl->max_slots) {
4685 ret = -ENOMEM; 4688 ret = -ENOMEM;
4686 new = kmalloc(max_reqs * sizeof(struct nfs4_slot), 4689 new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
4687 GFP_KERNEL); 4690 GFP_NOFS);
4688 if (!new) 4691 if (!new)
4689 goto out; 4692 goto out;
4690 ret = 0; 4693 ret = 0;
@@ -4749,7 +4752,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4749 4752
4750 dprintk("--> %s: max_reqs=%u\n", __func__, max_slots); 4753 dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
4751 4754
4752 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); 4755 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
4753 if (!slot) 4756 if (!slot)
4754 goto out; 4757 goto out;
4755 ret = 0; 4758 ret = 0;
@@ -4798,7 +4801,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4798 struct nfs4_session *session; 4801 struct nfs4_session *session;
4799 struct nfs4_slot_table *tbl; 4802 struct nfs4_slot_table *tbl;
4800 4803
4801 session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL); 4804 session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
4802 if (!session) 4805 if (!session)
4803 return NULL; 4806 return NULL;
4804 4807
@@ -5142,8 +5145,8 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
5142 5145
5143 if (!atomic_inc_not_zero(&clp->cl_count)) 5146 if (!atomic_inc_not_zero(&clp->cl_count))
5144 return -EIO; 5147 return -EIO;
5145 args = kzalloc(sizeof(*args), GFP_KERNEL); 5148 args = kzalloc(sizeof(*args), GFP_NOFS);
5146 res = kzalloc(sizeof(*res), GFP_KERNEL); 5149 res = kzalloc(sizeof(*res), GFP_NOFS);
5147 if (!args || !res) { 5150 if (!args || !res) {
5148 kfree(args); 5151 kfree(args);
5149 kfree(res); 5152 kfree(res);
@@ -5244,7 +5247,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5244 int status = -ENOMEM; 5247 int status = -ENOMEM;
5245 5248
5246 dprintk("--> %s\n", __func__); 5249 dprintk("--> %s\n", __func__);
5247 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); 5250 calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
5248 if (calldata == NULL) 5251 if (calldata == NULL)
5249 goto out; 5252 goto out;
5250 calldata->clp = clp; 5253 calldata->clp = clp;