Tear down and flush the mmap region
[zfs.git] / module / zfs / zfs_vfsops.c
index 1e8e6af..2575638 100644 (file)
@@ -1088,10 +1088,16 @@ zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting)
                 * for non-snapshots.
                 */
                shrink_dcache_sb(zsb->z_parent->z_sb);
-               invalidate_inodes(zsb->z_parent->z_sb);
+               (void) spl_invalidate_inodes(zsb->z_parent->z_sb, 0);
        }
 
        /*
+        * Drain the iput_taskq to ensure all active references to the
+        * zfs_sb_t have been handled only then can it be safely destroyed.
+        */
+       taskq_wait(dsl_pool_iput_taskq(dmu_objset_pool(zsb->z_os)));
+
+       /*
         * Close the zil. NB: Can't close the zil while zfs_inactive
         * threads are blocked as zil_close can call zfs_inactive.
         */
@@ -1206,9 +1212,7 @@ zfs_domount(struct super_block *sb, void *data, int silent)
        /* Set callback operations for the file system. */
        sb->s_op = &zpl_super_operations;
        sb->s_xattr = zpl_xattr_handlers;
-#ifdef HAVE_EXPORTS
-        sb->s_export_op = &zpl_export_operations;
-#endif /* HAVE_EXPORTS */
+       sb->s_export_op = &zpl_export_operations;
 
        /* Set features for file system. */
        zfs_set_fuid_feature(zsb);
@@ -1292,6 +1296,46 @@ zfs_umount(struct super_block *sb)
 EXPORT_SYMBOL(zfs_umount);
 
 int
+zfs_remount(struct super_block *sb, int *flags, char *data)
+{
+       zfs_sb_t *zsb = sb->s_fs_info;
+       boolean_t readonly = B_FALSE;
+       boolean_t setuid = B_TRUE;
+       boolean_t exec = B_TRUE;
+       boolean_t devices = B_TRUE;
+       boolean_t atime = B_TRUE;
+
+       if (*flags & MS_RDONLY)
+               readonly = B_TRUE;
+
+       if (*flags & MS_NOSUID) {
+               devices = B_FALSE;
+               setuid = B_FALSE;
+       } else {
+               if (*flags & MS_NODEV)
+                       devices = B_FALSE;
+       }
+
+       if (*flags & MS_NOEXEC)
+               exec = B_FALSE;
+
+       if (*flags & MS_NOATIME)
+               atime = B_FALSE;
+
+       /*
+        * Invoke our callbacks to set required flags.
+        */
+       readonly_changed_cb(zsb, readonly);
+       setuid_changed_cb(zsb, setuid);
+       exec_changed_cb(zsb, exec);
+       devices_changed_cb(zsb, devices);
+       atime_changed_cb(zsb, atime);
+
+       return (0);
+}
+EXPORT_SYMBOL(zfs_remount);
+
+int
 zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp)
 {
        zfs_sb_t        *zsb = VTOZSB(vfsp);