aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ.Bruce Fields <bfields@fieldses.org>2006-12-13 03:35:25 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-13 12:05:54 -0500
commite0bb89ef031f76dcb9c9d920d18b13948f1418da (patch)
tree6016032b160db2cf697eea19cd0f12ace946c7cc /fs/nfsd
parent021d3a72459191a76e8e482ee4937ba6bc9fd712 (diff)
[PATCH] knfsd: nfsd: don't drop silently on upcall deferral
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> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/export.c11
-rw-r--r--fs/nfsd/nfsfh.c6
-rw-r--r--fs/nfsd/vfs.c2
3 files changed, 13 insertions, 6 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index b0591cd172eb..1137d09c5976 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -787,15 +787,20 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
787 key.ex_dentry = dentry; 787 key.ex_dentry = dentry;
788 788
789 exp = svc_export_lookup(&key); 789 exp = svc_export_lookup(&key);
790 if (exp != NULL) 790 if (exp != NULL) {
791 switch (cache_check(&svc_export_cache, &exp->h, reqp)) { 791 int err;
792
793 err = cache_check(&svc_export_cache, &exp->h, reqp);
794 switch (err) {
792 case 0: break; 795 case 0: break;
793 case -EAGAIN: 796 case -EAGAIN:
794 exp = ERR_PTR(-EAGAIN); 797 case -ETIMEDOUT:
798 exp = ERR_PTR(err);
795 break; 799 break;
796 default: 800 default:
797 exp = NULL; 801 exp = NULL;
798 } 802 }
803 }
799 804
800 return exp; 805 return exp;
801} 806}
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 727ab3bd450d..b06bf9f70efc 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -169,9 +169,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
169 exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); 169 exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
170 } 170 }
171 171
172 error = nfserr_dropit; 172 if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
173 if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN) 173 || PTR_ERR(exp) == -ETIMEDOUT)) {
174 error = nfserrno(PTR_ERR(exp));
174 goto out; 175 goto out;
176 }
175 177
176 error = nfserr_stale; 178 error = nfserr_stale;
177 if (!exp || IS_ERR(exp)) 179 if (!exp || IS_ERR(exp))
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4883d7586229..7a79c23aa6d4 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -99,7 +99,7 @@ static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE];
99/* 99/*
100 * Called from nfsd_lookup and encode_dirent. Check if we have crossed 100 * Called from nfsd_lookup and encode_dirent. Check if we have crossed
101 * a mount point. 101 * a mount point.
102 * Returns -EAGAIN leaving *dpp and *expp unchanged, 102 * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged,
103 * or nfs_ok having possibly changed *dpp and *expp 103 * or nfs_ok having possibly changed *dpp and *expp
104 */ 104 */
105int 105int