diff options
Diffstat (limited to 'module/zfs/zpl_super.c')
-rw-r--r-- | module/zfs/zpl_super.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index 0e6e9360f..98d0a0312 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -26,6 +26,7 @@ #include <sys/zfs_vfsops.h> #include <sys/zfs_vnops.h> #include <sys/zfs_znode.h> +#include <sys/zfs_ctldir.h> #include <sys/zpl.h> @@ -139,6 +140,20 @@ zpl_remount_fs(struct super_block *sb, int *flags, char *data) return (error); } +static void +zpl_umount_begin(struct super_block *sb) +{ + zfs_sb_t *zsb = sb->s_fs_info; + int count; + + /* + * Best effort to unmount snapshots in .zfs/snapshot/. Normally this + * isn't required because snapshots have the MNT_SHRINKABLE flag set. + */ + if (zsb->z_ctldir) + (void) zfsctl_unmount_snapshots(zsb, MNT_FORCE, &count); +} + /* * The Linux VFS automatically handles the following flags: * MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, MNT_NOATIME, MNT_READONLY @@ -199,13 +214,7 @@ zpl_get_sb(struct file_system_type *fs_type, int flags, static void zpl_kill_sb(struct super_block *sb) { -#ifdef HAVE_SNAPSHOT - zfs_sb_t *zsb = sb->s_fs_info; - - if (zsb && dmu_objset_is_snapshot(zsb->z_os)) - zfs_snap_destroy(zsb); -#endif /* HAVE_SNAPSHOT */ - + zfs_preumount(sb); kill_anon_super(sb); } @@ -306,6 +315,7 @@ const struct super_operations zpl_super_operations = { .sync_fs = zpl_sync_fs, .statfs = zpl_statfs, .remount_fs = zpl_remount_fs, + .umount_begin = zpl_umount_begin, .show_options = zpl_show_options, .show_stats = NULL, #ifdef HAVE_NR_CACHED_OBJECTS |