Print this page
NEX-3562 filename normalization doesn't work for removes (sync with upstream)
NEX-8972 Async-delete side-effect that may cause unmount EBUSY
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-8466 Failed to do 'pkg update' because of beadm failed to create BE, because of EBUSY in umount
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-5108 make deletes interruptible on pool export
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-5036 case-insensitive matching is not working on casesensitivity=mixed, normalization=none FS
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3562 filename normalization doesn't work for removes
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-4290 'insensitive' case sensitivity is broken
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3762 Appliance crashes with a NULL pointer dereference during a zpool export when a zfs_vn_rele_taskq thread attempts to check a bogus rwlock from rw_write_held
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
6328 Fix cstyle errors in zfs codebase (fix studio)
6328 Fix cstyle errors in zfs codebase
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Jorgen Lundman <lundman@lundman.net>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-3329 libnsl: set_up_connection() over TCP does not adhere the specified timeout
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-3521 CLONE - Port NEX-3209 normalization=formD and casesensitivity=mixed behaves improperly, squashing case
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-2965 4.0.3-FP2: deferred deletes causing RSF import failure during fail-over of service
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
SUP-780 zfs with casesensitivity=mixed and Unicode normalization doesn't normalize properly/fully

@@ -50,10 +50,11 @@
 #include <sys/zfs_acl.h>
 #include <sys/fs/zfs.h>
 #include "fs/fs_subr.h"
 #include <sys/zap.h>
 #include <sys/dmu.h>
+#include <sys/dmu_objset.h>
 #include <sys/atomic.h>
 #include <sys/zfs_ctldir.h>
 #include <sys/zfs_fuid.h>
 #include <sys/sa.h>
 #include <sys/zfs_sa.h>

@@ -478,24 +479,27 @@
 
 /*
  * Clean up any znodes that had no links when we either crashed or
  * (force) umounted the file system.
  */
-void
-zfs_unlinked_drain(zfsvfs_t *zfsvfs)
+static void
+zfs_unlinked_drain_impl(zfsvfs_t *zfsvfs)
 {
         zap_cursor_t    zc;
         zap_attribute_t zap;
         dmu_object_info_t doi;
         znode_t         *zp;
         int             error;
 
+        ASSERT(zfsvfs->z_drain_state != ZFS_DRAIN_SHUTDOWN);
         /*
          * Interate over the contents of the unlinked set.
          */
         for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
-            zap_cursor_retrieve(&zc, &zap) == 0;
+            zap_cursor_retrieve(&zc, &zap) == 0 &&
+            /* Only checking for a shutdown request, so no locking reqd. */
+            zfsvfs->z_drain_state == ZFS_DRAIN_RUNNING;
             zap_cursor_advance(&zc)) {
 
                 /*
                  * See what kind of object we have in list
                  */

@@ -522,14 +526,62 @@
                 if (error != 0)
                         continue;
 
                 zp->z_unlinked = B_TRUE;
                 VN_RELE(ZTOV(zp));
+
+                ASSERT(!zfsvfs->z_unmounted);
         }
         zap_cursor_fini(&zc);
+
+        mutex_enter(&zfsvfs->z_drain_lock);
+        zfsvfs->z_drain_state = ZFS_DRAIN_SHUTDOWN;
+        cv_broadcast(&zfsvfs->z_drain_cv);
+        mutex_exit(&zfsvfs->z_drain_lock);
 }
 
+/*
+ * Setup required hold. After that tries to dispatch
+ * async unlinked drain logic. Otherwise executes
+ * the logic synchronously.
+ */
+void
+zfs_unlinked_drain(zfsvfs_t *zfsvfs)
+{
+        ASSERT(!zfsvfs->z_unmounted);
+
+        mutex_enter(&zfsvfs->z_drain_lock);
+        ASSERT(zfsvfs->z_drain_state == ZFS_DRAIN_SHUTDOWN);
+        zfsvfs->z_drain_state = ZFS_DRAIN_RUNNING;
+        mutex_exit(&zfsvfs->z_drain_lock);
+
+        if (taskq_dispatch(dsl_pool_vnrele_taskq(
+            spa_get_dsl(zfsvfs->z_os->os_spa)),
+            (void (*)(void *))zfs_unlinked_drain_impl, zfsvfs,
+            TQ_NOSLEEP) == NULL) {
+                cmn_err(CE_WARN, "async zfs_unlinked_drain dispatch failed");
+                zfs_unlinked_drain_impl(zfsvfs);
+        }
+}
+
+/*
+ * Stops an asynchronous zfs_unlinked_drain. This must be called prior to
+ * destroying the zfsvfs_t, as the drain doesn't hold the z_teardown_lock.
+ */
+void
+zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs)
+{
+        ASSERT(!zfsvfs->z_unmounted);
+
+        mutex_enter(&zfsvfs->z_drain_lock);
+        while (zfsvfs->z_drain_state != ZFS_DRAIN_SHUTDOWN) {
+                zfsvfs->z_drain_state = ZFS_DRAIN_SHUTDOWN_REQ;
+                cv_wait(&zfsvfs->z_drain_cv, &zfsvfs->z_drain_lock);
+        }
+        mutex_exit(&zfsvfs->z_drain_lock);
+}
+
 /*
  * Delete the entire contents of a directory.  Return a count
  * of the number of entries that could not be deleted. If we encounter
  * an error, return a count of at least one so that the directory stays
  * in the unlinked set.