From 4d4d890f5e4b91fe7b795d09852b3c4d1f13f389 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 14 Mar 2003 02:12:01 -0800 Subject: [PATCH] [PATCH] kNFSd: Introduce CROSSMNT flag for knfsd Now that we have working up-calls to userspace, CROSSMNT makes sense. If CROSSMNT is set for an export, and we too a LOOKUP which crosses a mountpoint, we initiate an upcall to find out if and how that filesystem is exported. --- fs/nfsd/export.c | 9 ++++++++- fs/nfsd/vfs.c | 18 +++++++++++++++++- include/linux/nfsd/export.h | 3 ++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 00caf0afa1be..4ea38a35403e 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -475,8 +475,14 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, exp = svc_export_lookup(&key, 0); if (exp != NULL) - if (cache_check(&svc_export_cache, &exp->h, reqp)) + switch (cache_check(&svc_export_cache, &exp->h, reqp)) { + case 0: break; + case -EAGAIN: + exp = ERR_PTR(-EAGAIN); + break; + default: exp = NULL; + } return exp; } @@ -918,6 +924,7 @@ struct flags { { NFSEXP_KERBEROS, { "kerberos", ""}}, { NFSEXP_SUNSECURE, { "sunsecure", ""}}, { NFSEXP_NOHIDE, {"nohide", ""}}, + { NFSEXP_CROSSMNT, {"crossmnt", ""}}, { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, #ifdef MSNFS diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e869ef882cd6..d749aef9c3a5 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -133,6 +133,12 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, exp2 = exp_parent(exp->ex_client, mnt, dentry, &rqstp->rq_chandle); + if (IS_ERR(exp2)) { + err = PTR_ERR(exp2); + dput(dentry); + mntput(mnt); + goto out; + } if (!exp2) { dput(dentry); dentry = dget(dparent); @@ -157,9 +163,19 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, struct dentry *mounts = dget(dentry); while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)) ; + exp2 = exp_get_by_name(exp->ex_client, mnt, mounts, &rqstp->rq_chandle); - if (exp2 && EX_NOHIDE(exp2)) { + if (IS_ERR(exp2)) { + err = PTR_ERR(exp2); + dput(mounts); + dput(dentry); + mntput(mnt); + goto out; + } + if (exp2 && + ((exp->ex_flags & NFSEXP_CROSSMNT) + || EX_NOHIDE(exp2))) { /* successfully crossed mount point */ exp_put(exp); exp = exp2; diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index c37f57ae878b..48860ac34dae 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -40,7 +40,8 @@ #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ #define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */ #define NFSEXP_FSID 0x2000 -#define NFSEXP_ALLFLAGS 0x3FFF +#define NFSEXP_CROSSMNT 0x4000 +#define NFSEXP_ALLFLAGS 0x7FFF #ifdef __KERNEL__ -- 2.39.5