From acf82b85a70f39786e3cbb1ffed8655bcc972424 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 22 Apr 2010 11:28:39 +0200 Subject: nfs: fix some issues in nfs41_proc_reclaim_complete() The original code passed an ERR_PTR() to rpc_put_task() and instead of returning zero on success it returned -ENOMEM. Signed-off-by: Dan Carpenter Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 638067007c65..071fcedd517c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5218,9 +5218,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) msg.rpc_resp = &calldata->res; task_setup_data.callback_data = calldata; task = rpc_run_task(&task_setup_data); - if (IS_ERR(task)) + if (IS_ERR(task)) { status = PTR_ERR(task); + goto out; + } rpc_put_task(task); + return 0; out: dprintk("<-- %s status=%d\n", __func__, status); return status; -- cgit From c407d41a1612aa487f5a9cb5338ed7dc60fe1da2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:22:48 -0400 Subject: NFSv4: Reduce stack footprint of nfs4_proc_access() and nfs3_proc_access() Signed-off-by: Trond Myklebust --- fs/nfs/nfs3proc.c | 17 ++++++++++------- fs/nfs/nfs4proc.c | 11 +++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 72334c19d481..9d5d02f02515 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -181,13 +181,10 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name, static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) { - struct nfs_fattr fattr; struct nfs3_accessargs arg = { .fh = NFS_FH(inode), }; - struct nfs3_accessres res = { - .fattr = &fattr, - }; + struct nfs3_accessres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], .rpc_argp = &arg, @@ -195,7 +192,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) .rpc_cred = entry->cred, }; int mode = entry->mask; - int status; + int status = -ENOMEM; dprintk("NFS call access\n"); @@ -212,9 +209,13 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) if (mode & MAY_EXEC) arg.access |= NFS3_ACCESS_EXECUTE; } - nfs_fattr_init(&fattr); + + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, res.fattr); if (status == 0) { entry->mask = 0; if (res.access & NFS3_ACCESS_READ) @@ -224,6 +225,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE)) entry->mask |= MAY_EXEC; } + nfs_free_fattr(res.fattr); +out: dprintk("NFS reply access: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 071fcedd517c..6591bd852f84 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2404,14 +2404,12 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) { struct nfs_server *server = NFS_SERVER(inode); - struct nfs_fattr fattr; struct nfs4_accessargs args = { .fh = NFS_FH(inode), .bitmask = server->attr_bitmask, }; struct nfs4_accessres res = { .server = server, - .fattr = &fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], @@ -2438,7 +2436,11 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry if (mode & MAY_EXEC) args.access |= NFS4_ACCESS_EXECUTE; } - nfs_fattr_init(&fattr); + + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + return -ENOMEM; + status = nfs4_call_sync(server, &msg, &args, &res, 0); if (!status) { entry->mask = 0; @@ -2448,8 +2450,9 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry entry->mask |= MAY_WRITE; if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) entry->mask |= MAY_EXEC; - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, res.fattr); } + nfs_free_fattr(res.fattr); return status; } -- cgit From 011fff7239eb90e33e7bebba48bf596fced06eb9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:22:49 -0400 Subject: NFS: Reduce stack footprint of nfs3_proc_rename() and nfs4_proc_rename() Signed-off-by: Trond Myklebust --- fs/nfs/nfs3proc.c | 23 +++++++++++++---------- fs/nfs/nfs4proc.c | 16 +++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 9d5d02f02515..c252fc983a7e 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -432,7 +432,6 @@ static int nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *new_dir, struct qstr *new_name) { - struct nfs_fattr old_dir_attr, new_dir_attr; struct nfs3_renameargs arg = { .fromfh = NFS_FH(old_dir), .fromname = old_name->name, @@ -441,23 +440,27 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, .toname = new_name->name, .tolen = new_name->len }; - struct nfs3_renameres res = { - .fromattr = &old_dir_attr, - .toattr = &new_dir_attr - }; + struct nfs3_renameres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); - nfs_fattr_init(&old_dir_attr); - nfs_fattr_init(&new_dir_attr); + + res.fromattr = nfs_alloc_fattr(); + res.toattr = nfs_alloc_fattr(); + if (res.fromattr == NULL || res.toattr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); - nfs_post_op_update_inode(old_dir, &old_dir_attr); - nfs_post_op_update_inode(new_dir, &new_dir_attr); + nfs_post_op_update_inode(old_dir, res.fromattr); + nfs_post_op_update_inode(new_dir, res.toattr); +out: + nfs_free_fattr(res.toattr); + nfs_free_fattr(res.fromattr); dprintk("NFS reply rename: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6591bd852f84..14cde99d8a60 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2656,29 +2656,31 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, .new_name = new_name, .bitmask = server->attr_bitmask, }; - struct nfs_fattr old_fattr, new_fattr; struct nfs4_rename_res res = { .server = server, - .old_fattr = &old_fattr, - .new_fattr = &new_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; - nfs_fattr_init(res.old_fattr); - nfs_fattr_init(res.new_fattr); - status = nfs4_call_sync(server, &msg, &arg, &res, 1); + res.old_fattr = nfs_alloc_fattr(); + res.new_fattr = nfs_alloc_fattr(); + if (res.old_fattr == NULL || res.new_fattr == NULL) + goto out; + status = nfs4_call_sync(server, &msg, &arg, &res, 1); if (!status) { update_changeattr(old_dir, &res.old_cinfo); nfs_post_op_update_inode(old_dir, res.old_fattr); update_changeattr(new_dir, &res.new_cinfo); nfs_post_op_update_inode(new_dir, res.new_fattr); } +out: + nfs_free_fattr(res.new_fattr); + nfs_free_fattr(res.old_fattr); return status; } -- cgit From 136f2627c932da5835e67e464e191d8c43c3f3fd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:22:49 -0400 Subject: NFS: Reduce the stack footprint of nfs_link() Signed-off-by: Trond Myklebust --- fs/nfs/nfs3proc.c | 22 ++++++++++++---------- fs/nfs/nfs4proc.c | 16 +++++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 1c5bfb3d6f08..982a81bb7257 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -468,30 +468,32 @@ out: static int nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { - struct nfs_fattr dir_attr, fattr; struct nfs3_linkargs arg = { .fromfh = NFS_FH(inode), .tofh = NFS_FH(dir), .toname = name->name, .tolen = name->len }; - struct nfs3_linkres res = { - .dir_attr = &dir_attr, - .fattr = &fattr - }; + struct nfs3_linkres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_LINK], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call link %s\n", name->name); - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); + res.fattr = nfs_alloc_fattr(); + res.dir_attr = nfs_alloc_fattr(); + if (res.fattr == NULL || res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); - nfs_post_op_update_inode(inode, &fattr); + nfs_post_op_update_inode(dir, res.dir_attr); + nfs_post_op_update_inode(inode, res.fattr); +out: + nfs_free_fattr(res.dir_attr); + nfs_free_fattr(res.fattr); dprintk("NFS reply link: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 14cde99d8a60..0ffd4cfd3b1f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2707,28 +2707,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr * .name = name, .bitmask = server->attr_bitmask, }; - struct nfs_fattr fattr, dir_attr; struct nfs4_link_res res = { .server = server, - .fattr = &fattr, - .dir_attr = &dir_attr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; + + res.fattr = nfs_alloc_fattr(); + res.dir_attr = nfs_alloc_fattr(); + if (res.fattr == NULL || res.dir_attr == NULL) + goto out; - nfs_fattr_init(res.fattr); - nfs_fattr_init(res.dir_attr); status = nfs4_call_sync(server, &msg, &arg, &res, 1); if (!status) { update_changeattr(dir, &res.cinfo); nfs_post_op_update_inode(dir, res.dir_attr); nfs_post_op_update_inode(inode, res.fattr); } - +out: + nfs_free_fattr(res.dir_attr); + nfs_free_fattr(res.fattr); return status; } -- cgit From d346890bea062d697e24fb4e34591428021ad011 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:22:50 -0400 Subject: NFS: Reduce stack footprint of nfs_proc_remove() Signed-off-by: Trond Myklebust --- fs/nfs/nfs3proc.c | 13 +++++++++---- fs/nfs/nfs3xdr.c | 2 +- fs/nfs/nfs4proc.c | 13 +++++++++---- fs/nfs/nfs4xdr.c | 2 +- fs/nfs/unlink.c | 4 +++- include/linux/nfs_xdr.h | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 088dceb513b8..80378d1283cb 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -406,12 +406,17 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name) .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call remove %s\n", name->name); - nfs_fattr_init(&res.dir_attr); + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &res.dir_attr); + nfs_post_op_update_inode(dir, res.dir_attr); + nfs_free_fattr(res.dir_attr); +out: dprintk("NFS reply remove: %d\n", status); return status; } @@ -429,7 +434,7 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) if (nfs3_async_handle_jukebox(task, dir)) return 0; res = task->tk_msg.rpc_resp; - nfs_post_op_update_inode(dir, &res->dir_attr); + nfs_post_op_update_inode(dir, res->dir_attr); return 1; } diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 56a86f6ac8b5..75dcfc7da365 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -762,7 +762,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) static int nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res) { - return nfs3_xdr_wccstat(req, p, &res->dir_attr); + return nfs3_xdr_wccstat(req, p, res->dir_attr); } /* diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0ffd4cfd3b1f..d0cb6e163320 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2599,14 +2599,19 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) .rpc_argp = &args, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; + + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; - nfs_fattr_init(&res.dir_attr); status = nfs4_call_sync(server, &msg, &args, &res, 1); if (status == 0) { update_changeattr(dir, &res.cinfo); - nfs_post_op_update_inode(dir, &res.dir_attr); + nfs_post_op_update_inode(dir, res.dir_attr); } + nfs_free_fattr(res.dir_attr); +out: return status; } @@ -2641,7 +2646,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) return 0; update_changeattr(dir, &res->cinfo); - nfs_post_op_update_inode(dir, &res->dir_attr); + nfs_post_op_update_inode(dir, res->dir_attr); return 1; } diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 38f3b582e7c2..890580642dc0 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4815,7 +4815,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem goto out; if ((status = decode_remove(&xdr, &res->cinfo)) != 0) goto out; - decode_getfattr(&xdr, &res->dir_attr, res->server, + decode_getfattr(&xdr, res->dir_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 6da3d3ff6edd..a2242af6a17d 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -23,6 +23,7 @@ struct nfs_unlinkdata { struct nfs_removeres res; struct inode *dir; struct rpc_cred *cred; + struct nfs_fattr dir_attr; }; /** @@ -169,7 +170,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n } nfs_sb_active(dir->i_sb); data->args.fh = NFS_FH(dir); - nfs_fattr_init(&data->res.dir_attr); + nfs_fattr_init(data->res.dir_attr); NFS_PROTO(dir)->unlink_setup(&msg, dir); @@ -259,6 +260,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry) goto out_free; } data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE; + data->res.dir_attr = &data->dir_attr; status = -EBUSY; spin_lock(&dentry->d_lock); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 89b28812ec24..76e11c663403 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -386,8 +386,8 @@ struct nfs_removeargs { struct nfs_removeres { const struct nfs_server *server; + struct nfs_fattr *dir_attr; struct nfs4_change_info cinfo; - struct nfs_fattr dir_attr; struct nfs4_sequence_res seq_res; }; -- cgit From 0ab64e0e147e45c07e33d344401cf898a6c181c0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:22:51 -0400 Subject: NFS: Reduce stack footprint of nfs4_proc_create() Move the O_EXCL open handling into _nfs4_do_open() where it belongs. Doing so also allows us to reuse the struct fattr from the opendata. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d0cb6e163320..45f64701d4a6 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -70,6 +70,9 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); +static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, struct iattr *sattr, + struct nfs4_state *state); /* Prevent leaks of NFSv4 errors into userland */ static int nfs4_map_errors(int err) @@ -1659,15 +1662,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in if (status != 0) goto err_opendata_put; - if (opendata->o_arg.open_flags & O_EXCL) - nfs4_exclusive_attrset(opendata, sattr); - state = nfs4_opendata_to_nfs4_state(opendata); status = PTR_ERR(state); if (IS_ERR(state)) goto err_opendata_put; if (server->caps & NFS_CAP_POSIX_LOCK) set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); + + if (opendata->o_arg.open_flags & O_EXCL) { + nfs4_exclusive_attrset(opendata, sattr); + + nfs_fattr_init(opendata->o_res.f_attr); + status = nfs4_do_setattr(state->inode, cred, + opendata->o_res.f_attr, sattr, + state); + if (status == 0) + nfs_setattr_update_inode(state->inode, sattr); + nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); + } nfs4_opendata_put(opendata); nfs4_put_state_owner(sp); *res = state; @@ -2565,13 +2577,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, } d_add(dentry, igrab(state->inode)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); - if (flags & O_EXCL) { - struct nfs_fattr fattr; - status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state); - if (status == 0) - nfs_setattr_update_inode(state->inode, sattr); - nfs_post_op_update_inode(state->inode, &fattr); - } if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) status = nfs4_intent_set_file(nd, &path, state, fmode); else -- cgit From bb8b27e504c0f0463535fea31b42bcaa393c3fb0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Apr 2010 16:43:06 -0400 Subject: NFSv4: Clean up the NFSv4 setclientid operation Reviewed-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 4 ++-- fs/nfs/nfs4proc.c | 18 ++++++++++++------ fs/nfs/nfs4state.c | 15 ++++++++++----- fs/nfs/nfs4xdr.c | 20 ++++++++++---------- include/linux/nfs_fs_sb.h | 1 - include/linux/nfs_xdr.h | 5 +++++ 6 files changed, 39 insertions(+), 24 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index a187200a7aac..509930664d74 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -206,8 +206,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); /* nfs4proc.c */ -extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); -extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); +extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); +extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 45f64701d4a6..04f4b2b2506b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3511,7 +3511,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, return _nfs4_async_handle_error(task, server, server->nfs_client, state); } -int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) +int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, + unsigned short port, struct rpc_cred *cred, + struct nfs4_setclientid_res *res) { nfs4_verifier sc_verifier; struct nfs4_setclientid setclientid = { @@ -3521,7 +3523,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], .rpc_argp = &setclientid, - .rpc_resp = clp, + .rpc_resp = res, .rpc_cred = cred, }; __be32 *p; @@ -3564,12 +3566,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po return status; } -static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) +static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, + struct nfs4_setclientid_res *arg, + struct rpc_cred *cred) { struct nfs_fsinfo fsinfo; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], - .rpc_argp = clp, + .rpc_argp = arg, .rpc_resp = &fsinfo, .rpc_cred = cred, }; @@ -3587,12 +3591,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre return status; } -int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) +int nfs4_proc_setclientid_confirm(struct nfs_client *clp, + struct nfs4_setclientid_res *arg, + struct rpc_cred *cred) { long timeout = 0; int err; do { - err = _nfs4_proc_setclientid_confirm(clp, cred); + err = _nfs4_proc_setclientid_confirm(clp, arg, cred); switch (err) { case 0: return err; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6c5ed51f105e..cd2d90400d46 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -62,6 +62,7 @@ static LIST_HEAD(nfs4_clientid_list); int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) { + struct nfs4_setclientid_res clid; unsigned short port; int status; @@ -69,11 +70,15 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) if (clp->cl_addr.ss_family == AF_INET6) port = nfs_callback_tcpport6; - status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred); - if (status == 0) - status = nfs4_proc_setclientid_confirm(clp, cred); - if (status == 0) - nfs4_schedule_state_renewal(clp); + status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); + if (status != 0) + goto out; + status = nfs4_proc_setclientid_confirm(clp, &clid, cred); + if (status != 0) + goto out; + clp->cl_clientid = clid.clientid; + nfs4_schedule_state_renewal(clp); +out: return status; } diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 890580642dc0..6bdef28efa33 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1504,14 +1504,14 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie hdr->replen += decode_setclientid_maxsz; } -static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr) +static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr) { __be32 *p; p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE); *p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM); - p = xdr_encode_hyper(p, client_state->cl_clientid); - xdr_encode_opaque_fixed(p, client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); + p = xdr_encode_hyper(p, arg->clientid); + xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE); hdr->nops++; hdr->replen += decode_setclientid_confirm_maxsz; } @@ -2324,7 +2324,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 /* * a SETCLIENTID_CONFIRM request */ -static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp) +static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -2334,7 +2334,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, req, &hdr); - encode_setclientid_confirm(&xdr, clp, &hdr); + encode_setclientid_confirm(&xdr, arg, &hdr); encode_putrootfh(&xdr, &hdr); encode_fsinfo(&xdr, lease_bitmap, &hdr); encode_nops(&hdr); @@ -4397,7 +4397,7 @@ out_overflow: return -EIO; } -static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) +static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res) { __be32 *p; uint32_t opnum; @@ -4417,8 +4417,8 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); if (unlikely(!p)) goto out_overflow; - p = xdr_decode_hyper(p, &clp->cl_clientid); - memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE); + p = xdr_decode_hyper(p, &res->clientid); + memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE); } else if (nfserr == NFSERR_CLID_INUSE) { uint32_t len; @@ -5498,7 +5498,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy) * Decode SETCLIENTID response */ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, - struct nfs_client *clp) + struct nfs4_setclientid_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -5507,7 +5507,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, xdr_init_decode(&xdr, &req->rq_rcv_buf, p); status = decode_compound_hdr(&xdr, &hdr); if (!status) - status = decode_setclientid(&xdr, clp); + status = decode_setclientid(&xdr, res); return status; } diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index e82957acea56..d6e10a4c06e5 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -44,7 +44,6 @@ struct nfs_client { #ifdef CONFIG_NFS_V4 u64 cl_clientid; /* constant */ - nfs4_verifier cl_confirm; unsigned long cl_state; struct rb_root cl_openowner_id; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 76e11c663403..51914d7d6cc4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -824,6 +824,11 @@ struct nfs4_setclientid { u32 sc_cb_ident; }; +struct nfs4_setclientid_res { + u64 clientid; + nfs4_verifier confirm; +}; + struct nfs4_statfs_arg { const struct nfs_fh * fh; const u32 * bitmask; -- cgit From 9bc4e3ca46e4eb9cb434de4175c6041d00bbdca3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 7 May 2010 13:34:17 -0400 Subject: NFS: Calldata for nfs4_renew_done() I'm about to change task->tk_start from a jiffies value to a ktime_t value in order to make RPC RTT reporting more precise. Recently (commit dc96aef9) nfs4_renew_done() started to reference task->tk_start so that a jiffies value no longer had to be passed from nfs4_proc_async_renew(). This allowed the calldata to point to an nfs_client instead. Changing task->tk_start to a ktime_t value makes it effectively useless for renew timestamps, so we need to restore the pre-dc96aef9 logic that provided a jiffies "start" timestamp to nfs4_renew_done(). Both an nfs_client pointer and a timestamp need to be passed to nfs4_renew_done(), so create a new nfs_renewdata structure that contains both, resembling what is already done for delegreturn, lock, and unlock. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'fs/nfs/nfs4proc.c') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 04f4b2b2506b..9998c2958103 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3163,23 +3163,31 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; } +struct nfs4_renewdata { + struct nfs_client *client; + unsigned long timestamp; +}; + /* * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special * standalone procedure for queueing an asynchronous RENEW. */ -static void nfs4_renew_release(void *data) +static void nfs4_renew_release(void *calldata) { - struct nfs_client *clp = data; + struct nfs4_renewdata *data = calldata; + struct nfs_client *clp = data->client; if (atomic_read(&clp->cl_count) > 1) nfs4_schedule_state_renewal(clp); nfs_put_client(clp); + kfree(data); } -static void nfs4_renew_done(struct rpc_task *task, void *data) +static void nfs4_renew_done(struct rpc_task *task, void *calldata) { - struct nfs_client *clp = data; - unsigned long timestamp = task->tk_start; + struct nfs4_renewdata *data = calldata; + struct nfs_client *clp = data->client; + unsigned long timestamp = data->timestamp; if (task->tk_status < 0) { /* Unless we're shutting down, schedule state recovery! */ @@ -3205,11 +3213,17 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) .rpc_argp = clp, .rpc_cred = cred, }; + struct nfs4_renewdata *data; if (!atomic_inc_not_zero(&clp->cl_count)) return -EIO; + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + data->client = clp; + data->timestamp = jiffies; return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, - &nfs4_renew_ops, clp); + &nfs4_renew_ops, data); } int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) -- cgit From 8535b2be5181fc3019e4150567ef53210fe3b04f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 13 May 2010 12:51:01 -0400 Subject: 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 --- fs/nfs/delegation.c | 2 +- fs/nfs/nfs4_fs.h | 4 ++-- fs/nfs/nfs4proc.c | 47 +++++++++++++++++++++++++---------------------- fs/nfs/nfs4state.c | 21 +++++++++++---------- 4 files changed, 39 insertions(+), 35 deletions(-) (limited to 'fs/nfs/nfs4proc.c') 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 struct nfs_delegation *freeme = NULL; int status = 0; - delegation = kmalloc(sizeof(*delegation), GFP_KERNEL); + delegation = kmalloc(sizeof(*delegation), GFP_NOFS); if (delegation == NULL) return -ENOMEM; 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 *); extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); -extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); +extern int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait); extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); extern 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); extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); -extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter); +extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); extern 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) static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, struct nfs4_state_owner *sp, fmode_t fmode, int flags, - const struct iattr *attrs) + const struct iattr *attrs, + gfp_t gfp_mask) { struct dentry *parent = dget_parent(path->dentry); struct inode *dir = parent->d_inode; struct nfs_server *server = NFS_SERVER(dir); struct nfs4_opendata *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), gfp_mask); if (p == NULL) goto err; - p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); + p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); if (p->o_arg.seqid == NULL) goto err_free; path_get(path); @@ -1063,7 +1064,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context { struct nfs4_opendata *opendata; - opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL); + opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS); if (opendata == NULL) return ERR_PTR(-ENOMEM); opendata->state = state; @@ -1651,7 +1652,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in if (path->dentry->d_inode != NULL) nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); status = -ENOMEM; - opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr); + opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL); if (opendata == NULL) goto err_put_state_owner; @@ -1926,7 +1927,7 @@ static const struct rpc_call_ops nfs4_close_ops = { * * NOTE: Caller must be holding the sp->so_owner semaphore! */ -int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) +int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait) { struct nfs_server *server = NFS_SERVER(state->inode); struct nfs4_closedata *calldata; @@ -1945,7 +1946,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) }; int status = -ENOMEM; - calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); + calldata = kzalloc(sizeof(*calldata), gfp_mask); if (calldata == NULL) goto out; calldata->inode = state->inode; @@ -1953,7 +1954,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) calldata->arg.fh = NFS_FH(state->inode); calldata->arg.stateid = &state->open_stateid; /* Serialization for the sequence id */ - calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); + calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid, gfp_mask); if (calldata->arg.seqid == NULL) goto out_free_calldata; calldata->arg.fmode = 0; @@ -3704,7 +3705,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co }; int status = 0; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_NOFS); if (data == NULL) return -ENOMEM; data->args.fhandle = &data->fh; @@ -3860,7 +3861,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, struct nfs4_unlockdata *p; struct inode *inode = lsp->ls_state->inode; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_NOFS); if (p == NULL) return NULL; p->arg.fh = NFS_FH(inode); @@ -3998,7 +3999,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * if (test_bit(NFS_DELEGATED_STATE, &state->flags)) goto out; lsp = request->fl_u.nfs4_fl.owner; - seqid = nfs_alloc_seqid(&lsp->ls_seqid); + seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL); status = -ENOMEM; if (seqid == NULL) goto out; @@ -4026,22 +4027,23 @@ struct nfs4_lockdata { }; static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, - struct nfs_open_context *ctx, struct nfs4_lock_state *lsp) + struct nfs_open_context *ctx, struct nfs4_lock_state *lsp, + gfp_t gfp_mask) { struct nfs4_lockdata *p; struct inode *inode = lsp->ls_state->inode; struct nfs_server *server = NFS_SERVER(inode); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), gfp_mask); if (p == NULL) return NULL; p->arg.fh = NFS_FH(inode); p->arg.fl = &p->fl; - p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); + p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask); if (p->arg.open_seqid == NULL) goto out_free; - p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); + p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid, gfp_mask); if (p->arg.lock_seqid == NULL) goto out_free_seqid; 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 dprintk("%s: begin!\n", __func__); data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), - fl->fl_u.nfs4_fl.owner); + fl->fl_u.nfs4_fl.owner, + recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS); if (data == NULL) return -ENOMEM; if (IS_SETLKW(cmd)) @@ -4684,7 +4687,7 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, if (max_reqs != tbl->max_slots) { ret = -ENOMEM; new = kmalloc(max_reqs * sizeof(struct nfs4_slot), - GFP_KERNEL); + GFP_NOFS); if (!new) goto out; ret = 0; @@ -4749,7 +4752,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, dprintk("--> %s: max_reqs=%u\n", __func__, max_slots); - slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); + slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS); if (!slot) goto out; ret = 0; @@ -4798,7 +4801,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) struct nfs4_session *session; struct nfs4_slot_table *tbl; - session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL); + session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); if (!session) return NULL; @@ -5142,8 +5145,8 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, if (!atomic_inc_not_zero(&clp->cl_count)) return -EIO; - args = kzalloc(sizeof(*args), GFP_KERNEL); - res = kzalloc(sizeof(*res), GFP_KERNEL); + args = kzalloc(sizeof(*args), GFP_NOFS); + res = kzalloc(sizeof(*res), GFP_NOFS); if (!args || !res) { kfree(args); kfree(res); @@ -5244,7 +5247,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) int status = -ENOMEM; dprintk("--> %s\n", __func__); - calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); + calldata = kzalloc(sizeof(*calldata), GFP_NOFS); if (calldata == NULL) goto out; 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) { struct nfs4_state_owner *sp; - sp = kzalloc(sizeof(*sp),GFP_KERNEL); + sp = kzalloc(sizeof(*sp),GFP_NOFS); if (!sp) return NULL; spin_lock_init(&sp->so_lock); @@ -440,7 +440,7 @@ nfs4_alloc_open_state(void) { struct nfs4_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc(sizeof(*state), GFP_NOFS); if (!state) return NULL; atomic_set(&state->count, 1); @@ -542,7 +542,8 @@ void nfs4_put_open_state(struct nfs4_state *state) /* * Close the current file. */ -static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fmode, int wait) +static void __nfs4_close(struct path *path, struct nfs4_state *state, + fmode_t fmode, gfp_t gfp_mask, int wait) { struct nfs4_state_owner *owner = state->owner; int call_close = 0; @@ -583,17 +584,17 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fm nfs4_put_open_state(state); nfs4_put_state_owner(owner); } else - nfs4_do_close(path, state, wait); + nfs4_do_close(path, state, gfp_mask, wait); } void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode) { - __nfs4_close(path, state, fmode, 0); + __nfs4_close(path, state, fmode, GFP_NOFS, 0); } void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode) { - __nfs4_close(path, state, fmode, 1); + __nfs4_close(path, state, fmode, GFP_KERNEL, 1); } /* @@ -623,7 +624,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f struct nfs4_lock_state *lsp; struct nfs_client *clp = state->owner->so_client; - lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); + lsp = kzalloc(sizeof(*lsp), GFP_NOFS); if (lsp == NULL) return NULL; 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 nfs4_put_lock_state(lsp); } -struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) +struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) { struct nfs_seqid *new; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc(sizeof(*new), gfp_mask); if (new != NULL) { new->sequence = counter; INIT_LIST_HEAD(&new->list); @@ -1352,7 +1353,7 @@ static int nfs4_recall_slot(struct nfs_client *clp) nfs4_begin_drain_session(clp); new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot), - GFP_KERNEL); + GFP_NOFS); if (!new) return -ENOMEM; -- cgit