@@ -833,6 +833,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
goto out;
if (d_really_is_negative(dchild))
goto out;
+ if (IS_AUTOMOUNT(dchild->d_inode))
+ goto out;
if (dchild->d_inode->i_ino != ino)
goto out;
rv = fh_compose(fhp, exp, dchild, &cd->fh);
@@ -244,8 +244,12 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
* dentry may be negative, it may need to be updated.
*/
err = fh_compose(resfh, exp, dentry, fhp);
- if (!err && d_really_is_negative(dentry))
- err = nfserr_noent;
+ if (!err) {
+ if (d_really_is_negative(dentry))
+ err = nfserr_noent;
+ else if (IS_AUTOMOUNT(dentry->d_inode))
+ err = nfserr_remote;
+ }
out:
dput(dentry);
exp_put(exp);
Our interest with the NFS reexporting code is primarily to reexport NFSv4 filesystems, but there is no way to get the fsid that is associated with an inode. So, we must require that any reexported NFSv4 filesystem have an explicit fsid= value assigned to it. That value must also be persistent across reboots or we'll see a lot of ESTALE errors. Because of this requirement, we can't really deal with transparent automounting (and implicit exporting) of NFSv4 filesystems after a mountpoint traversal. Don't allow knfsd to traverse S_AUTOMOUNT inodes. If we find one in a LOOKUP then we simply return NFS3ERR_REMOTE. In the case of READDIRPLUS, we opt not to send any attributes for the inode, so the follow on stat() call (if any) can figure out that it's remote. Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> --- fs/nfsd/nfs3xdr.c | 2 ++ fs/nfsd/vfs.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)