* [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more
@ 2006-12-08 1:13 NeilBrown
2006-12-08 1:13 ` [PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock NeilBrown
` (17 more replies)
0 siblings, 18 replies; 19+ messages in thread
From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Following are 18 patches against 2.6.19-rc6-mm2 which are suitable for 2.6.20.
First 16 are from the NFSv4 team at umich (thanks Bruce). Mostly
fixing minor bugs and tidying-up code.
Last 2 from me. We haven't been testing against old versions of
nfs-utils and bit-rot has set in. Some of that (hopefully all) has
been fixed.
[PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock
[PATCH 002 of 18] knfsd: svcrpc: fix gss krb5i memory leak
[PATCH 003 of 18] knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE
[PATCH 004 of 18] knfsd: nfsd: make exp_rootfh handle exp_parent errors
[PATCH 005 of 18] knfsd: nfsd: simplify exp_pseudoroot
[PATCH 006 of 18] knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir
[PATCH 007 of 18] knfsd: nfsd: don't drop silently on upcall deferral
[PATCH 008 of 18] knfsd: svcrpc: remove another silent drop from deferral code
[PATCH 009 of 18] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations.
[PATCH 010 of 18] knfsd: nfsd4: remove spurious replay_owner check
[PATCH 011 of 18] knfsd: nfsd4: move replay_owner to cstate
[PATCH 012 of 18] knfsd: nfsd4: don't inline nfsd4 compound op functions
[PATCH 013 of 18] knfsd: nfsd4: make verify and nverify wrappers
[PATCH 014 of 18] knfsd: nfsd4: reorganize compound ops
[PATCH 015 of 18] knfsd: nfsd4: simplify migration op check
[PATCH 016 of 18] knfsd: nfsd4: simplify filehandle check
[PATCH 017 of 18] knfsd: Don't ignore kstrdup failure in rpc caches.
[PATCH 018 of 18] knfsd: Fix up some bit-rot in exp_export
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 002 of 18] knfsd: svcrpc: fix gss krb5i memory leak NeilBrown ` (16 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> This dprintk is printing the wrong error now, but it's probably an unnecessary dprintk anyway; just remove it. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4state.c | 1 - 1 file changed, 1 deletion(-) diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c --- .prev/fs/nfsd/nfs4state.c 2006-12-08 12:07:29.000000000 +1100 +++ ./fs/nfsd/nfs4state.c 2006-12-08 12:07:57.000000000 +1100 @@ -2760,7 +2760,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc conflock.fl_ops = NULL; conflock.fl_lmops = NULL; err = posix_lock_file_conf(filp, &file_lock, &conflock); - dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status); switch (-err) { case 0: /* success! */ update_stateid(&lock_stp->st_stateid); ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 002 of 18] knfsd: svcrpc: fix gss krb5i memory leak 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown 2006-12-08 1:13 ` [PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 003 of 18] knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE NeilBrown ` (15 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1521 bytes --] From: J.Bruce Fields <bfields@fieldses.org> The memory leak here is embarassingly obvious. This fixes a problem that causes the kernel to leak a small amount of memory every time it receives a integrity-protected request. Thanks to Aimé Le Rouzic for the bug report. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./net/sunrpc/auth_gss/svcauth_gss.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff .prev/net/sunrpc/auth_gss/svcauth_gss.c ./net/sunrpc/auth_gss/svcauth_gss.c --- .prev/net/sunrpc/auth_gss/svcauth_gss.c 2006-12-08 12:07:28.000000000 +1100 +++ ./net/sunrpc/auth_gss/svcauth_gss.c 2006-12-08 12:08:05.000000000 +1100 @@ -818,19 +818,19 @@ unwrap_integ_data(struct xdr_buf *buf, u integ_len = svc_getnl(&buf->head[0]); if (integ_len & 3) - goto out; + return stat; if (integ_len > buf->len) - goto out; + return stat; if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len)) BUG(); /* copy out mic... */ if (read_u32_from_xdr_buf(buf, integ_len, &mic.len)) BUG(); if (mic.len > RPC_MAX_AUTH_SIZE) - goto out; + return stat; mic.data = kmalloc(mic.len, GFP_KERNEL); if (!mic.data) - goto out; + return stat; if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len)) goto out; maj_stat = gss_verify_mic(ctx, &integ_buf, &mic); @@ -840,6 +840,7 @@ unwrap_integ_data(struct xdr_buf *buf, u goto out; stat = 0; out: + kfree(mic.data); return stat; } [-- Attachment #2: Type: text/plain, Size: 347 bytes --] ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV [-- Attachment #3: Type: text/plain, Size: 140 bytes --] _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 003 of 18] knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown 2006-12-08 1:13 ` [PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock NeilBrown 2006-12-08 1:13 ` [PATCH 002 of 18] knfsd: svcrpc: fix gss krb5i memory leak NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 004 of 18] knfsd: nfsd: make exp_rootfh handle exp_parent errors NeilBrown ` (14 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> A comment here incorrectly states that "slack_space" is measured in words, not bytes. Remove the comment, and adjust a variable name and a few comments to clarify the situation. This is pure cleanup; there should be no change in functionality. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 10 +++++----- ./include/linux/nfsd/nfsd.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:07:28.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:08:12.000000000 +1100 @@ -740,7 +740,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs struct svc_fh *current_fh = NULL; struct svc_fh *save_fh = NULL; struct nfs4_stateowner *replay_owner = NULL; - int slack_space; /* in words, not bytes! */ + int slack_bytes; __be32 status; status = nfserr_resource; @@ -790,10 +790,10 @@ nfsd4_proc_compound(struct svc_rqst *rqs * failed response to the next operation. If we don't * have enough room, fail with ERR_RESOURCE. */ -/* FIXME - is slack_space *really* words, or bytes??? - neilb */ - slack_space = (char *)resp->end - (char *)resp->p; - if (slack_space < COMPOUND_SLACK_SPACE + COMPOUND_ERR_SLACK_SPACE) { - BUG_ON(slack_space < COMPOUND_ERR_SLACK_SPACE); + slack_bytes = (char *)resp->end - (char *)resp->p; + if (slack_bytes < COMPOUND_SLACK_SPACE + + COMPOUND_ERR_SLACK_SPACE) { + BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); op->status = nfserr_resource; goto encode_op; } diff .prev/include/linux/nfsd/nfsd.h ./include/linux/nfsd/nfsd.h --- .prev/include/linux/nfsd/nfsd.h 2006-12-08 12:07:28.000000000 +1100 +++ ./include/linux/nfsd/nfsd.h 2006-12-08 12:08:12.000000000 +1100 @@ -275,12 +275,12 @@ static inline int is_fsid(struct svc_fh * we might process an operation with side effects, and be unable to * tell the client that the operation succeeded. * - * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space + * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space * needed to encode an "ordinary" _successful_ operation. (GETATTR, * READ, READDIR, and READLINK have their own buffer checks.) if we * fall below this level, we fail the next operation with NFS4ERR_RESOURCE. * - * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space + * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space * needed to encode an operation which has failed with NFS4ERR_RESOURCE. * care is taken to ensure that we never fall below this level for any * reason. ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 004 of 18] knfsd: nfsd: make exp_rootfh handle exp_parent errors 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (2 preceding siblings ...) 2006-12-08 1:13 ` [PATCH 003 of 18] knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 005 of 18] knfsd: nfsd: simplify exp_pseudoroot NeilBrown ` (13 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Since exp_parent can fail by returning an error (-EAGAIN) in addition to by returning NULL, we should check for that case in exp_rootfh. (TODO: we should check that userland handles these errors too.) Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/export.c | 4 ++++ 1 file changed, 4 insertions(+) diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c --- .prev/fs/nfsd/export.c 2006-12-08 12:07:28.000000000 +1100 +++ ./fs/nfsd/export.c 2006-12-08 12:08:20.000000000 +1100 @@ -1104,6 +1104,10 @@ exp_rootfh(svc_client *clp, char *path, path, nd.dentry, clp->name, inode->i_sb->s_id, inode->i_ino); exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); + if (IS_ERR(exp)) { + err = PTR_ERR(exp); + goto out; + } if (!exp) { dprintk("nfsd: exp_rootfh export not found.\n"); goto out; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 005 of 18] knfsd: nfsd: simplify exp_pseudoroot 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (3 preceding siblings ...) 2006-12-08 1:13 ` [PATCH 004 of 18] knfsd: nfsd: make exp_rootfh handle exp_parent errors NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 006 of 18] knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir NeilBrown ` (12 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Note there's no need for special handling of -EAGAIN here; nfserrno() does what we want already. So this is a pure cleanup with no change in functionality. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/export.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c --- .prev/fs/nfsd/export.c 2006-12-08 12:08:20.000000000 +1100 +++ ./fs/nfsd/export.c 2006-12-08 12:08:25.000000000 +1100 @@ -1163,12 +1163,10 @@ exp_pseudoroot(struct auth_domain *clp, mk_fsid_v1(fsidv, 0); exp = exp_find(clp, 1, fsidv, creq); - if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN) - return nfserr_dropit; + if (IS_ERR(exp)) + return nfserrno(PTR_ERR(exp)); if (exp == NULL) return nfserr_perm; - else if (IS_ERR(exp)) - return nfserrno(PTR_ERR(exp)); rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); exp_put(exp); return rv; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 006 of 18] knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (4 preceding siblings ...) 2006-12-08 1:13 ` [PATCH 005 of 18] knfsd: nfsd: simplify exp_pseudoroot NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:13 ` [PATCH 007 of 18] knfsd: nfsd: don't drop silently on upcall deferral NeilBrown ` (11 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> This patch on its own causes no change in behavior, since nfsd_cross_mnt() only returns -EAGAIN; but in the future I'd like it to also be able to return -ETIMEDOUT, so we may as well handle any possible error here. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4xdr.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff .prev/fs/nfsd/nfs4xdr.c ./fs/nfsd/nfs4xdr.c --- .prev/fs/nfsd/nfs4xdr.c 2006-12-08 12:07:28.000000000 +1100 +++ ./fs/nfsd/nfs4xdr.c 2006-12-08 12:08:31.000000000 +1100 @@ -1845,15 +1845,11 @@ nfsd4_encode_dirent_fattr(struct nfsd4_r exp_get(exp); if (d_mountpoint(dentry)) { - if (nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp)) { - /* - * -EAGAIN is the only error returned from - * nfsd_cross_mnt() and it indicates that an - * up-call has been initiated to fill in the export - * options on exp. When the answer comes back, - * this call will be retried. - */ - nfserr = nfserr_dropit; + int err; + + err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); + if (err) { + nfserr = nfserrno(err); goto out_put; } ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 007 of 18] knfsd: nfsd: don't drop silently on upcall deferral 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (5 preceding siblings ...) 2006-12-08 1:13 ` [PATCH 006 of 18] knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir NeilBrown @ 2006-12-08 1:13 ` NeilBrown 2006-12-08 1:14 ` [PATCH 008 of 18] knfsd: svcrpc: remove another silent drop from deferral code NeilBrown ` (10 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:13 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> To avoid tying up server threads when nfsd makes an upcall (to mountd, to get export options, to idmapd, for nfsv4 name<->id mapping, etc.), we temporarily "drop" the request and save enough information so that we can revisit it later. Certain failures during the deferral process can cause us to really drop the request and never revisit it. This is often less than ideal, and is unacceptable in the NFSv4 case--rfc 3530 forbids the server from dropping a request without also closing the connection. As a first step, we modify the deferral code to return -ETIMEDOUT (which is translated to nfserr_jukebox in the v3 and v4 cases, and remains a drop in the v2 case). Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/export.c | 11 ++++++++--- ./fs/nfsd/nfsfh.c | 6 ++++-- ./fs/nfsd/vfs.c | 2 +- ./net/sunrpc/auth_gss/svcauth_gss.c | 2 +- ./net/sunrpc/cache.c | 11 +++++++---- ./net/sunrpc/svcauth_unix.c | 1 + 6 files changed, 22 insertions(+), 11 deletions(-) diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c --- .prev/fs/nfsd/export.c 2006-12-08 12:08:25.000000000 +1100 +++ ./fs/nfsd/export.c 2006-12-08 12:08:37.000000000 +1100 @@ -787,15 +787,20 @@ exp_get_by_name(svc_client *clp, struct key.ex_dentry = dentry; exp = svc_export_lookup(&key); - if (exp != NULL) - switch (cache_check(&svc_export_cache, &exp->h, reqp)) { + if (exp != NULL) { + int err; + + err = cache_check(&svc_export_cache, &exp->h, reqp); + switch (err) { case 0: break; case -EAGAIN: - exp = ERR_PTR(-EAGAIN); + case -ETIMEDOUT: + exp = ERR_PTR(err); break; default: exp = NULL; } + } return exp; } diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c --- .prev/fs/nfsd/nfsfh.c 2006-12-08 12:07:23.000000000 +1100 +++ ./fs/nfsd/nfsfh.c 2006-12-08 12:08:37.000000000 +1100 @@ -169,9 +169,11 @@ fh_verify(struct svc_rqst *rqstp, struct exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); } - error = nfserr_dropit; - if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN) + if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN + || PTR_ERR(exp) == -ETIMEDOUT)) { + error = nfserrno(PTR_ERR(exp)); goto out; + } error = nfserr_stale; if (!exp || IS_ERR(exp)) diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c --- .prev/fs/nfsd/vfs.c 2006-12-08 12:07:23.000000000 +1100 +++ ./fs/nfsd/vfs.c 2006-12-08 12:08:37.000000000 +1100 @@ -99,7 +99,7 @@ static struct raparm_hbucket raparm_hash /* * Called from nfsd_lookup and encode_dirent. Check if we have crossed * a mount point. - * Returns -EAGAIN leaving *dpp and *expp unchanged, + * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged, * or nfs_ok having possibly changed *dpp and *expp */ int diff .prev/net/sunrpc/auth_gss/svcauth_gss.c ./net/sunrpc/auth_gss/svcauth_gss.c --- .prev/net/sunrpc/auth_gss/svcauth_gss.c 2006-12-08 12:08:05.000000000 +1100 +++ ./net/sunrpc/auth_gss/svcauth_gss.c 2006-12-08 12:08:37.000000000 +1100 @@ -1080,7 +1080,7 @@ svcauth_gss_accept(struct svc_rqst *rqst } switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { case -EAGAIN: - goto drop; + case -ETIMEDOUT: case -ENOENT: goto drop; case 0: diff .prev/net/sunrpc/cache.c ./net/sunrpc/cache.c --- .prev/net/sunrpc/cache.c 2006-12-08 12:07:23.000000000 +1100 +++ ./net/sunrpc/cache.c 2006-12-08 12:09:12.000000000 +1100 @@ -34,7 +34,7 @@ #define RPCDBG_FACILITY RPCDBG_CACHE -static void cache_defer_req(struct cache_req *req, struct cache_head *item); +static int cache_defer_req(struct cache_req *req, struct cache_head *item); static void cache_revisit_request(struct cache_head *item); static void cache_init(struct cache_head *h) @@ -185,6 +185,7 @@ static int cache_make_upcall(struct cach * * Returns 0 if the cache_head can be used, or cache_puts it and returns * -EAGAIN if upcall is pending, + * -ETIMEDOUT if upcall failed and should be retried, * -ENOENT if cache entry was negative */ int cache_check(struct cache_detail *detail, @@ -236,7 +237,8 @@ int cache_check(struct cache_detail *det } if (rv == -EAGAIN) - cache_defer_req(rqstp, h); + if (cache_defer_req(rqstp, h) != 0) + rv = -ETIMEDOUT; if (rv) cache_put(h, detail); @@ -523,14 +525,14 @@ static LIST_HEAD(cache_defer_list); static struct list_head cache_defer_hash[DFR_HASHSIZE]; static int cache_defer_cnt; -static void cache_defer_req(struct cache_req *req, struct cache_head *item) +static int cache_defer_req(struct cache_req *req, struct cache_head *item) { struct cache_deferred_req *dreq; int hash = DFR_HASH(item); dreq = req->defer(req); if (dreq == NULL) - return; + return -ETIMEDOUT; dreq->item = item; dreq->recv_time = get_seconds(); @@ -571,6 +573,7 @@ static void cache_defer_req(struct cache /* must have just been validated... */ cache_revisit_request(item); } + return 0; } static void cache_revisit_request(struct cache_head *item) diff .prev/net/sunrpc/svcauth_unix.c ./net/sunrpc/svcauth_unix.c --- .prev/net/sunrpc/svcauth_unix.c 2006-12-08 12:07:23.000000000 +1100 +++ ./net/sunrpc/svcauth_unix.c 2006-12-08 12:08:37.000000000 +1100 @@ -435,6 +435,7 @@ svcauth_unix_set_client(struct svc_rqst default: BUG(); case -EAGAIN: + case -ETIMEDOUT: return SVC_DROP; case -ENOENT: return SVC_DENIED; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 008 of 18] knfsd: svcrpc: remove another silent drop from deferral code 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (6 preceding siblings ...) 2006-12-08 1:13 ` [PATCH 007 of 18] knfsd: nfsd: don't drop silently on upcall deferral NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 009 of 18] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations NeilBrown ` (9 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> There's no point deferring something just to immediately fail the deferral, especially now that we can do something more useful in the failure case by returning an error. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./net/sunrpc/cache.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff .prev/net/sunrpc/cache.c ./net/sunrpc/cache.c --- .prev/net/sunrpc/cache.c 2006-12-08 12:09:12.000000000 +1100 +++ ./net/sunrpc/cache.c 2006-12-08 12:09:26.000000000 +1100 @@ -530,6 +530,13 @@ static int cache_defer_req(struct cache_ struct cache_deferred_req *dreq; int hash = DFR_HASH(item); + if (cache_defer_cnt >= DFR_MAX) { + /* too much in the cache, randomly drop this one, + * or continue and drop the oldest below + */ + if (net_random()&1) + return -ETIMEDOUT; + } dreq = req->defer(req); if (dreq == NULL) return -ETIMEDOUT; @@ -548,17 +555,8 @@ static int cache_defer_req(struct cache_ /* it is in, now maybe clean up */ dreq = NULL; if (++cache_defer_cnt > DFR_MAX) { - /* too much in the cache, randomly drop - * first or last - */ - if (net_random()&1) - dreq = list_entry(cache_defer_list.next, - struct cache_deferred_req, - recent); - else - dreq = list_entry(cache_defer_list.prev, - struct cache_deferred_req, - recent); + dreq = list_entry(cache_defer_list.prev, + struct cache_deferred_req, recent); list_del(&dreq->recent); list_del(&dreq->hash); cache_defer_cnt--; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 009 of 18] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations. 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (7 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 008 of 18] knfsd: svcrpc: remove another silent drop from deferral code NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 010 of 18] knfsd: nfsd4: remove spurious replay_owner check NeilBrown ` (8 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Pass the saved and current filehandles together into all the nfsd4 compound operations. I want a unified interface to these operations so we can just call them by pointer and throw out the huge switch statement. Also I'll eventually want a structure like this--that holds the state used during compound processing--for deferral. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 348 +++++++++++++++++++++++++------------------- ./fs/nfsd/nfs4state.c | 68 +++++--- ./include/linux/nfsd/xdr4.h | 22 +- 3 files changed, 259 insertions(+), 179 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:08:12.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 @@ -162,7 +162,8 @@ do_open_fhandle(struct svc_rqst *rqstp, static inline __be32 -nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) +nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) { __be32 status; dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", @@ -179,11 +180,11 @@ nfsd4_open(struct svc_rqst *rqstp, struc status = nfsd4_process_open1(open); if (status == nfserr_replay_me) { struct nfs4_replay *rp = &open->op_stateowner->so_replay; - fh_put(current_fh); - current_fh->fh_handle.fh_size = rp->rp_openfh_len; - memcpy(¤t_fh->fh_handle.fh_base, rp->rp_openfh, + fh_put(&cstate->current_fh); + cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len; + memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh, rp->rp_openfh_len); - status = fh_verify(rqstp, current_fh, 0, MAY_NOP); + status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); if (status) dprintk("nfsd4_open: replay failed" " restoring previous filehandle\n"); @@ -215,7 +216,8 @@ nfsd4_open(struct svc_rqst *rqstp, struc * (3) set open->op_truncate if the file is to be * truncated after opening, (4) do permission checking. */ - status = do_open_lookup(rqstp, current_fh, open); + status = do_open_lookup(rqstp, &cstate->current_fh, + open); if (status) goto out; break; @@ -227,7 +229,8 @@ nfsd4_open(struct svc_rqst *rqstp, struc * open->op_truncate if the file is to be truncated * after opening, (3) do permission checking. */ - status = do_open_fhandle(rqstp, current_fh, open); + status = do_open_fhandle(rqstp, &cstate->current_fh, + open); if (status) goto out; break; @@ -248,7 +251,7 @@ nfsd4_open(struct svc_rqst *rqstp, struc * successful, it (1) truncates the file if open->op_truncate was * set, (2) sets open->op_stateid, (3) sets open->op_delegation. */ - status = nfsd4_process_open2(rqstp, current_fh, open); + status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); out: if (open->op_stateowner) { nfs4_get_stateowner(open->op_stateowner); @@ -262,52 +265,54 @@ out: * filehandle-manipulating ops. */ static inline __be32 -nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) +nfsd4_getfh(struct nfsd4_compound_state *cstate, struct svc_fh **getfh) { - if (!current_fh->fh_dentry) + if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; - *getfh = current_fh; + *getfh = &cstate->current_fh; return nfs_ok; } static inline __be32 -nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh) +nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_putfh *putfh) { - fh_put(current_fh); - current_fh->fh_handle.fh_size = putfh->pf_fhlen; - memcpy(¤t_fh->fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen); - return fh_verify(rqstp, current_fh, 0, MAY_NOP); + fh_put(&cstate->current_fh); + cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; + memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, + putfh->pf_fhlen); + return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); } static inline __be32 -nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) +nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) { __be32 status; - fh_put(current_fh); - status = exp_pseudoroot(rqstp->rq_client, current_fh, + fh_put(&cstate->current_fh); + status = exp_pseudoroot(rqstp->rq_client, &cstate->current_fh, &rqstp->rq_chandle); return status; } static inline __be32 -nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) +nfsd4_restorefh(struct nfsd4_compound_state *cstate) { - if (!save_fh->fh_dentry) + if (!cstate->save_fh.fh_dentry) return nfserr_restorefh; - fh_dup2(current_fh, save_fh); + fh_dup2(&cstate->current_fh, &cstate->save_fh); return nfs_ok; } static inline __be32 -nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) +nfsd4_savefh(struct nfsd4_compound_state *cstate) { - if (!current_fh->fh_dentry) + if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; - fh_dup2(save_fh, current_fh); + fh_dup2(&cstate->save_fh, &cstate->current_fh); return nfs_ok; } @@ -315,17 +320,20 @@ nfsd4_savefh(struct svc_fh *current_fh, * misc nfsv4 ops */ static inline __be32 -nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access) +nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_access *access) { if (access->ac_req_access & ~NFS3_ACCESS_FULL) return nfserr_inval; access->ac_resp_access = access->ac_req_access; - return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported); + return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, + &access->ac_supported); } static inline __be32 -nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) +nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_commit *commit) { __be32 status; @@ -333,14 +341,16 @@ nfsd4_commit(struct svc_rqst *rqstp, str *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count); + status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, + commit->co_count); if (status == nfserr_symlink) status = nfserr_inval; return status; } static __be32 -nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) +nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_create *create) { struct svc_fh resfh; __be32 status; @@ -348,7 +358,7 @@ nfsd4_create(struct svc_rqst *rqstp, str fh_init(&resfh, NFS4_FHSIZE); - status = fh_verify(rqstp, current_fh, S_IFDIR, MAY_CREATE); + status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE); if (status == nfserr_symlink) status = nfserr_notdir; if (status) @@ -365,9 +375,10 @@ nfsd4_create(struct svc_rqst *rqstp, str */ create->cr_linkname[create->cr_linklen] = 0; - status = nfsd_symlink(rqstp, current_fh, create->cr_name, - create->cr_namelen, create->cr_linkname, - create->cr_linklen, &resfh, &create->cr_iattr); + status = nfsd_symlink(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + create->cr_linkname, create->cr_linklen, + &resfh, &create->cr_iattr); break; case NF4BLK: @@ -375,9 +386,9 @@ nfsd4_create(struct svc_rqst *rqstp, str if (MAJOR(rdev) != create->cr_specdata1 || MINOR(rdev) != create->cr_specdata2) return nfserr_inval; - status = nfsd_create(rqstp, current_fh, create->cr_name, - create->cr_namelen, &create->cr_iattr, - S_IFBLK, rdev, &resfh); + status = nfsd_create(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + &create->cr_iattr, S_IFBLK, rdev, &resfh); break; case NF4CHR: @@ -385,28 +396,28 @@ nfsd4_create(struct svc_rqst *rqstp, str if (MAJOR(rdev) != create->cr_specdata1 || MINOR(rdev) != create->cr_specdata2) return nfserr_inval; - status = nfsd_create(rqstp, current_fh, create->cr_name, - create->cr_namelen, &create->cr_iattr, - S_IFCHR, rdev, &resfh); + status = nfsd_create(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + &create->cr_iattr,S_IFCHR, rdev, &resfh); break; case NF4SOCK: - status = nfsd_create(rqstp, current_fh, create->cr_name, - create->cr_namelen, &create->cr_iattr, - S_IFSOCK, 0, &resfh); + status = nfsd_create(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + &create->cr_iattr, S_IFSOCK, 0, &resfh); break; case NF4FIFO: - status = nfsd_create(rqstp, current_fh, create->cr_name, - create->cr_namelen, &create->cr_iattr, - S_IFIFO, 0, &resfh); + status = nfsd_create(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + &create->cr_iattr, S_IFIFO, 0, &resfh); break; case NF4DIR: create->cr_iattr.ia_valid &= ~ATTR_SIZE; - status = nfsd_create(rqstp, current_fh, create->cr_name, - create->cr_namelen, &create->cr_iattr, - S_IFDIR, 0, &resfh); + status = nfsd_create(rqstp, &cstate->current_fh, + create->cr_name, create->cr_namelen, + &create->cr_iattr, S_IFDIR, 0, &resfh); break; default: @@ -414,9 +425,9 @@ nfsd4_create(struct svc_rqst *rqstp, str } if (!status) { - fh_unlock(current_fh); - set_change_info(&create->cr_cinfo, current_fh); - fh_dup2(current_fh, &resfh); + fh_unlock(&cstate->current_fh); + set_change_info(&create->cr_cinfo, &cstate->current_fh); + fh_dup2(&cstate->current_fh, &resfh); } fh_put(&resfh); @@ -424,11 +435,12 @@ nfsd4_create(struct svc_rqst *rqstp, str } static inline __be32 -nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr) +nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_getattr *getattr) { __be32 status; - status = fh_verify(rqstp, current_fh, 0, MAY_NOP); + status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); if (status) return status; @@ -438,26 +450,27 @@ nfsd4_getattr(struct svc_rqst *rqstp, st getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; - getattr->ga_fhp = current_fh; + getattr->ga_fhp = &cstate->current_fh; return nfs_ok; } static inline __be32 -nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, - struct svc_fh *save_fh, struct nfsd4_link *link) +nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_link *link) { __be32 status = nfserr_nofilehandle; - if (!save_fh->fh_dentry) + if (!cstate->save_fh.fh_dentry) return status; - status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh); + status = nfsd_link(rqstp, &cstate->current_fh, + link->li_name, link->li_namelen, &cstate->save_fh); if (!status) - set_change_info(&link->li_cinfo, current_fh); + set_change_info(&link->li_cinfo, &cstate->current_fh); return status; } static __be32 -nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) +nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) { struct svc_fh tmp_fh; __be32 ret; @@ -466,22 +479,27 @@ nfsd4_lookupp(struct svc_rqst *rqstp, st if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle)) != 0) return ret; - if (tmp_fh.fh_dentry == current_fh->fh_dentry) { + if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { fh_put(&tmp_fh); return nfserr_noent; } fh_put(&tmp_fh); - return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh); + return nfsd_lookup(rqstp, &cstate->current_fh, + "..", 2, &cstate->current_fh); } static inline __be32 -nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup) +nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_lookup *lookup) { - return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); + return nfsd_lookup(rqstp, &cstate->current_fh, + lookup->lo_name, lookup->lo_len, + &cstate->current_fh); } static inline __be32 -nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) +nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_read *read) { __be32 status; @@ -493,7 +511,8 @@ nfsd4_read(struct svc_rqst *rqstp, struc nfs4_lock_state(); /* check stateid */ - if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, + if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh, + &read->rd_stateid, CHECK_FH | RD_STATE, &read->rd_filp))) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -504,12 +523,13 @@ nfsd4_read(struct svc_rqst *rqstp, struc out: nfs4_unlock_state(); read->rd_rqstp = rqstp; - read->rd_fhp = current_fh; + read->rd_fhp = &cstate->current_fh; return status; } static inline __be32 -nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) +nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_readdir *readdir) { u64 cookie = readdir->rd_cookie; static const nfs4_verifier zeroverf; @@ -527,48 +547,51 @@ nfsd4_readdir(struct svc_rqst *rqstp, st return nfserr_bad_cookie; readdir->rd_rqstp = rqstp; - readdir->rd_fhp = current_fh; + readdir->rd_fhp = &cstate->current_fh; return nfs_ok; } static inline __be32 -nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink) +nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_readlink *readlink) { readlink->rl_rqstp = rqstp; - readlink->rl_fhp = current_fh; + readlink->rl_fhp = &cstate->current_fh; return nfs_ok; } static inline __be32 -nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove) +nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_remove *remove) { __be32 status; if (nfs4_in_grace()) return nfserr_grace; - status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen); + status = nfsd_unlink(rqstp, &cstate->current_fh, 0, + remove->rm_name, remove->rm_namelen); if (status == nfserr_symlink) return nfserr_notdir; if (!status) { - fh_unlock(current_fh); - set_change_info(&remove->rm_cinfo, current_fh); + fh_unlock(&cstate->current_fh); + set_change_info(&remove->rm_cinfo, &cstate->current_fh); } return status; } static inline __be32 -nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, - struct svc_fh *save_fh, struct nfsd4_rename *rename) +nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_rename *rename) { __be32 status = nfserr_nofilehandle; - if (!save_fh->fh_dentry) + if (!cstate->save_fh.fh_dentry) return status; - if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags + if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK)) return nfserr_grace; - status = nfsd_rename(rqstp, save_fh, rename->rn_sname, - rename->rn_snamelen, current_fh, + status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, + rename->rn_snamelen, &cstate->current_fh, rename->rn_tname, rename->rn_tnamelen); /* the underlying filesystem returns different error's than required @@ -576,27 +599,28 @@ nfsd4_rename(struct svc_rqst *rqstp, str if (status == nfserr_isdir) status = nfserr_exist; else if ((status == nfserr_notdir) && - (S_ISDIR(save_fh->fh_dentry->d_inode->i_mode) && - S_ISDIR(current_fh->fh_dentry->d_inode->i_mode))) + (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && + S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) status = nfserr_exist; else if (status == nfserr_symlink) status = nfserr_notdir; if (!status) { - set_change_info(&rename->rn_sinfo, current_fh); - set_change_info(&rename->rn_tinfo, save_fh); + set_change_info(&rename->rn_sinfo, &cstate->current_fh); + set_change_info(&rename->rn_tinfo, &cstate->save_fh); } return status; } static inline __be32 -nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) +nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_setattr *setattr) { __be32 status = nfs_ok; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); - status = nfs4_preprocess_stateid_op(current_fh, + status = nfs4_preprocess_stateid_op(&cstate->current_fh, &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); nfs4_unlock_state(); if (status) { @@ -606,16 +630,18 @@ nfsd4_setattr(struct svc_rqst *rqstp, st } status = nfs_ok; if (setattr->sa_acl != NULL) - status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl); + status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, + setattr->sa_acl); if (status) return status; - status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, + status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 0, (time_t)0); return status; } static inline __be32 -nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) +nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_write *write) { stateid_t *stateid = &write->wr_stateid; struct file *filp = NULL; @@ -628,7 +654,7 @@ nfsd4_write(struct svc_rqst *rqstp, stru return nfserr_inval; nfs4_lock_state(); - status = nfs4_preprocess_stateid_op(current_fh, stateid, + status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid, CHECK_FH | WR_STATE, &filp); if (filp) get_file(filp); @@ -645,9 +671,9 @@ nfsd4_write(struct svc_rqst *rqstp, stru *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - status = nfsd_write(rqstp, current_fh, filp, write->wr_offset, - rqstp->rq_vec, write->wr_vlen, write->wr_buflen, - &write->wr_how_written); + status = nfsd_write(rqstp, &cstate->current_fh, filp, + write->wr_offset, rqstp->rq_vec, write->wr_vlen, + write->wr_buflen, &write->wr_how_written); if (filp) fput(filp); @@ -662,13 +688,14 @@ nfsd4_write(struct svc_rqst *rqstp, stru * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. */ static __be32 -nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify) +nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_verify *verify) { __be32 *buf, *p; int count; __be32 status; - status = fh_verify(rqstp, current_fh, 0, MAY_NOP); + status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); if (status) return status; @@ -689,8 +716,9 @@ nfsd4_verify(struct svc_rqst *rqstp, str if (!buf) return nfserr_resource; - status = nfsd4_encode_fattr(current_fh, current_fh->fh_export, - current_fh->fh_dentry, buf, + status = nfsd4_encode_fattr(&cstate->current_fh, + cstate->current_fh.fh_export, + cstate->current_fh.fh_dentry, buf, &count, verify->ve_bmval, rqstp); @@ -727,6 +755,26 @@ static inline void nfsd4_increment_op_st nfsdstats.nfs4_opcount[opnum]++; } +static void cstate_free(struct nfsd4_compound_state *cstate) +{ + if (cstate == NULL) + return; + fh_put(&cstate->current_fh); + fh_put(&cstate->save_fh); + kfree(cstate); +} + +static struct nfsd4_compound_state *cstate_alloc(void) +{ + struct nfsd4_compound_state *cstate; + + cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL); + if (cstate == NULL) + return NULL; + fh_init(&cstate->current_fh, NFS4_FHSIZE); + fh_init(&cstate->save_fh, NFS4_FHSIZE); + return cstate; +} /* * COMPOUND call. @@ -737,21 +785,15 @@ nfsd4_proc_compound(struct svc_rqst *rqs struct nfsd4_compoundres *resp) { struct nfsd4_op *op; - struct svc_fh *current_fh = NULL; - struct svc_fh *save_fh = NULL; + struct nfsd4_compound_state *cstate = NULL; struct nfs4_stateowner *replay_owner = NULL; int slack_bytes; __be32 status; status = nfserr_resource; - current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); - if (current_fh == NULL) - goto out; - fh_init(current_fh, NFS4_FHSIZE); - save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL); - if (save_fh == NULL) + cstate = cstate_alloc(); + if (cstate == NULL) goto out; - fh_init(save_fh, NFS4_FHSIZE); resp->xbuf = &rqstp->rq_res; resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; @@ -802,7 +844,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH * require a valid current filehandle */ - if (!current_fh->fh_dentry) { + if (!cstate->current_fh.fh_dentry) { if (!((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) || (op->opnum == OP_SETCLIENTID) || @@ -817,7 +859,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs /* Check must be done at start of each operation, except * for GETATTR and ops not listed as returning NFS4ERR_MOVED */ - else if (current_fh->fh_export->ex_fslocs.migrated && + else if (cstate->current_fh.fh_export->ex_fslocs.migrated && !((op->opnum == OP_GETATTR) || (op->opnum == OP_PUTROOTFH) || (op->opnum == OP_PUTPUBFH) || @@ -829,90 +871,110 @@ nfsd4_proc_compound(struct svc_rqst *rqs } switch (op->opnum) { case OP_ACCESS: - op->status = nfsd4_access(rqstp, current_fh, &op->u.access); + op->status = nfsd4_access(rqstp, cstate, + &op->u.access); break; case OP_CLOSE: - op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner); + op->status = nfsd4_close(rqstp, cstate, + &op->u.close, &replay_owner); break; case OP_COMMIT: - op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); + op->status = nfsd4_commit(rqstp, cstate, + &op->u.commit); break; case OP_CREATE: - op->status = nfsd4_create(rqstp, current_fh, &op->u.create); + op->status = nfsd4_create(rqstp, cstate, + &op->u.create); break; case OP_DELEGRETURN: - op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn); + op->status = nfsd4_delegreturn(rqstp, cstate, + &op->u.delegreturn); break; case OP_GETATTR: - op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); + op->status = nfsd4_getattr(rqstp, cstate, + &op->u.getattr); break; case OP_GETFH: - op->status = nfsd4_getfh(current_fh, &op->u.getfh); + op->status = nfsd4_getfh(cstate, &op->u.getfh); break; case OP_LINK: - op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link); + op->status = nfsd4_link(rqstp, cstate, &op->u.link); break; case OP_LOCK: - op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner); + op->status = nfsd4_lock(rqstp, cstate, &op->u.lock, + &replay_owner); break; case OP_LOCKT: - op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); + op->status = nfsd4_lockt(rqstp, cstate, &op->u.lockt); break; case OP_LOCKU: - op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner); + op->status = nfsd4_locku(rqstp, cstate, &op->u.locku, + &replay_owner); break; case OP_LOOKUP: - op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); + op->status = nfsd4_lookup(rqstp, cstate, + &op->u.lookup); break; case OP_LOOKUPP: - op->status = nfsd4_lookupp(rqstp, current_fh); + op->status = nfsd4_lookupp(rqstp, cstate); break; case OP_NVERIFY: - op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify); + op->status = nfsd4_verify(rqstp, cstate, + &op->u.nverify); if (op->status == nfserr_not_same) op->status = nfs_ok; break; case OP_OPEN: - op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner); + op->status = nfsd4_open(rqstp, cstate, + &op->u.open, &replay_owner); break; case OP_OPEN_CONFIRM: - op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner); + op->status = nfsd4_open_confirm(rqstp, cstate, + &op->u.open_confirm, + &replay_owner); break; case OP_OPEN_DOWNGRADE: - op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner); + op->status = nfsd4_open_downgrade(rqstp, cstate, + &op->u.open_downgrade, + &replay_owner); break; case OP_PUTFH: - op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); + op->status = nfsd4_putfh(rqstp, cstate, &op->u.putfh); break; case OP_PUTROOTFH: - op->status = nfsd4_putrootfh(rqstp, current_fh); + op->status = nfsd4_putrootfh(rqstp, cstate); break; case OP_READ: - op->status = nfsd4_read(rqstp, current_fh, &op->u.read); + op->status = nfsd4_read(rqstp, cstate, &op->u.read); break; case OP_READDIR: - op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir); + op->status = nfsd4_readdir(rqstp, cstate, + &op->u.readdir); break; case OP_READLINK: - op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink); + op->status = nfsd4_readlink(rqstp, cstate, + &op->u.readlink); break; case OP_REMOVE: - op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove); + op->status = nfsd4_remove(rqstp, cstate, + &op->u.remove); break; case OP_RENAME: - op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename); + op->status = nfsd4_rename(rqstp, cstate, + &op->u.rename); break; case OP_RENEW: op->status = nfsd4_renew(&op->u.renew); break; case OP_RESTOREFH: - op->status = nfsd4_restorefh(current_fh, save_fh); + op->status = nfsd4_restorefh(cstate); break; case OP_SAVEFH: - op->status = nfsd4_savefh(current_fh, save_fh); + op->status = nfsd4_savefh(cstate); break; case OP_SETATTR: - op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr); + op->status = nfsd4_setattr(rqstp, cstate, + &op->u.setattr); break; case OP_SETCLIENTID: op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); @@ -921,12 +983,13 @@ nfsd4_proc_compound(struct svc_rqst *rqs op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); break; case OP_VERIFY: - op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify); + op->status = nfsd4_verify(rqstp, cstate, + &op->u.verify); if (op->status == nfserr_same) op->status = nfs_ok; break; case OP_WRITE: - op->status = nfsd4_write(rqstp, current_fh, &op->u.write); + op->status = nfsd4_write(rqstp, cstate, &op->u.write); break; case OP_RELEASE_LOCKOWNER: op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); @@ -958,12 +1021,7 @@ encode_op: out: nfsd4_release_compoundargs(args); - if (current_fh) - fh_put(current_fh); - kfree(current_fh); - if (save_fh) - fh_put(save_fh); - kfree(save_fh); + cstate_free(cstate); return status; } diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c --- .prev/fs/nfsd/nfs4state.c 2006-12-08 12:07:57.000000000 +1100 +++ ./fs/nfsd/nfs4state.c 2006-12-08 12:09:27.000000000 +1100 @@ -2242,24 +2242,26 @@ check_replay: } __be32 -nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner) +nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_open_confirm *oc, + struct nfs4_stateowner **replay_owner) { __be32 status; struct nfs4_stateowner *sop; struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", - (int)current_fh->fh_dentry->d_name.len, - current_fh->fh_dentry->d_name.name); + (int)cstate->current_fh.fh_dentry->d_name.len, + cstate->current_fh.fh_dentry->d_name.name); - status = fh_verify(rqstp, current_fh, S_IFREG, 0); + status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0); if (status) return status; nfs4_lock_state(); - if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid, - &oc->oc_req_stateid, + if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, + oc->oc_seqid, &oc->oc_req_stateid, CHECK_FH | CONFIRM | OPEN_STATE, &oc->oc_stateowner, &stp, NULL))) goto out; @@ -2311,22 +2313,26 @@ reset_union_bmap_deny(unsigned long deny } __be32 -nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner) +nfsd4_open_downgrade(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_open_downgrade *od, + struct nfs4_stateowner **replay_owner) { __be32 status; struct nfs4_stateid *stp; unsigned int share_access; dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", - (int)current_fh->fh_dentry->d_name.len, - current_fh->fh_dentry->d_name.name); + (int)cstate->current_fh.fh_dentry->d_name.len, + cstate->current_fh.fh_dentry->d_name.name); if (!access_valid(od->od_share_access) || !deny_valid(od->od_share_deny)) return nfserr_inval; nfs4_lock_state(); - if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, + if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, + od->od_seqid, &od->od_stateid, CHECK_FH | OPEN_STATE, &od->od_stateowner, &stp, NULL))) @@ -2366,18 +2372,20 @@ out: * nfs4_unlock_state() called after encode */ __be32 -nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) +nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) { __be32 status; struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_close on file %.*s\n", - (int)current_fh->fh_dentry->d_name.len, - current_fh->fh_dentry->d_name.name); + (int)cstate->current_fh.fh_dentry->d_name.len, + cstate->current_fh.fh_dentry->d_name.name); nfs4_lock_state(); /* check close_lru for replay */ - if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, + if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, + close->cl_seqid, &close->cl_stateid, CHECK_FH | OPEN_STATE | CLOSE_STATE, &close->cl_stateowner, &stp, NULL))) @@ -2405,15 +2413,17 @@ out: } __be32 -nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr) +nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_delegreturn *dr) { __be32 status; - if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) + if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) goto out; nfs4_lock_state(); - status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET, NULL); + status = nfs4_preprocess_stateid_op(&cstate->current_fh, + &dr->dr_stateid, DELEG_RET, NULL); nfs4_unlock_state(); out: return status; @@ -2636,7 +2646,8 @@ check_lock_length(u64 offset, u64 length * LOCK operation */ __be32 -nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) +nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) { struct nfs4_stateowner *open_sop = NULL; struct nfs4_stateowner *lock_sop = NULL; @@ -2655,7 +2666,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struc if (check_lock_length(lock->lk_offset, lock->lk_length)) return nfserr_inval; - if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) { + if ((status = fh_verify(rqstp, &cstate->current_fh, + S_IFREG, MAY_LOCK))) { dprintk("NFSD: nfsd4_lock: permission denied!\n"); return status; } @@ -2676,7 +2688,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc goto out; /* validate and update open stateid and open seqid */ - status = nfs4_preprocess_seqid_op(current_fh, + status = nfs4_preprocess_seqid_op(&cstate->current_fh, lock->lk_new_open_seqid, &lock->lk_new_open_stateid, CHECK_FH | OPEN_STATE, @@ -2703,7 +2715,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc goto out; } else { /* lock (lock owner + lock stateid) already exists */ - status = nfs4_preprocess_seqid_op(current_fh, + status = nfs4_preprocess_seqid_op(&cstate->current_fh, lock->lk_old_lock_seqid, &lock->lk_old_lock_stateid, CHECK_FH | LOCK_STATE, @@ -2795,7 +2807,8 @@ out: * LOCKT operation */ __be32 -nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt) +nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_lockt *lockt) { struct inode *inode; struct file file; @@ -2816,14 +2829,14 @@ nfsd4_lockt(struct svc_rqst *rqstp, stru if (STALE_CLIENTID(&lockt->lt_clientid)) goto out; - if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) { + if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) { dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); if (status == nfserr_symlink) status = nfserr_inval; goto out; } - inode = current_fh->fh_dentry->d_inode; + inode = cstate->current_fh.fh_dentry->d_inode; locks_init_lock(&file_lock); switch (lockt->lt_type) { case NFS4_READ_LT: @@ -2862,7 +2875,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, stru * only the dentry:inode set. */ memset(&file, 0, sizeof (struct file)); - file.f_path.dentry = current_fh->fh_dentry; + file.f_path.dentry = cstate->current_fh.fh_dentry; status = nfs_ok; if (posix_test_lock(&file, &file_lock, &conflock)) { @@ -2875,7 +2888,8 @@ out: } __be32 -nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) +nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) { struct nfs4_stateid *stp; struct file *filp = NULL; @@ -2892,7 +2906,7 @@ nfsd4_locku(struct svc_rqst *rqstp, stru nfs4_lock_state(); - if ((status = nfs4_preprocess_seqid_op(current_fh, + if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, locku->lu_seqid, &locku->lu_stateid, CHECK_FH | LOCK_STATE, diff .prev/include/linux/nfsd/xdr4.h ./include/linux/nfsd/xdr4.h --- .prev/include/linux/nfsd/xdr4.h 2006-12-08 12:07:22.000000000 +1100 +++ ./include/linux/nfsd/xdr4.h 2006-12-08 12:09:27.000000000 +1100 @@ -44,6 +44,11 @@ #define NFSD4_MAX_TAGLEN 128 #define XDR_LEN(n) (((n) + 3) & ~3) +struct nfsd4_compound_state { + struct svc_fh current_fh; + struct svc_fh save_fh; +}; + struct nfsd4_change_info { u32 atomic; u32 before_ctime_sec; @@ -437,20 +442,23 @@ extern __be32 nfsd4_process_open1(struct extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, - struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, + struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **); -extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern __be32 nfsd4_close(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner); extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, - struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, + struct nfsd4_compound_state *, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner); -extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner); -extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_lockt *lockt); -extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern __be32 nfsd4_locku(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner); extern __be32 @@ -458,7 +466,7 @@ nfsd4_release_lockowner(struct svc_rqst struct nfsd4_release_lockowner *rlockowner); extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, - struct svc_fh *current_fh, struct nfsd4_delegreturn *dr); + struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); #endif /* ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 010 of 18] knfsd: nfsd4: remove spurious replay_owner check 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (8 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 009 of 18] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 011 of 18] knfsd: nfsd4: move replay_owner to cstate NeilBrown ` (7 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> OK, this is embarassing--I've even looked back at the history, and cannot for the life of me figure out why I added this check. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 @@ -1008,7 +1008,7 @@ encode_op: nfsd4_encode_operation(resp, op); status = op->status; } - if (replay_owner && (replay_owner != (void *)(-1))) { + if (replay_owner) { nfs4_put_stateowner(replay_owner); replay_owner = NULL; } ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 011 of 18] knfsd: nfsd4: move replay_owner to cstate 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (9 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 010 of 18] knfsd: nfsd4: remove spurious replay_owner check NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 012 of 18] knfsd: nfsd4: don't inline nfsd4 compound op functions NeilBrown ` (6 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Tuck away the replay_owner in the cstate while we're at it. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 31 ++++++++++++++----------------- ./fs/nfsd/nfs4state.c | 22 ++++++++++------------ ./include/linux/nfsd/xdr4.h | 17 +++++++---------- 3 files changed, 31 insertions(+), 39 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 @@ -163,7 +163,7 @@ do_open_fhandle(struct svc_rqst *rqstp, static inline __be32 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) + struct nfsd4_open *open) { __be32 status; dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", @@ -255,7 +255,7 @@ nfsd4_open(struct svc_rqst *rqstp, struc out: if (open->op_stateowner) { nfs4_get_stateowner(open->op_stateowner); - *replay_owner = open->op_stateowner; + cstate->replay_owner = open->op_stateowner; } nfs4_unlock_state(); return status; @@ -761,6 +761,7 @@ static void cstate_free(struct nfsd4_com return; fh_put(&cstate->current_fh); fh_put(&cstate->save_fh); + BUG_ON(cstate->replay_owner); kfree(cstate); } @@ -773,6 +774,7 @@ static struct nfsd4_compound_state *csta return NULL; fh_init(&cstate->current_fh, NFS4_FHSIZE); fh_init(&cstate->save_fh, NFS4_FHSIZE); + cstate->replay_owner = NULL; return cstate; } @@ -786,7 +788,6 @@ nfsd4_proc_compound(struct svc_rqst *rqs { struct nfsd4_op *op; struct nfsd4_compound_state *cstate = NULL; - struct nfs4_stateowner *replay_owner = NULL; int slack_bytes; __be32 status; @@ -876,7 +877,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs break; case OP_CLOSE: op->status = nfsd4_close(rqstp, cstate, - &op->u.close, &replay_owner); + &op->u.close); break; case OP_COMMIT: op->status = nfsd4_commit(rqstp, cstate, @@ -901,15 +902,13 @@ nfsd4_proc_compound(struct svc_rqst *rqs op->status = nfsd4_link(rqstp, cstate, &op->u.link); break; case OP_LOCK: - op->status = nfsd4_lock(rqstp, cstate, &op->u.lock, - &replay_owner); + op->status = nfsd4_lock(rqstp, cstate, &op->u.lock); break; case OP_LOCKT: op->status = nfsd4_lockt(rqstp, cstate, &op->u.lockt); break; case OP_LOCKU: - op->status = nfsd4_locku(rqstp, cstate, &op->u.locku, - &replay_owner); + op->status = nfsd4_locku(rqstp, cstate, &op->u.locku); break; case OP_LOOKUP: op->status = nfsd4_lookup(rqstp, cstate, @@ -926,17 +925,15 @@ nfsd4_proc_compound(struct svc_rqst *rqs break; case OP_OPEN: op->status = nfsd4_open(rqstp, cstate, - &op->u.open, &replay_owner); + &op->u.open); break; case OP_OPEN_CONFIRM: op->status = nfsd4_open_confirm(rqstp, cstate, - &op->u.open_confirm, - &replay_owner); + &op->u.open_confirm); break; case OP_OPEN_DOWNGRADE: op->status = nfsd4_open_downgrade(rqstp, cstate, - &op->u.open_downgrade, - &replay_owner); + &op->u.open_downgrade); break; case OP_PUTFH: op->status = nfsd4_putfh(rqstp, cstate, &op->u.putfh); @@ -1001,16 +998,16 @@ nfsd4_proc_compound(struct svc_rqst *rqs encode_op: if (op->status == nfserr_replay_me) { - op->replay = &replay_owner->so_replay; + op->replay = &cstate->replay_owner->so_replay; nfsd4_encode_replay(resp, op); status = op->status = op->replay->rp_status; } else { nfsd4_encode_operation(resp, op); status = op->status; } - if (replay_owner) { - nfs4_put_stateowner(replay_owner); - replay_owner = NULL; + if (cstate->replay_owner) { + nfs4_put_stateowner(cstate->replay_owner); + cstate->replay_owner = NULL; } /* XXX Ugh, we need to get rid of this kind of special case: */ if (op->opnum == OP_READ && op->u.read.rd_filp) diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c --- .prev/fs/nfsd/nfs4state.c 2006-12-08 12:09:27.000000000 +1100 +++ ./fs/nfsd/nfs4state.c 2006-12-08 12:09:27.000000000 +1100 @@ -2243,8 +2243,7 @@ check_replay: __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_open_confirm *oc, - struct nfs4_stateowner **replay_owner) + struct nfsd4_open_confirm *oc) { __be32 status; struct nfs4_stateowner *sop; @@ -2281,7 +2280,7 @@ nfsd4_open_confirm(struct svc_rqst *rqst out: if (oc->oc_stateowner) { nfs4_get_stateowner(oc->oc_stateowner); - *replay_owner = oc->oc_stateowner; + cstate->replay_owner = oc->oc_stateowner; } nfs4_unlock_state(); return status; @@ -2315,8 +2314,7 @@ reset_union_bmap_deny(unsigned long deny __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_open_downgrade *od, - struct nfs4_stateowner **replay_owner) + struct nfsd4_open_downgrade *od) { __be32 status; struct nfs4_stateid *stp; @@ -2362,7 +2360,7 @@ nfsd4_open_downgrade(struct svc_rqst *rq out: if (od->od_stateowner) { nfs4_get_stateowner(od->od_stateowner); - *replay_owner = od->od_stateowner; + cstate->replay_owner = od->od_stateowner; } nfs4_unlock_state(); return status; @@ -2373,7 +2371,7 @@ out: */ __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) + struct nfsd4_close *close) { __be32 status; struct nfs4_stateid *stp; @@ -2406,7 +2404,7 @@ nfsd4_close(struct svc_rqst *rqstp, stru out: if (close->cl_stateowner) { nfs4_get_stateowner(close->cl_stateowner); - *replay_owner = close->cl_stateowner; + cstate->replay_owner = close->cl_stateowner; } nfs4_unlock_state(); return status; @@ -2647,7 +2645,7 @@ check_lock_length(u64 offset, u64 length */ __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) + struct nfsd4_lock *lock) { struct nfs4_stateowner *open_sop = NULL; struct nfs4_stateowner *lock_sop = NULL; @@ -2797,7 +2795,7 @@ out: release_stateowner(lock_sop); if (lock->lk_replay_owner) { nfs4_get_stateowner(lock->lk_replay_owner); - *replay_owner = lock->lk_replay_owner; + cstate->replay_owner = lock->lk_replay_owner; } nfs4_unlock_state(); return status; @@ -2889,7 +2887,7 @@ out: __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) + struct nfsd4_locku *locku) { struct nfs4_stateid *stp; struct file *filp = NULL; @@ -2947,7 +2945,7 @@ nfsd4_locku(struct svc_rqst *rqstp, stru out: if (locku->lu_stateowner) { nfs4_get_stateowner(locku->lu_stateowner); - *replay_owner = locku->lu_stateowner; + cstate->replay_owner = locku->lu_stateowner; } nfs4_unlock_state(); return status; diff .prev/include/linux/nfsd/xdr4.h ./include/linux/nfsd/xdr4.h --- .prev/include/linux/nfsd/xdr4.h 2006-12-08 12:09:27.000000000 +1100 +++ ./include/linux/nfsd/xdr4.h 2006-12-08 12:09:27.000000000 +1100 @@ -47,6 +47,7 @@ struct nfsd4_compound_state { struct svc_fh current_fh; struct svc_fh save_fh; + struct nfs4_stateowner *replay_owner; }; struct nfsd4_change_info { @@ -442,25 +443,21 @@ extern __be32 nfsd4_process_open1(struct extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc, - struct nfs4_stateowner **); + struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *, - struct nfsd4_close *close, - struct nfs4_stateowner **replay_owner); + struct nfsd4_close *close); extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_open_downgrade *od, - struct nfs4_stateowner **replay_owner); + struct nfsd4_compound_state *, + struct nfsd4_open_downgrade *od); extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, - struct nfsd4_lock *lock, - struct nfs4_stateowner **replay_owner); + struct nfsd4_lock *lock); extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *, struct nfsd4_lockt *lockt); extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *, - struct nfsd4_locku *locku, - struct nfs4_stateowner **replay_owner); + struct nfsd4_locku *locku); extern __be32 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner); ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 012 of 18] knfsd: nfsd4: don't inline nfsd4 compound op functions 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (10 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 011 of 18] knfsd: nfsd4: move replay_owner to cstate NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 013 of 18] knfsd: nfsd4: make verify and nverify wrappers NeilBrown ` (5 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> The inlining contributes to bloating the stack of nfsd4_compound, and I want to change the compound op functions to function pointers anyway. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:27.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:29.000000000 +1100 @@ -33,13 +33,6 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Note: some routines in this file are just trivial wrappers - * (e.g. nfsd4_lookup()) defined solely for the sake of consistent - * naming. Since all such routines have been declared "inline", - * there shouldn't be any associated overhead. At some point in - * the future, I might inline these "by hand" to clean up a - * little. */ #include <linux/param.h> @@ -161,7 +154,7 @@ do_open_fhandle(struct svc_rqst *rqstp, } -static inline __be32 +static __be32 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open) { @@ -264,7 +257,7 @@ out: /* * filehandle-manipulating ops. */ -static inline __be32 +static __be32 nfsd4_getfh(struct nfsd4_compound_state *cstate, struct svc_fh **getfh) { if (!cstate->current_fh.fh_dentry) @@ -274,7 +267,7 @@ nfsd4_getfh(struct nfsd4_compound_state return nfs_ok; } -static inline __be32 +static __be32 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_putfh *putfh) { @@ -285,7 +278,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, stru return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); } -static inline __be32 +static __be32 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) { __be32 status; @@ -296,7 +289,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, return status; } -static inline __be32 +static __be32 nfsd4_restorefh(struct nfsd4_compound_state *cstate) { if (!cstate->save_fh.fh_dentry) @@ -306,7 +299,7 @@ nfsd4_restorefh(struct nfsd4_compound_st return nfs_ok; } -static inline __be32 +static __be32 nfsd4_savefh(struct nfsd4_compound_state *cstate) { if (!cstate->current_fh.fh_dentry) @@ -319,7 +312,7 @@ nfsd4_savefh(struct nfsd4_compound_state /* * misc nfsv4 ops */ -static inline __be32 +static __be32 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_access *access) { @@ -331,7 +324,7 @@ nfsd4_access(struct svc_rqst *rqstp, str &access->ac_supported); } -static inline __be32 +static __be32 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_commit *commit) { @@ -434,7 +427,7 @@ nfsd4_create(struct svc_rqst *rqstp, str return status; } -static inline __be32 +static __be32 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_getattr *getattr) { @@ -454,7 +447,7 @@ nfsd4_getattr(struct svc_rqst *rqstp, st return nfs_ok; } -static inline __be32 +static __be32 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_link *link) { @@ -488,7 +481,7 @@ nfsd4_lookupp(struct svc_rqst *rqstp, st "..", 2, &cstate->current_fh); } -static inline __be32 +static __be32 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_lookup *lookup) { @@ -497,7 +490,7 @@ nfsd4_lookup(struct svc_rqst *rqstp, str &cstate->current_fh); } -static inline __be32 +static __be32 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_read *read) { @@ -527,7 +520,7 @@ out: return status; } -static inline __be32 +static __be32 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_readdir *readdir) { @@ -551,7 +544,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, st return nfs_ok; } -static inline __be32 +static __be32 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_readlink *readlink) { @@ -560,7 +553,7 @@ nfsd4_readlink(struct svc_rqst *rqstp, s return nfs_ok; } -static inline __be32 +static __be32 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_remove *remove) { @@ -579,7 +572,7 @@ nfsd4_remove(struct svc_rqst *rqstp, str return status; } -static inline __be32 +static __be32 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_rename *rename) { @@ -612,7 +605,7 @@ nfsd4_rename(struct svc_rqst *rqstp, str return status; } -static inline __be32 +static __be32 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) { @@ -639,7 +632,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, st return status; } -static inline __be32 +static __be32 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_write *write) { ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 013 of 18] knfsd: nfsd4: make verify and nverify wrappers 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (11 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 012 of 18] knfsd: nfsd4: don't inline nfsd4 compound op functions NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 014 of 18] knfsd: nfsd4: reorganize compound ops NeilBrown ` (4 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Make wrappers for verify and nverify, for consistency with other ops. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:29.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 @@ -681,7 +681,7 @@ nfsd4_write(struct svc_rqst *rqstp, stru * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. */ static __be32 -nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, +_nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_verify *verify) { __be32 *buf, *p; @@ -733,6 +733,26 @@ out_kfree: return status; } +static __be32 +nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_verify *verify) +{ + __be32 status; + + status = _nfsd4_verify(rqstp, cstate, verify); + return status == nfserr_not_same ? nfs_ok : status; +} + +static __be32 +nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_verify *verify) +{ + __be32 status; + + status = _nfsd4_verify(rqstp, cstate, verify); + return status == nfserr_same ? nfs_ok : status; +} + /* * NULL call. */ @@ -911,10 +931,8 @@ nfsd4_proc_compound(struct svc_rqst *rqs op->status = nfsd4_lookupp(rqstp, cstate); break; case OP_NVERIFY: - op->status = nfsd4_verify(rqstp, cstate, + op->status = nfsd4_nverify(rqstp, cstate, &op->u.nverify); - if (op->status == nfserr_not_same) - op->status = nfs_ok; break; case OP_OPEN: op->status = nfsd4_open(rqstp, cstate, @@ -975,8 +993,6 @@ nfsd4_proc_compound(struct svc_rqst *rqs case OP_VERIFY: op->status = nfsd4_verify(rqstp, cstate, &op->u.verify); - if (op->status == nfserr_same) - op->status = nfs_ok; break; case OP_WRITE: op->status = nfsd4_write(rqstp, cstate, &op->u.write); ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 014 of 18] knfsd: nfsd4: reorganize compound ops 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (12 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 013 of 18] knfsd: nfsd4: make verify and nverify wrappers NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 015 of 18] knfsd: nfsd4: simplify migration op check NeilBrown ` (3 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Define an op descriptor struct, use it to simplify nfsd4_proc_compound(). Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 254 +++++++++++++++++++++---------------------- ./fs/nfsd/nfs4state.c | 14 +- ./include/linux/nfsd/state.h | 1 ./include/linux/nfsd/xdr4.h | 5 4 files changed, 144 insertions(+), 130 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 @@ -258,7 +258,8 @@ out: * filehandle-manipulating ops. */ static __be32 -nfsd4_getfh(struct nfsd4_compound_state *cstate, struct svc_fh **getfh) +nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct svc_fh **getfh) { if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; @@ -279,7 +280,8 @@ nfsd4_putfh(struct svc_rqst *rqstp, stru } static __be32 -nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) +nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + void *arg) { __be32 status; @@ -290,7 +292,8 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, } static __be32 -nfsd4_restorefh(struct nfsd4_compound_state *cstate) +nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + void *arg) { if (!cstate->save_fh.fh_dentry) return nfserr_restorefh; @@ -300,7 +303,8 @@ nfsd4_restorefh(struct nfsd4_compound_st } static __be32 -nfsd4_savefh(struct nfsd4_compound_state *cstate) +nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + void *arg) { if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; @@ -463,7 +467,8 @@ nfsd4_link(struct svc_rqst *rqstp, struc } static __be32 -nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) +nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + void *arg) { struct svc_fh tmp_fh; __be32 ret; @@ -791,6 +796,16 @@ static struct nfsd4_compound_state *csta return cstate; } +typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, + void *); + +struct nfsd4_operation { + nfsd4op_func op_func; + u32 op_flags; +}; + +static struct nfsd4_operation nfsd4_ops[]; + /* * COMPOUND call. */ @@ -800,6 +815,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs struct nfsd4_compoundres *resp) { struct nfsd4_op *op; + struct nfsd4_operation *opdesc; struct nfsd4_compound_state *cstate = NULL; int slack_bytes; __be32 status; @@ -854,6 +870,8 @@ nfsd4_proc_compound(struct svc_rqst *rqs goto encode_op; } + opdesc = &nfsd4_ops[op->opnum]; + /* All operations except RENEW, SETCLIENTID, RESTOREFH * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH * require a valid current filehandle @@ -883,127 +901,11 @@ nfsd4_proc_compound(struct svc_rqst *rqs op->status = nfserr_moved; goto encode_op; } - switch (op->opnum) { - case OP_ACCESS: - op->status = nfsd4_access(rqstp, cstate, - &op->u.access); - break; - case OP_CLOSE: - op->status = nfsd4_close(rqstp, cstate, - &op->u.close); - break; - case OP_COMMIT: - op->status = nfsd4_commit(rqstp, cstate, - &op->u.commit); - break; - case OP_CREATE: - op->status = nfsd4_create(rqstp, cstate, - &op->u.create); - break; - case OP_DELEGRETURN: - op->status = nfsd4_delegreturn(rqstp, cstate, - &op->u.delegreturn); - break; - case OP_GETATTR: - op->status = nfsd4_getattr(rqstp, cstate, - &op->u.getattr); - break; - case OP_GETFH: - op->status = nfsd4_getfh(cstate, &op->u.getfh); - break; - case OP_LINK: - op->status = nfsd4_link(rqstp, cstate, &op->u.link); - break; - case OP_LOCK: - op->status = nfsd4_lock(rqstp, cstate, &op->u.lock); - break; - case OP_LOCKT: - op->status = nfsd4_lockt(rqstp, cstate, &op->u.lockt); - break; - case OP_LOCKU: - op->status = nfsd4_locku(rqstp, cstate, &op->u.locku); - break; - case OP_LOOKUP: - op->status = nfsd4_lookup(rqstp, cstate, - &op->u.lookup); - break; - case OP_LOOKUPP: - op->status = nfsd4_lookupp(rqstp, cstate); - break; - case OP_NVERIFY: - op->status = nfsd4_nverify(rqstp, cstate, - &op->u.nverify); - break; - case OP_OPEN: - op->status = nfsd4_open(rqstp, cstate, - &op->u.open); - break; - case OP_OPEN_CONFIRM: - op->status = nfsd4_open_confirm(rqstp, cstate, - &op->u.open_confirm); - break; - case OP_OPEN_DOWNGRADE: - op->status = nfsd4_open_downgrade(rqstp, cstate, - &op->u.open_downgrade); - break; - case OP_PUTFH: - op->status = nfsd4_putfh(rqstp, cstate, &op->u.putfh); - break; - case OP_PUTROOTFH: - op->status = nfsd4_putrootfh(rqstp, cstate); - break; - case OP_READ: - op->status = nfsd4_read(rqstp, cstate, &op->u.read); - break; - case OP_READDIR: - op->status = nfsd4_readdir(rqstp, cstate, - &op->u.readdir); - break; - case OP_READLINK: - op->status = nfsd4_readlink(rqstp, cstate, - &op->u.readlink); - break; - case OP_REMOVE: - op->status = nfsd4_remove(rqstp, cstate, - &op->u.remove); - break; - case OP_RENAME: - op->status = nfsd4_rename(rqstp, cstate, - &op->u.rename); - break; - case OP_RENEW: - op->status = nfsd4_renew(&op->u.renew); - break; - case OP_RESTOREFH: - op->status = nfsd4_restorefh(cstate); - break; - case OP_SAVEFH: - op->status = nfsd4_savefh(cstate); - break; - case OP_SETATTR: - op->status = nfsd4_setattr(rqstp, cstate, - &op->u.setattr); - break; - case OP_SETCLIENTID: - op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); - break; - case OP_SETCLIENTID_CONFIRM: - op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); - break; - case OP_VERIFY: - op->status = nfsd4_verify(rqstp, cstate, - &op->u.verify); - break; - case OP_WRITE: - op->status = nfsd4_write(rqstp, cstate, &op->u.write); - break; - case OP_RELEASE_LOCKOWNER: - op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); - break; - default: + + if (opdesc->op_func) + op->status = opdesc->op_func(rqstp, cstate, &op->u); + else BUG_ON(op->status == nfs_ok); - break; - } encode_op: if (op->status == nfserr_replay_me) { @@ -1031,6 +933,108 @@ out: return status; } +static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = { + [OP_ACCESS] = { + .op_func = (nfsd4op_func)nfsd4_access, + }, + [OP_CLOSE] = { + .op_func = (nfsd4op_func)nfsd4_close, + }, + [OP_COMMIT] = { + .op_func = (nfsd4op_func)nfsd4_commit, + }, + [OP_CREATE] = { + .op_func = (nfsd4op_func)nfsd4_create, + }, + [OP_DELEGRETURN] = { + .op_func = (nfsd4op_func)nfsd4_delegreturn, + }, + [OP_GETATTR] = { + .op_func = (nfsd4op_func)nfsd4_getattr, + }, + [OP_GETFH] = { + .op_func = (nfsd4op_func)nfsd4_getfh, + }, + [OP_LINK] = { + .op_func = (nfsd4op_func)nfsd4_link, + }, + [OP_LOCK] = { + .op_func = (nfsd4op_func)nfsd4_lock, + }, + [OP_LOCKT] = { + .op_func = (nfsd4op_func)nfsd4_lockt, + }, + [OP_LOCKU] = { + .op_func = (nfsd4op_func)nfsd4_locku, + }, + [OP_LOOKUP] = { + .op_func = (nfsd4op_func)nfsd4_lookup, + }, + [OP_LOOKUPP] = { + .op_func = (nfsd4op_func)nfsd4_lookupp, + }, + [OP_NVERIFY] = { + .op_func = (nfsd4op_func)nfsd4_nverify, + }, + [OP_OPEN] = { + .op_func = (nfsd4op_func)nfsd4_open, + }, + [OP_OPEN_CONFIRM] = { + .op_func = (nfsd4op_func)nfsd4_open_confirm, + }, + [OP_OPEN_DOWNGRADE] = { + .op_func = (nfsd4op_func)nfsd4_open_downgrade, + }, + [OP_PUTFH] = { + .op_func = (nfsd4op_func)nfsd4_putfh, + }, + [OP_PUTROOTFH] = { + .op_func = (nfsd4op_func)nfsd4_putrootfh, + }, + [OP_READ] = { + .op_func = (nfsd4op_func)nfsd4_read, + }, + [OP_READDIR] = { + .op_func = (nfsd4op_func)nfsd4_readdir, + }, + [OP_READLINK] = { + .op_func = (nfsd4op_func)nfsd4_readlink, + }, + [OP_REMOVE] = { + .op_func = (nfsd4op_func)nfsd4_remove, + }, + [OP_RENAME] = { + .op_func = (nfsd4op_func)nfsd4_rename, + }, + [OP_RENEW] = { + .op_func = (nfsd4op_func)nfsd4_renew, + }, + [OP_RESTOREFH] = { + .op_func = (nfsd4op_func)nfsd4_restorefh, + }, + [OP_SAVEFH] = { + .op_func = (nfsd4op_func)nfsd4_savefh, + }, + [OP_SETATTR] = { + .op_func = (nfsd4op_func)nfsd4_setattr, + }, + [OP_SETCLIENTID] = { + .op_func = (nfsd4op_func)nfsd4_setclientid, + }, + [OP_SETCLIENTID_CONFIRM] = { + .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, + }, + [OP_VERIFY] = { + .op_func = (nfsd4op_func)nfsd4_verify, + }, + [OP_WRITE] = { + .op_func = (nfsd4op_func)nfsd4_write, + }, + [OP_RELEASE_LOCKOWNER] = { + .op_func = (nfsd4op_func)nfsd4_release_lockowner, + }, +}; + #define nfs4svc_decode_voidargs NULL #define nfs4svc_release_void NULL #define nfsd4_voidres nfsd4_voidargs diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c --- .prev/fs/nfsd/nfs4state.c 2006-12-08 12:09:27.000000000 +1100 +++ ./fs/nfsd/nfs4state.c 2006-12-08 12:09:30.000000000 +1100 @@ -711,7 +711,8 @@ out_err: * */ __be32 -nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) +nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_setclientid *setclid) { __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; struct xdr_netobj clname = { @@ -876,7 +877,9 @@ out: * NOTE: callback information will be processed here in a future patch */ __be32 -nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm) +nfsd4_setclientid_confirm(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_setclientid_confirm *setclientid_confirm) { __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; struct nfs4_client *conf, *unconf; @@ -1834,7 +1837,8 @@ static void laundromat_main(void *); static DECLARE_WORK(laundromat_work, laundromat_main, NULL); __be32 -nfsd4_renew(clientid_t *clid) +nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + clientid_t *clid) { struct nfs4_client *clp; __be32 status; @@ -2980,7 +2984,9 @@ out: } __be32 -nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) +nfsd4_release_lockowner(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_release_lockowner *rlockowner) { clientid_t *clid = &rlockowner->rl_clientid; struct nfs4_stateowner *sop; diff .prev/include/linux/nfsd/state.h ./include/linux/nfsd/state.h --- .prev/include/linux/nfsd/state.h 2006-12-08 12:07:21.000000000 +1100 +++ ./include/linux/nfsd/state.h 2006-12-08 12:09:30.000000000 +1100 @@ -273,7 +273,6 @@ struct nfs4_stateid { ((err) != nfserr_stale_stateid) && \ ((err) != nfserr_bad_stateid)) -extern __be32 nfsd4_renew(clientid_t *clid); extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filp); extern void nfs4_lock_state(void); diff .prev/include/linux/nfsd/xdr4.h ./include/linux/nfsd/xdr4.h --- .prev/include/linux/nfsd/xdr4.h 2006-12-08 12:09:27.000000000 +1100 +++ ./include/linux/nfsd/xdr4.h 2006-12-08 12:09:30.000000000 +1100 @@ -436,8 +436,10 @@ __be32 nfsd4_encode_fattr(struct svc_fh struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, struct svc_rqst *); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_setclientid *setclid); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_setclientid_confirm *setclientid_confirm); extern __be32 nfsd4_process_open1(struct nfsd4_open *open); extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, @@ -460,10 +462,13 @@ extern __be32 nfsd4_locku(struct svc_rqs struct nfsd4_locku *locku); extern __be32 nfsd4_release_lockowner(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_release_lockowner *rlockowner); extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); +extern __be32 nfsd4_renew(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, clientid_t *clid); #endif /* ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 015 of 18] knfsd: nfsd4: simplify migration op check 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (13 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 014 of 18] knfsd: nfsd4: reorganize compound ops NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 016 of 18] knfsd: nfsd4: simplify filehandle check NeilBrown ` (2 subsequent siblings) 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> I'm not too fond of these big if conditions. Replace them by checks of a flag in the operation descriptor. To my eye this makes the code a bit more self-documenting, and makes the complicated part of the code (proc_compound) a little more compact. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 @@ -802,6 +802,8 @@ typedef __be32(*nfsd4op_func)(struct svc struct nfsd4_operation { nfsd4op_func op_func; u32 op_flags; +/* GETATTR and ops not listed as returning NFS4ERR_MOVED: */ +#define ALLOWED_ON_ABSENT_FS 1 }; static struct nfsd4_operation nfsd4_ops[]; @@ -887,17 +889,8 @@ nfsd4_proc_compound(struct svc_rqst *rqs op->status = nfserr_nofilehandle; goto encode_op; } - } - /* Check must be done at start of each operation, except - * for GETATTR and ops not listed as returning NFS4ERR_MOVED - */ - else if (cstate->current_fh.fh_export->ex_fslocs.migrated && - !((op->opnum == OP_GETATTR) || - (op->opnum == OP_PUTROOTFH) || - (op->opnum == OP_PUTPUBFH) || - (op->opnum == OP_RENEW) || - (op->opnum == OP_SETCLIENTID) || - (op->opnum == OP_RELEASE_LOCKOWNER))) { + } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && + !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { op->status = nfserr_moved; goto encode_op; } @@ -951,6 +944,7 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_GETATTR] = { .op_func = (nfsd4op_func)nfsd4_getattr, + .op_flags = ALLOWED_ON_ABSENT_FS, }, [OP_GETFH] = { .op_func = (nfsd4op_func)nfsd4_getfh, @@ -988,8 +982,13 @@ static struct nfsd4_operation nfsd4_ops[ [OP_PUTFH] = { .op_func = (nfsd4op_func)nfsd4_putfh, }, + [OP_PUTPUBFH] = { + /* unsupported; just for future reference: */ + .op_flags = ALLOWED_ON_ABSENT_FS, + }, [OP_PUTROOTFH] = { .op_func = (nfsd4op_func)nfsd4_putrootfh, + .op_flags = ALLOWED_ON_ABSENT_FS, }, [OP_READ] = { .op_func = (nfsd4op_func)nfsd4_read, @@ -1008,6 +1007,7 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_RENEW] = { .op_func = (nfsd4op_func)nfsd4_renew, + .op_flags = ALLOWED_ON_ABSENT_FS, }, [OP_RESTOREFH] = { .op_func = (nfsd4op_func)nfsd4_restorefh, @@ -1020,6 +1020,7 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_SETCLIENTID] = { .op_func = (nfsd4op_func)nfsd4_setclientid, + .op_flags = ALLOWED_ON_ABSENT_FS, }, [OP_SETCLIENTID_CONFIRM] = { .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, @@ -1032,6 +1033,7 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_RELEASE_LOCKOWNER] = { .op_func = (nfsd4op_func)nfsd4_release_lockowner, + .op_flags = ALLOWED_ON_ABSENT_FS, }, }; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 016 of 18] knfsd: nfsd4: simplify filehandle check 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (14 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 015 of 18] knfsd: nfsd4: simplify migration op check NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 017 of 18] knfsd: Don't ignore kstrdup failure in rpc caches NeilBrown 2006-12-08 1:14 ` [PATCH 018 of 18] knfsd: Fix up some bit-rot in exp_export NeilBrown 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel From: J.Bruce Fields <bfields@fieldses.org> Kill another big "if" clause. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/nfs4proc.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff .prev/fs/nfsd/nfs4proc.c ./fs/nfsd/nfs4proc.c --- .prev/fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 +++ ./fs/nfsd/nfs4proc.c 2006-12-08 12:09:30.000000000 +1100 @@ -802,8 +802,10 @@ typedef __be32(*nfsd4op_func)(struct svc struct nfsd4_operation { nfsd4op_func op_func; u32 op_flags; +/* Most ops require a valid current filehandle; a few don't: */ +#define ALLOWED_WITHOUT_FH 1 /* GETATTR and ops not listed as returning NFS4ERR_MOVED: */ -#define ALLOWED_ON_ABSENT_FS 1 +#define ALLOWED_ON_ABSENT_FS 2 }; static struct nfsd4_operation nfsd4_ops[]; @@ -874,18 +876,8 @@ nfsd4_proc_compound(struct svc_rqst *rqs opdesc = &nfsd4_ops[op->opnum]; - /* All operations except RENEW, SETCLIENTID, RESTOREFH - * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH - * require a valid current filehandle - */ if (!cstate->current_fh.fh_dentry) { - if (!((op->opnum == OP_PUTFH) || - (op->opnum == OP_PUTROOTFH) || - (op->opnum == OP_SETCLIENTID) || - (op->opnum == OP_SETCLIENTID_CONFIRM) || - (op->opnum == OP_RENEW) || - (op->opnum == OP_RESTOREFH) || - (op->opnum == OP_RELEASE_LOCKOWNER))) { + if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { op->status = nfserr_nofilehandle; goto encode_op; } @@ -981,14 +973,15 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_PUTFH] = { .op_func = (nfsd4op_func)nfsd4_putfh, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_PUTPUBFH] = { /* unsupported; just for future reference: */ - .op_flags = ALLOWED_ON_ABSENT_FS, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_PUTROOTFH] = { .op_func = (nfsd4op_func)nfsd4_putrootfh, - .op_flags = ALLOWED_ON_ABSENT_FS, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_READ] = { .op_func = (nfsd4op_func)nfsd4_read, @@ -1007,10 +1000,11 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_RENEW] = { .op_func = (nfsd4op_func)nfsd4_renew, - .op_flags = ALLOWED_ON_ABSENT_FS, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_RESTOREFH] = { .op_func = (nfsd4op_func)nfsd4_restorefh, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_SAVEFH] = { .op_func = (nfsd4op_func)nfsd4_savefh, @@ -1020,10 +1014,11 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_SETCLIENTID] = { .op_func = (nfsd4op_func)nfsd4_setclientid, - .op_flags = ALLOWED_ON_ABSENT_FS, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_SETCLIENTID_CONFIRM] = { .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, [OP_VERIFY] = { .op_func = (nfsd4op_func)nfsd4_verify, @@ -1033,7 +1028,7 @@ static struct nfsd4_operation nfsd4_ops[ }, [OP_RELEASE_LOCKOWNER] = { .op_func = (nfsd4op_func)nfsd4_release_lockowner, - .op_flags = ALLOWED_ON_ABSENT_FS, + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, }, }; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 017 of 18] knfsd: Don't ignore kstrdup failure in rpc caches. 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (15 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 016 of 18] knfsd: nfsd4: simplify filehandle check NeilBrown @ 2006-12-08 1:14 ` NeilBrown 2006-12-08 1:14 ` [PATCH 018 of 18] knfsd: Fix up some bit-rot in exp_export NeilBrown 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./net/sunrpc/svcauth_unix.c | 4 ++++ 1 file changed, 4 insertions(+) diff .prev/net/sunrpc/svcauth_unix.c ./net/sunrpc/svcauth_unix.c --- .prev/net/sunrpc/svcauth_unix.c 2006-12-08 12:08:37.000000000 +1100 +++ ./net/sunrpc/svcauth_unix.c 2006-12-08 12:09:31.000000000 +1100 @@ -53,6 +53,10 @@ struct auth_domain *unix_domain_find(cha return NULL; kref_init(&new->h.ref); new->h.name = kstrdup(name, GFP_KERNEL); + if (new->h.name == NULL) { + kfree(new); + return NULL; + } new->h.flavour = &svcauth_unix; new->addr_changes = 0; rv = auth_domain_lookup(name, &new->h); ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 018 of 18] knfsd: Fix up some bit-rot in exp_export 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown ` (16 preceding siblings ...) 2006-12-08 1:14 ` [PATCH 017 of 18] knfsd: Don't ignore kstrdup failure in rpc caches NeilBrown @ 2006-12-08 1:14 ` NeilBrown 17 siblings, 0 replies; 19+ messages in thread From: NeilBrown @ 2006-12-08 1:14 UTC (permalink / raw) To: Andrew Morton; +Cc: nfs, linux-kernel The nfsservctl systemcall isn't used but recent nfs-utils releases for exporting filesystems, and consequently the code that is uses - exp_export - has suffered some bitrot. Particular: - some newly added fields in 'struct svc_export' are being initialised properly. - the return value is now always -ENOMEM ... This patch fixes both these problems. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/nfsd/export.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c --- .prev/fs/nfsd/export.c 2006-12-08 12:08:37.000000000 +1100 +++ ./fs/nfsd/export.c 2006-12-08 12:09:31.000000000 +1100 @@ -955,6 +955,8 @@ exp_export(struct nfsctl_export *nxp) exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); + memset(&new, 0, sizeof(new)); + /* must make sure there won't be an ex_fsid clash */ if ((nxp->ex_flags & NFSEXP_FSID) && (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && @@ -985,6 +987,9 @@ exp_export(struct nfsctl_export *nxp) new.h.expiry_time = NEVER; new.h.flags = 0; + new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); + if (! new.ex_path) + goto finish; new.ex_client = clp; new.ex_mnt = nd.mnt; new.ex_dentry = nd.dentry; @@ -1005,10 +1010,11 @@ exp_export(struct nfsctl_export *nxp) /* failed to create at least one index */ exp_do_unexport(exp); cache_flush(); - err = -ENOMEM; - } - + } else + err = 0; finish: + if (new.ex_path) + kfree(new.ex_path); if (exp) exp_put(exp); if (fsid_key && !IS_ERR(fsid_key)) ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2006-12-08 1:14 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-12-08 1:13 [PATCH 000 of 18] knfsd: Introduction - NFSv4 updates and more NeilBrown 2006-12-08 1:13 ` [PATCH 001 of 18] knfsd: nfsd4: remove a dprink from nfsd4_lock NeilBrown 2006-12-08 1:13 ` [PATCH 002 of 18] knfsd: svcrpc: fix gss krb5i memory leak NeilBrown 2006-12-08 1:13 ` [PATCH 003 of 18] knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE NeilBrown 2006-12-08 1:13 ` [PATCH 004 of 18] knfsd: nfsd: make exp_rootfh handle exp_parent errors NeilBrown 2006-12-08 1:13 ` [PATCH 005 of 18] knfsd: nfsd: simplify exp_pseudoroot NeilBrown 2006-12-08 1:13 ` [PATCH 006 of 18] knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir NeilBrown 2006-12-08 1:13 ` [PATCH 007 of 18] knfsd: nfsd: don't drop silently on upcall deferral NeilBrown 2006-12-08 1:14 ` [PATCH 008 of 18] knfsd: svcrpc: remove another silent drop from deferral code NeilBrown 2006-12-08 1:14 ` [PATCH 009 of 18] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations NeilBrown 2006-12-08 1:14 ` [PATCH 010 of 18] knfsd: nfsd4: remove spurious replay_owner check NeilBrown 2006-12-08 1:14 ` [PATCH 011 of 18] knfsd: nfsd4: move replay_owner to cstate NeilBrown 2006-12-08 1:14 ` [PATCH 012 of 18] knfsd: nfsd4: don't inline nfsd4 compound op functions NeilBrown 2006-12-08 1:14 ` [PATCH 013 of 18] knfsd: nfsd4: make verify and nverify wrappers NeilBrown 2006-12-08 1:14 ` [PATCH 014 of 18] knfsd: nfsd4: reorganize compound ops NeilBrown 2006-12-08 1:14 ` [PATCH 015 of 18] knfsd: nfsd4: simplify migration op check NeilBrown 2006-12-08 1:14 ` [PATCH 016 of 18] knfsd: nfsd4: simplify filehandle check NeilBrown 2006-12-08 1:14 ` [PATCH 017 of 18] knfsd: Don't ignore kstrdup failure in rpc caches NeilBrown 2006-12-08 1:14 ` [PATCH 018 of 18] knfsd: Fix up some bit-rot in exp_export NeilBrown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox