Commit ba5e8187 authored by Jeff Layton's avatar Jeff Layton Committed by Chuck Lever
Browse files

nfsd: allow filesystems to opt out of subtree checking



When we start allowing NFS to be reexported, then we have some problems
when it comes to subtree checking. In principle, we could allow it, but
it would mean encoding parent info in the filehandles and there may not
be enough space for that in a NFSv3 filehandle.

To enforce this at export upcall time, we add a new export_ops flag
that declares the filesystem ineligible for subtree checking.

Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarLance Shelton <lance.shelton@hammerspace.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent daab110e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -190,3 +190,15 @@ following flags are defined:
    this on filesystems that have an expensive ->getattr inode operation,
    or when atomicity between pre and post operation attribute collection
    is impossible to guarantee.

  EXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fs
    Many NFS operations deal with filehandles, which the server must then
    vet to ensure that they live inside of an exported tree. When the
    export consists of an entire filesystem, this is trivial. nfsd can just
    ensure that the filehandle live on the filesystem. When only part of a
    filesystem is exported however, then nfsd must walk the ancestors of the
    inode to ensure that it's within an exported subtree. This is an
    expensive operation and not all filesystems can support it properly.
    This flag exempts the filesystem from subtree checking and causes
    exportfs to get back an error if it tries to enable subtree checking
    on it.
+1 −1
Original line number Diff line number Diff line
@@ -171,5 +171,5 @@ const struct export_operations nfs_export_ops = {
	.encode_fh = nfs_encode_fh,
	.fh_to_dentry = nfs_fh_to_dentry,
	.get_parent = nfs_get_parent,
	.flags = EXPORT_OP_NOWCC,
	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK,
};
+6 −0
Original line number Diff line number Diff line
@@ -408,6 +408,12 @@ static int check_export(struct inode *inode, int *flags, unsigned char *uuid)
		return -EINVAL;
	}

	if (inode->i_sb->s_export_op->flags & EXPORT_OP_NOSUBTREECHK &&
	    !(*flags & NFSEXP_NOSUBTREECHECK)) {
		dprintk("%s: %s does not support subtree checking!\n",
			__func__, inode->i_sb->s_type->name);
		return -EINVAL;
	}
	return 0;

}
+1 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ struct export_operations {
	int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
			     int nr_iomaps, struct iattr *iattr);
#define	EXPORT_OP_NOWCC		(0x1)	/* Don't collect wcc data for NFSv3 replies */
#define	EXPORT_OP_NOSUBTREECHK	(0x2)	/* Subtree checking is not supported! */
	unsigned long	flags;
};