diff options
author | Brian Behlendorf <[email protected]> | 2015-04-24 16:21:13 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-08-31 13:54:39 -0700 |
commit | 278bee9319ba5947b995673d2c76e0333f2d33d4 (patch) | |
tree | a621142a2d5314b460cbf1a8bc6b6092f7a46424 /module/zfs/zpl_inode.c | |
parent | b23975cbe0f249671c131b0d6e4ae1bb10594440 (diff) |
Linux 3.18 compat: Snapshot auto-mounting
Re-factor the .zfs/snapshot auto-mouting code to take in to account
changes made to the upstream kernels. And to lay the groundwork for
enabling access to .zfs snapshots via NFS clients. This patch makes
the following core improvements.
* All actively auto-mounted snapshots are now tracked in two global
trees which are indexed by snapshot name and objset id respectively.
This allows for fast lookups of any auto-mounted snapshot regardless
without needing access to the parent dataset.
* Snapshot entries are added to the tree in zfsctl_snapshot_mount().
However, they are now removed from the tree in the context of the
unmount process. This eliminates the need complicated error logic
in zfsctl_snapshot_unmount() to handle unmount failures.
* References are now taken on the snapshot entries in the tree to
ensure they always remain valid while a task is outstanding.
* The MNT_SHRINKABLE flag is set on the snapshot vfsmount_t right
after the auto-mount succeeds. This allows to kernel to unmount
idle auto-mounted snapshots if needed removing the need for the
zfsctl_unmount_snapshots() function.
* Snapshots in active use will not be automatically unmounted. As
long as at least one dentry is revalidated every zfs_expire_snapshot/2
seconds the auto-unmount expiration timer will be extended.
* Commit torvalds/linux@bafc9b7 caused snapshots auto-mounted by ZFS
to be immediately unmounted when the dentry was revalidated. This
was a consequence of ZFS invaliding all snapdir dentries to ensure that
negative dentries didn't mask new snapshots. This patch modifies the
behavior such that only negative dentries are invalidated. This solves
the issue and may result in a performance improvement.
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3589
Closes #3344
Closes #3295
Closes #3257
Closes #3243
Closes #3030
Closes #2841
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. |