]> granicus.if.org Git - zfs/commitdiff
Allow NFS activity to defer snapshot unmounts
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Sep 2015 20:00:28 +0000 (13:00 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 25 Sep 2015 19:45:38 +0000 (12:45 -0700)
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 <behlendorf1@llnl.gov>
Issue #3794

module/zfs/zfs_ctldir.c

index e54b0c16c16cddd5f52d777c45d099f49adbf2e4..b70eb66239489751383bd32b3f5aa852785d2290 100644 (file)
@@ -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 {