Linux 3.7 compat, schedule_delayed_work()
[zfs.git] / module / zfs / zfs_ctldir.c
index d139b86..a667340 100644 (file)
  */
 int zfs_expire_snapshot = ZFSCTL_EXPIRE_SNAPSHOT;
 
+/*
+ * Dedicated task queue for unmounting snapshots.
+ */
+static taskq_t *zfs_expire_taskq;
+
 static zfs_snapentry_t *
 zfsctl_sep_alloc(void)
 {
@@ -112,16 +117,15 @@ zfsctl_sep_free(zfs_snapentry_t *sep)
 static void
 zfsctl_expire_snapshot(void *data)
 {
-       zfs_snapentry_t *sep;
-       zfs_sb_t *zsb;
+       zfs_snapentry_t *sep = (zfs_snapentry_t *)data;
+       zfs_sb_t *zsb = ITOZSB(sep->se_inode);
        int error;
 
-       sep = spl_get_work_data(data, zfs_snapentry_t, se_work.work);
-       zsb = ITOZSB(sep->se_inode);
-
        error = zfsctl_unmount_snapshot(zsb, sep->se_name, MNT_EXPIRE);
        if (error == EBUSY)
-               schedule_delayed_work(&sep->se_work, zfs_expire_snapshot * HZ);
+               sep->se_taskqid = taskq_dispatch_delay(zfs_expire_taskq,
+                   zfsctl_expire_snapshot, sep, TQ_SLEEP,
+                   ddi_get_lbolt() + zfs_expire_snapshot * HZ);
 }
 
 int
@@ -661,7 +665,7 @@ zfsctl_snapdir_inactive(struct inode *ip)
 
                if (sep->se_inode == ip) {
                        avl_remove(&zsb->z_ctldir_snaps, sep);
-                       cancel_delayed_work_sync(&sep->se_work);
+                       taskq_cancel_id(zfs_expire_taskq, sep->se_taskqid);
                        zfsctl_sep_free(sep);
                        break;
                }
@@ -708,7 +712,8 @@ __zfsctl_unmount_snapshot(zfs_snapentry_t *sep, int flags)
         * to prevent zfsctl_expire_snapshot() from attempting a unmount.
         */
        if ((error == 0) && !(flags & MNT_EXPIRE))
-               cancel_delayed_work(&sep->se_work);
+               taskq_cancel_id(zfs_expire_taskq, sep->se_taskqid);
+
 
        return (error);
 }
@@ -837,7 +842,7 @@ zfsctl_mount_snapshot(struct path *path, int flags)
        sep = avl_find(&zsb->z_ctldir_snaps, &search, NULL);
        if (sep) {
                avl_remove(&zsb->z_ctldir_snaps, sep);
-               cancel_delayed_work_sync(&sep->se_work);
+               taskq_cancel_id(zfs_expire_taskq, sep->se_taskqid);
                zfsctl_sep_free(sep);
        }
 
@@ -847,8 +852,9 @@ zfsctl_mount_snapshot(struct path *path, int flags)
        sep->se_inode = ip;
        avl_add(&zsb->z_ctldir_snaps, sep);
 
-        spl_init_delayed_work(&sep->se_work, zfsctl_expire_snapshot, sep);
-       schedule_delayed_work(&sep->se_work, zfs_expire_snapshot * HZ);
+       sep->se_taskqid = taskq_dispatch_delay(zfs_expire_taskq,
+           zfsctl_expire_snapshot, sep, TQ_SLEEP,
+           ddi_get_lbolt() + zfs_expire_snapshot * HZ);
 
        mutex_exit(&zsb->z_ctldir_lock);
 error:
@@ -977,6 +983,8 @@ zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
 void
 zfsctl_init(void)
 {
+       zfs_expire_taskq = taskq_create("z_unmount", 1, maxclsyspri,
+           1, 8, TASKQ_PREPOPULATE);
 }
 
 /*
@@ -986,6 +994,7 @@ zfsctl_init(void)
 void
 zfsctl_fini(void)
 {
+       taskq_destroy(zfs_expire_taskq);
 }
 
 module_param(zfs_expire_snapshot, int, 0644);