X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=fs%2Fnfsd%2Fvfs.c;h=a0015a958aeff545688b10bf8ee85ef88c7f069c;hp=638573968dcfb1573bfb57100e9f16c4fce1df5a;hb=3227fa41abc191384fa81b3bcf52aa7fccb31536;hpb=289ede453e5a621de19c61e630302b1845cc1d59 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6385739..a0015a9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -16,48 +16,31 @@ * Zerocpy NFS support (C) 2002 Hirokazu Takahashi */ -#include -#include -#include #include #include -#include -#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include -#ifdef CONFIG_NFSD_V3 -#include -#include -#endif /* CONFIG_NFSD_V3 */ -#include #include #include -#include #include #include +#include +#include +#include + +#ifdef CONFIG_NFSD_V3 +#include "xdr3.h" +#endif /* CONFIG_NFSD_V3 */ + #ifdef CONFIG_NFSD_V4 -#include #include #include -#include #endif /* CONFIG_NFSD_V4 */ -#include -#include -#include +#include "nfsd.h" +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_FILEOP @@ -116,8 +99,16 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, exp2 = rqst_exp_get_by_name(rqstp, &path); if (IS_ERR(exp2)) { - if (PTR_ERR(exp2) != -ENOENT) - err = PTR_ERR(exp2); + err = PTR_ERR(exp2); + /* + * We normally allow NFS clients to continue + * "underneath" a mountpoint that is not exported. + * The exception is V4ROOT, where no traversal is ever + * allowed without an explicit export of the new + * directory. + */ + if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) + err = 0; path_put(&path); goto out; } @@ -175,6 +166,19 @@ static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, st return 0; } +/* + * For nfsd purposes, we treat V4ROOT exports as though there was an + * export at *every* directory. + */ +int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) +{ + if (d_mountpoint(dentry)) + return 1; + if (!(exp->ex_flags & NFSEXP_V4ROOT)) + return 0; + return dentry->d_inode != NULL; +} + __be32 nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, unsigned int len, @@ -220,7 +224,7 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, /* * check if we have crossed a mount point ... */ - if (d_mountpoint(dentry)) { + if (nfsd_mountpoint(dentry, exp)) { if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { dput(dentry); goto out_nfserr;