aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_ctldir.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2015-09-23 13:00:28 -0700
committerBrian Behlendorf <[email protected]>2015-09-25 12:45:38 -0700
commitd4787d55ad65f517d8bdf12b73b296b27ca42e3a (patch)
treeaa5613a27595db45adeb8ecef842b0918030fcf3 /module/zfs/zfs_ctldir.c
parent784a7fe5d9a0c02e96f3ae019a08ecebee2a7018 (diff)
Allow NFS activity to defer snapshot unmounts
Accessing a snapshot via NFS should cause an auto-unmount of that snapshot to be deferred until such as time as the snapshot is idle. This is analogous to the zpl_revalidate logic employed by locally mounted snapshots. Signed-off-by: Brian Behlendorf <[email protected]> Issue #3794
Diffstat (limited to 'module/zfs/zfs_ctldir.c')
-rw-r--r--module/zfs/zfs_ctldir.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c
index e54b0c16c..b70eb6623 100644
--- a/module/zfs/zfs_ctldir.c
+++ b/module/zfs/zfs_ctldir.c
@@ -1147,8 +1147,19 @@ zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid, zfs_sb_t **zsbp)
*/
mutex_enter(&zfs_snapshot_lock);
if ((se = zfsctl_snapshot_find_by_objsetid(objsetid)) != NULL) {
- *zsbp = ITOZSB(se->se_root_dentry->d_inode);
- ASSERT3U(dmu_objset_id((*zsbp)->z_os), ==, objsetid);
+ zfs_sb_t *zsb;
+
+ zsb = ITOZSB(se->se_root_dentry->d_inode);
+ ASSERT3U(dmu_objset_id(zsb->z_os), ==, objsetid);
+
+ 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(objsetid,
+ zfs_expire_snapshot);
+ }
+
+ *zsbp = zsb;
zfsctl_snapshot_rele(se);
error = SET_ERROR(0);
} else {