diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-21 22:34:01 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-21 22:34:01 +0000 |
commit | 9e30c3705aed9fbec4c3304570e4d6e707856bcb (patch) | |
tree | b19e6acb5a67af31a4e7742e05c2166dc3f1444c /fs/nfsd | |
parent | 72919904796333a20c6a5d5c380091b42e407aa9 (diff) |
Merge with Linux 2.3.22.
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/export.c | 2 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 41 |
2 files changed, 28 insertions, 15 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 0a9b5cf06..1ad581ea8 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -627,7 +627,7 @@ struct flags { { NFSEXP_UIDMAP, {"uidmap", ""}}, { NFSEXP_KERBEROS, { "kerberos", ""}}, { NFSEXP_SUNSECURE, { "sunsecure", ""}}, - { NFSEXP_CROSSMNT, {"crossmnt", ""}}, + { NFSEXP_CROSSMNT, {"nohide", ""}}, { 0, {"", ""}} }; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 999d90d25..fa1753633 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -137,6 +137,14 @@ nfsd_iscovered(struct dentry *dentry, struct svc_export *exp) /* * Look up one component of a pathname. * N.B. After this call _both_ fhp and resfh need an fh_put + * + * If the lookup would cross a mountpoint, and the mounted filesystem + * is exported to the client with NFSEXP_CROSSMNT, then the lookup is + * accepted as it stands and the mounted directory is + * returned. Otherwise the covered directory is returned. + * NOTE: this mountpoint crossing is not supported properly by all + * clients and is explicitly disallowed for NFSv3 + * NeilBrown <neilb@cse.unsw.edu.au> */ int nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, @@ -176,18 +184,27 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, * check if we have crossed a mount point ... */ if (dchild->d_sb != dparent->d_sb) { - struct dentry *tdentry; - tdentry = dchild->d_covers; - if (tdentry == dchild) - goto out_dput; - dput(dchild); - dchild = dget(tdentry); - if (dchild->d_sb != dparent->d_sb) { -printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name, dchild->d_name.name); - goto out_dput; + struct svc_export *exp2 = NULL; + exp2 = exp_get(rqstp->rq_client, + dchild->d_inode->i_dev, + dchild->d_inode->i_ino); + if (exp2 && EX_CROSSMNT(exp2)) + /* successfully crossed mount point */ + exp = exp2; + else if (dchild->d_covers->d_sb == dparent->d_sb) { + /* stay in the original filesystem */ + struct dentry *tdentry = dget(dchild->d_covers); + dput(dchild); + dchild = tdentry; + } else { + /* This cannot possibly happen */ + printk("nfsd_lookup: %s/%s impossible mount point!\n", dparent->d_name.name, dchild->d_name.name); + dput(dchild); + err = nfserr_acces; + goto out; + } } - /* * Note: we compose the file handle now, but as the * dentry may be negative, it may need to be updated. @@ -202,10 +219,6 @@ out: out_nfserr: err = nfserrno(-PTR_ERR(dchild)); goto out; -out_dput: - dput(dchild); - err = nfserr_acces; - goto out; } /* |