diff options
author | Brian Behlendorf <[email protected]> | 2011-05-19 11:44:07 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-07-01 13:36:39 -0700 |
commit | 2cf7f52bc42f215d4ef27d0fd75fc1b1417cb841 (patch) | |
tree | 3b30ae22546bd09968cff08c7a41bb9e791ea91d /lib | |
parent | 5c03efc379693f992ebe39c6a00c7297c4a304ea (diff) |
Linux compat 2.6.39: mount_nodev()
The .get_sb callback has been replaced by a .mount callback
in the file_system_type structure. When using the new
interface the caller must now use the mount_nodev() helper.
Unfortunately, the new interface no longer passes the vfsmount
down to the zfs layers. This poses a problem for the existing
implementation because we currently save this pointer in the
super block for latter use. It provides our only entry point
in to the namespace layer for manipulating certain mount options.
This needed to be done originally to allow commands like
'zfs set atime=off tank' to work properly. It also allowed me
to keep more of the original Solaris code unmodified. Under
Solaris there is a 1-to-1 mapping between a mount point and a
file system so this is a fairly natural thing to do. However,
under Linux they many be multiple entries in the namespace
which reference the same filesystem. Thus keeping a back
reference from the filesystem to the namespace is complicated.
Rather than introduce some ugly hack to get the vfsmount and
continue as before. I'm leveraging this API change to update
the ZFS code to do things in a more natural way for Linux.
This has the upside that is resolves the compatibility issue
for the long term and fixes several other minor bugs which
have been reported.
This commit updates the code to remove this vfsmount back
reference entirely. All modifications to filesystem mount
options are now passed in to the kernel via a '-o remount'.
This is the expected Linux mechanism and allows the namespace
to properly handle any options which apply to it before passing
them on to the file system itself.
Aside from fixing the compatibility issue, removing the
vfsmount has had the benefit of simplifying the code. This
change which fairly involved has turned out nicely.
Closes #246
Closes #217
Closes #187
Closes #248
Closes #231
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libavl/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libefi/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libnvpair/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/asm-generic/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/asm-i386/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/asm-x86_64/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/ia32/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/ia32/sys/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/rpc/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/sys/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/sys/dktp/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/sys/mntent.h | 4 | ||||
-rw-r--r-- | lib/libspl/include/sys/sysevent/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libspl/include/util/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libunicode/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libuutil/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libzfs/Makefile.in | 1 | ||||
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 41 | ||||
-rw-r--r-- | lib/libzfs/libzfs_mount.c | 79 | ||||
-rw-r--r-- | lib/libzpool/Makefile.in | 1 |
23 files changed, 131 insertions, 13 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in index 418476087..107aa7678 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -61,6 +61,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 9ab160e43..f7a6abd66 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 8116a2374..f2cb56011 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index 318dcbd04..13e64b5dc 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 09dd5245c..fa1ff51f1 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index 7e03433f2..6aeb054b8 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -62,6 +62,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index 85bebc9b3..c91a2bb7f 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index b6b9bed8f..7afeb56d8 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index b2de0ad14..5708683ff 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index d68fa7b74..7a6e4862e 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -61,6 +61,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index 30b81de33..2637df9cb 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 3b1270e58..9561e97a2 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index ccfefaa5d..503fefb5a 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index 9eed96c9d..40d4e0c44 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/sys/mntent.h b/lib/libspl/include/sys/mntent.h index 1cbdc3aeb..8fad65b56 100644 --- a/lib/libspl/include/sys/mntent.h +++ b/lib/libspl/include/sys/mntent.h @@ -88,8 +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_XATTR "user_xattr" /* enable extended attributes */ -#define MNTOPT_NOXATTR "nouser_xattr" /* disable extended attributes */ +#define MNTOPT_XATTR "xattr" /* enable extended attributes */ +#define MNTOPT_NOXATTR "noxattr" /* disable extended attributes */ #define MNTOPT_COMMENT "comment" /* comment */ #define MNTOPT_ZFSUTIL "zfsutil" /* called by zfs utility */ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index 83ce2b2fa..ed9f563cc 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index 1339ebc48..2a2a0c16d 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index 48a710020..6d1ffb432 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index bd224872d..8678411c8 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index d73e8eb8b..73ec60585 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 378bbc7b1..5f8847a93 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1313,6 +1313,25 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err, } } +static boolean_t +zfs_is_namespace_prop(zfs_prop_t prop) +{ + switch (prop) { + + case ZFS_PROP_ATIME: + case ZFS_PROP_DEVICES: + case ZFS_PROP_EXEC: + case ZFS_PROP_SETUID: + case ZFS_PROP_READONLY: + case ZFS_PROP_XATTR: + case ZFS_PROP_NBMAND: + return (B_TRUE); + + default: + return (B_FALSE); + } +} + /* * Given a property name and value, set the property for the given dataset. */ @@ -1408,12 +1427,22 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) if (do_prefix) ret = changelist_postfix(cl); - /* - * Refresh the statistics so the new property value - * is reflected. - */ - if (ret == 0) + if (ret == 0) { + /* + * Refresh the statistics so the new property + * value is reflected. + */ (void) get_stats(zhp); + + /* + * Remount the filesystem to propagate the change + * if one of the options handled by the generic + * Linux namespace layer has been modified. + */ + if (zfs_is_namespace_prop(prop) && + zfs_is_mounted(zhp, NULL)) + ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0); + } } error: @@ -1530,7 +1559,7 @@ error: * True DSL properties are stored in an nvlist. The following two functions * extract them appropriately. */ -static uint64_t +uint64_t getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source) { nvlist_t *nv; diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 1dc58f924..6b70cbbec 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -315,6 +315,52 @@ do_unmount(const char *mntpt, int flags) return (rc ? EINVAL : 0); } +static int +zfs_add_option(zfs_handle_t *zhp, char *options, int len, + zfs_prop_t prop, char *on, char *off) +{ + char *source; + uint64_t value; + + /* Skip adding duplicate default options */ + if ((strstr(options, on) != NULL) || (strstr(options, off) != NULL)) + return (0); + + /* + * zfs_prop_get_int() to not used to ensure our mount options + * are not influenced by the current /etc/mtab contents. + */ + value = getprop_uint64(zhp, prop, &source); + + (void) strlcat(options, ",", len); + (void) strlcat(options, value ? on : off, len); + + return (0); +} + +static int +zfs_add_options(zfs_handle_t *zhp, char *options, int len) +{ + int error = 0; + + error = zfs_add_option(zhp, options, len, + ZFS_PROP_ATIME, MNTOPT_ATIME, MNTOPT_NOATIME); + error = error ? error : zfs_add_option(zhp, options, len, + ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES); + error = error ? error : zfs_add_option(zhp, options, len, + ZFS_PROP_EXEC, MNTOPT_EXEC, MNTOPT_NOEXEC); + error = error ? error : zfs_add_option(zhp, options, 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); + + return (error); +} + /* * Mount the given filesystem. */ @@ -325,12 +371,16 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; - int rc; + int remount = 0, rc; - if (options == NULL) + if (options == NULL) { (void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts)); - else + } else { (void) strlcpy(mntopts, options, sizeof (mntopts)); + } + + if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) + remount = 1; /* * If the pool is imported read-only then all mounts must be read-only @@ -339,6 +389,22 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); /* + * Append default mount options which apply to the mount point. + * This is done because under Linux (unlike Solaris) multiple mount + * points may reference a single super block. This means that just + * given a super block there is no back reference to update the per + * mount point options. + */ + rc = zfs_add_options(zhp, mntopts, sizeof (mntopts)); + if (rc) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "default options unavailable")); + return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, + dgettext(TEXT_DOMAIN, "cannot mount '%s'"), + mountpoint)); + } + + /* * Append zfsutil option so the mount helper allow the mount */ strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); @@ -361,8 +427,7 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if 'remount' is specified. */ - if (strstr(mntopts, MNTOPT_REMOUNT) == NULL && - !dir_is_empty(mountpoint)) { + if (!remount && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, @@ -403,6 +468,10 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) zhp->zfs_name)); } + /* remove the mounted entry before re-adding on remount */ + if (remount) + libzfs_mnttab_remove(hdl, zhp->zfs_name); + /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 0245bb16a..db27fd5c1 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -63,6 +63,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ |