diff options
Diffstat (limited to 'module/zfs/zpl_inode.c')
-rw-r--r-- | module/zfs/zpl_inode.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index e81a3cd04..6475c72d7 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -24,6 +24,7 @@ */ +#include <sys/zfs_ctldir.h> #include <sys/zfs_vfsops.h> #include <sys/zfs_vnops.h> #include <sys/zfs_znode.h> @@ -240,21 +241,9 @@ zpl_rmdir(struct inode * dir, struct dentry *dentry) static int zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { - boolean_t issnap = ITOZSB(dentry->d_inode)->z_issnap; int error; fstrans_cookie_t cookie; - /* - * Ensure MNT_SHRINKABLE is set on snapshots to ensure they are - * unmounted automatically with the parent file system. This - * is done on the first getattr because it's not easy to get the - * vfsmount structure at mount time. This call path is explicitly - * marked unlikely to avoid any performance impact. FWIW, ext4 - * resorts to a similar trick for sysadmin convenience. - */ - if (unlikely(issnap && !(mnt->mnt_flags & MNT_SHRINKABLE))) - mnt->mnt_flags |= MNT_SHRINKABLE; - cookie = spl_fstrans_mark(); error = -zfs_getattr_fast(dentry->d_inode, stat); spl_fstrans_unmark(cookie); @@ -504,6 +493,19 @@ zpl_revalidate(struct dentry *dentry, unsigned int flags) return (-ECHILD); /* + * Automounted snapshots rely on periodic dentry revalidation + * to defer snapshots from being automatically unmounted. + */ + if (zsb->z_issnap) { + if (time_after(jiffies, zsb->z_snap_defer_time + + MAX(zfs_expire_snapshot * HZ / 2, HZ))) { + zsb->z_snap_defer_time = jiffies; + zfsctl_snapshot_unmount_delay( + dmu_objset_id(zsb->z_os), zfs_expire_snapshot); + } + } + + /* * After a rollback negative dentries created before the rollback * time must be invalidated. Otherwise they can obscure files which * are only present in the rolled back dataset. |