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.