aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/nfs4_fs.h4
-rw-r--r--fs/nfs/nfs4proc.c47
-rw-r--r--fs/nfs/nfs4state.c21
4 files changed, 39 insertions, 35 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index ea61d26e7871..301634543974 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -213,7 +213,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
213 struct nfs_delegation *freeme = NULL; 213 struct nfs_delegation *freeme = NULL;
214 int status = 0; 214 int status = 0;
215 215
216 delegation = kmalloc(sizeof(*delegation), GFP_KERNEL); 216 delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
217 if (delegation == NULL) 217 if (delegation == NULL)
218 return -ENOMEM; 218 return -ENOMEM;
219 memcpy(delegation->stateid.data, res->delegation.data, 219 memcpy(delegation->stateid.data, res->delegation.data,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 509930664d74..c538c6106e16 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -213,7 +213,7 @@ extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
213extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); 213extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
214extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); 214extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
215extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); 215extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
216extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); 216extern int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait);
217extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 217extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
218extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 218extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
219extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); 219extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -286,7 +286,7 @@ extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
286extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 286extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
287extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 287extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
288 288
289extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter); 289extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
290extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); 290extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
291extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); 291extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
292extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); 292extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
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;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index cd2d90400d46..34acf5926fdc 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -366,7 +366,7 @@ nfs4_alloc_state_owner(void)
366{ 366{
367 struct nfs4_state_owner *sp; 367 struct nfs4_state_owner *sp;
368 368
369 sp = kzalloc(sizeof(*sp),GFP_KERNEL); 369 sp = kzalloc(sizeof(*sp),GFP_NOFS);
370 if (!sp) 370 if (!sp)
371 return NULL; 371 return NULL;
372 spin_lock_init(&sp->so_lock); 372 spin_lock_init(&sp->so_lock);
@@ -440,7 +440,7 @@ nfs4_alloc_open_state(void)
440{ 440{
441 struct nfs4_state *state; 441 struct nfs4_state *state;
442 442
443 state = kzalloc(sizeof(*state), GFP_KERNEL); 443 state = kzalloc(sizeof(*state), GFP_NOFS);
444 if (!state) 444 if (!state)
445 return NULL; 445 return NULL;
446 atomic_set(&state->count, 1); 446 atomic_set(&state->count, 1);
@@ -542,7 +542,8 @@ void nfs4_put_open_state(struct nfs4_state *state)
542/* 542/*
543 * Close the current file. 543 * Close the current file.
544 */ 544 */
545static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fmode, int wait) 545static void __nfs4_close(struct path *path, struct nfs4_state *state,
546 fmode_t fmode, gfp_t gfp_mask, int wait)
546{ 547{
547 struct nfs4_state_owner *owner = state->owner; 548 struct nfs4_state_owner *owner = state->owner;
548 int call_close = 0; 549 int call_close = 0;
@@ -583,17 +584,17 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fm
583 nfs4_put_open_state(state); 584 nfs4_put_open_state(state);
584 nfs4_put_state_owner(owner); 585 nfs4_put_state_owner(owner);
585 } else 586 } else
586 nfs4_do_close(path, state, wait); 587 nfs4_do_close(path, state, gfp_mask, wait);
587} 588}
588 589
589void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode) 590void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
590{ 591{
591 __nfs4_close(path, state, fmode, 0); 592 __nfs4_close(path, state, fmode, GFP_NOFS, 0);
592} 593}
593 594
594void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode) 595void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode)
595{ 596{
596 __nfs4_close(path, state, fmode, 1); 597 __nfs4_close(path, state, fmode, GFP_KERNEL, 1);
597} 598}
598 599
599/* 600/*
@@ -623,7 +624,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
623 struct nfs4_lock_state *lsp; 624 struct nfs4_lock_state *lsp;
624 struct nfs_client *clp = state->owner->so_client; 625 struct nfs_client *clp = state->owner->so_client;
625 626
626 lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); 627 lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
627 if (lsp == NULL) 628 if (lsp == NULL)
628 return NULL; 629 return NULL;
629 rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue"); 630 rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue");
@@ -759,11 +760,11 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
759 nfs4_put_lock_state(lsp); 760 nfs4_put_lock_state(lsp);
760} 761}
761 762
762struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) 763struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask)
763{ 764{
764 struct nfs_seqid *new; 765 struct nfs_seqid *new;
765 766
766 new = kmalloc(sizeof(*new), GFP_KERNEL); 767 new = kmalloc(sizeof(*new), gfp_mask);
767 if (new != NULL) { 768 if (new != NULL) {
768 new->sequence = counter; 769 new->sequence = counter;
769 INIT_LIST_HEAD(&new->list); 770 INIT_LIST_HEAD(&new->list);
@@ -1352,7 +1353,7 @@ static int nfs4_recall_slot(struct nfs_client *clp)
1352 1353
1353 nfs4_begin_drain_session(clp); 1354 nfs4_begin_drain_session(clp);
1354 new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot), 1355 new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
1355 GFP_KERNEL); 1356 GFP_NOFS);
1356 if (!new) 1357 if (!new)
1357 return -ENOMEM; 1358 return -ENOMEM;
1358 1359