From 3af56fd95fbe8b417d7ed7c9c25ef59d6f1ee161 Mon Sep 17 00:00:00 2001 From: Ned Bass Date: Wed, 16 Sep 2015 02:49:09 -0700 Subject: [PATCH] Honor xattr=sa dataset property ZFS incorrectly uses directory-based extended attributes even when xattr=sa is specified as a dataset property or mount option. Support to honor temporary mount options including "xattr" was added in commit 0282c4137e7409e6d85289f4955adf07fac834f5. There are two issues with the mount option handling: * Libzfs has historically included "xattr" in its list of default mount options. This overrides the dataset property, so the dataset is always configured to use directory-based xattrs even when the xattr dataset property is set to off or sa. Address this by removing "xattr" from the set of default mount options in libzfs. * There was no way to enable system attribute-based extended attributes using temporary mount options. Add the mount options "saxattr" and "dirxattr" which enable the xattr behavior their names suggest. This approach has the advantages of mirroring the valid xattr dataset property values and following existing conventions for mount option names. Signed-off-by: Ned Bass Signed-off-by: Brian Behlendorf Closes #3787 --- include/sys/mntent.h | 2 ++ include/sys/zfs_vfsops.h | 2 +- lib/libzfs/libzfs_mount.c | 2 -- man/man8/mount.zfs.8 | 14 +++++++++++--- module/zfs/zpl_super.c | 16 ++++++++++++++-- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/sys/mntent.h b/include/sys/mntent.h index e6ce117769..7284f05b1d 100644 --- a/include/sys/mntent.h +++ b/include/sys/mntent.h @@ -88,6 +88,8 @@ #define MNTOPT_LOUD "loud" /* verbose mount */ #define MNTOPT_BIND "bind" /* remount part of a tree */ #define MNTOPT_RBIND "rbind" /* include subtrees */ +#define MNTOPT_DIRXATTR "dirxattr" /* enable directory xattrs */ +#define MNTOPT_SAXATTR "saxattr" /* enable system-attribute xattrs */ #define MNTOPT_XATTR "xattr" /* enable extended attributes */ #define MNTOPT_NOXATTR "noxattr" /* disable extended attributes */ #define MNTOPT_COMMENT "comment" /* comment */ diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 3d2b249c9f..28407c6f76 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -44,6 +44,7 @@ struct znode; typedef struct zfs_mntopts { char *z_osname; /* Objset name */ char *z_mntpoint; /* Primary mount point */ + uint64_t z_xattr; boolean_t z_readonly; boolean_t z_do_readonly; boolean_t z_setuid; @@ -52,7 +53,6 @@ typedef struct zfs_mntopts { boolean_t z_do_exec; boolean_t z_devices; boolean_t z_do_devices; - boolean_t z_xattr; boolean_t z_do_xattr; boolean_t z_atime; boolean_t z_do_atime; diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 0e3332e0e3..c01ec105e4 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -371,8 +371,6 @@ zfs_add_options(zfs_handle_t *zhp, char *options, int len) ZFS_PROP_READONLY, MNTOPT_RO, MNTOPT_RW); error = error ? error : zfs_add_option(zhp, options, len, ZFS_PROP_SETUID, MNTOPT_SETUID, MNTOPT_NOSETUID); - error = error ? error : zfs_add_option(zhp, options, len, - ZFS_PROP_XATTR, MNTOPT_XATTR, MNTOPT_NOXATTR); error = error ? error : zfs_add_option(zhp, options, len, ZFS_PROP_NBMAND, MNTOPT_NBMAND, MNTOPT_NONBMAND); diff --git a/man/man8/mount.zfs.8 b/man/man8/mount.zfs.8 index b4e2406a22..362a8332fb 100644 --- a/man/man8/mount.zfs.8 +++ b/man/man8/mount.zfs.8 @@ -83,7 +83,7 @@ under that mountpoint. This flag sets the SELinux context for the filesytem being mounted. .TP .BI "\-o defcontext" -This flag sets the SELinux context for unlabled files. +This flag sets the SELinux context for unlabeled files. .TP .BI "\-o rootcontext" This flag sets the SELinux context for the root inode of the filesystem. @@ -97,8 +97,16 @@ has an entry in the /etc/fstab file. This private flag disables extended attributes. .TP .BI "\-o xattr -This private flag enables extended attributes and, if appropriate, -adds a ZFS context to the selinux system policy. +This private flag enables directory-based extended attributes and, if +appropriate, adds a ZFS context to the selinux system policy. +.TP +.BI "\-o saxattr +This private flag enables system attributed-based extended attributes and, if +appropriate, adds a ZFS context to the selinux system policy. +.TP +.BI "\-o dirxattr +Equivalent to +.BR xattr . .TP .BI "\-o zfsutil" This private flag indicates that diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index 80cc15725c..87895d6ba2 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -193,6 +193,8 @@ enum { TOKEN_NOEXEC, TOKEN_DEVICES, TOKEN_NODEVICES, + TOKEN_DIRXATTR, + TOKEN_SAXATTR, TOKEN_XATTR, TOKEN_NOXATTR, TOKEN_ATIME, @@ -214,6 +216,8 @@ static const match_table_t zpl_tokens = { { TOKEN_NOEXEC, MNTOPT_NOEXEC }, { TOKEN_DEVICES, MNTOPT_DEVICES }, { TOKEN_NODEVICES, MNTOPT_NODEVICES }, + { TOKEN_DIRXATTR, MNTOPT_DIRXATTR }, + { TOKEN_SAXATTR, MNTOPT_SAXATTR }, { TOKEN_XATTR, MNTOPT_XATTR }, { TOKEN_NOXATTR, MNTOPT_NOXATTR }, { TOKEN_ATIME, MNTOPT_ATIME }, @@ -262,12 +266,20 @@ zpl_parse_option(char *option, int token, substring_t *args, zfs_mntopts_t *zmo) zmo->z_devices = B_FALSE; zmo->z_do_devices = B_TRUE; break; + case TOKEN_DIRXATTR: + zmo->z_xattr = ZFS_XATTR_DIR; + zmo->z_do_xattr = B_TRUE; + break; + case TOKEN_SAXATTR: + zmo->z_xattr = ZFS_XATTR_SA; + zmo->z_do_xattr = B_TRUE; + break; case TOKEN_XATTR: - zmo->z_xattr = B_TRUE; + zmo->z_xattr = ZFS_XATTR_DIR; zmo->z_do_xattr = B_TRUE; break; case TOKEN_NOXATTR: - zmo->z_xattr = B_FALSE; + zmo->z_xattr = ZFS_XATTR_OFF; zmo->z_do_xattr = B_TRUE; break; case TOKEN_ATIME: