diff options
author | Brian Behlendorf <[email protected]> | 2015-09-23 13:00:28 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-09-25 12:45:38 -0700 |
commit | d4787d55ad65f517d8bdf12b73b296b27ca42e3a (patch) | |
tree | aa5613a27595db45adeb8ecef842b0918030fcf3 /module/zfs/zfs_ctldir.c | |
parent | 784a7fe5d9a0c02e96f3ae019a08ecebee2a7018 (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.c | 15 |
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 { |