Skip to content

Commit 059e68a

Browse files
committed
try long hold approach
1 parent 4de9f5a commit 059e68a

File tree

4 files changed

+34
-19
lines changed

4 files changed

+34
-19
lines changed

include/sys/dsl_dir.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,10 @@ struct dsl_dir {
120120
dsl_deadlist_t dd_livelist;
121121
bplist_t dd_pending_frees;
122122
bplist_t dd_pending_allocs;
123+
123124
kmutex_t dd_activity_lock;
124125
kcondvar_t dd_activity_cv;
126+
boolean_t dd_activity_cancelled;
125127

126128
/* protected by dd_lock; keep at end of struct for better locality */
127129
char dd_myname[ZFS_MAX_DATASET_NAME_LEN];
@@ -194,7 +196,7 @@ boolean_t dsl_dir_is_zapified(dsl_dir_t *dd);
194196
void dsl_dir_livelist_open(dsl_dir_t *dd, uint64_t obj);
195197
void dsl_dir_livelist_close(dsl_dir_t *dd);
196198
void dsl_dir_remove_livelist(dsl_dir_t *dd, dmu_tx_t *tx, boolean_t total);
197-
int dsl_dir_wait(dsl_dir_t *dd, zfs_wait_activity_t activity,
199+
int dsl_dir_wait(dsl_dir_t *dd, dsl_dataset_t *ds, zfs_wait_activity_t activity,
198200
boolean_t *waited);
199201

200202
/* internal reserved dir name */

module/os/linux/zfs/zfs_vfsops.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <sys/zfs_fuid.h>
5555
#include <sys/sunddi.h>
5656
#include <sys/dmu_objset.h>
57+
#include <sys/dsl_dir.h>
5758
#include <sys/spa_boot.h>
5859
#include <sys/objlist.h>
5960
#include <sys/zpl.h>
@@ -1319,6 +1320,8 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
13191320
"num_entries in unlinked set: %llu",
13201321
zs.zs_num_entries);
13211322
zfs_unlinked_drain(zfsvfs);
1323+
dsl_dir_t *dd = zfsvfs->z_os->os_dsl_dataset->ds_dir;
1324+
dd->dd_activity_cancelled = B_FALSE;
13221325
}
13231326

13241327
/*
@@ -1869,6 +1872,9 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
18691872
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
18701873
}
18711874
dmu_objset_evict_dbufs(zfsvfs->z_os);
1875+
dsl_dir_t *dd = os->os_dsl_dataset->ds_dir;
1876+
dd->dd_activity_cancelled = B_TRUE;
1877+
cv_broadcast(&dd->dd_activity_cv);
18721878

18731879
return (0);
18741880
}
@@ -2256,6 +2262,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
22562262
if (err != 0)
22572263
goto bail;
22582264

2265+
ds->ds_dir->dd_activity_cancelled = B_FALSE;
22592266
VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
22602267

22612268
zfs_set_fuid_feature(zfsvfs);

module/zfs/dsl_dir.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ dsl_dir_evict_async(void *dbu)
160160
dsl_dir_livelist_close(dd);
161161

162162
dsl_prop_fini(dd);
163+
cv_destroy(&dd->dd_activity_cv);
164+
mutex_destroy(&dd->dd_activity_lock);
163165
mutex_destroy(&dd->dd_lock);
164166
kmem_free(dd, sizeof (dsl_dir_t));
165167
}
@@ -314,6 +316,8 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
314316
if (dsl_deadlist_is_open(&dd->dd_livelist))
315317
dsl_dir_livelist_close(dd);
316318
dsl_prop_fini(dd);
319+
cv_destroy(&dd->dd_activity_cv);
320+
mutex_destroy(&dd->dd_activity_lock);
317321
mutex_destroy(&dd->dd_lock);
318322
kmem_free(dd, sizeof (dsl_dir_t));
319323
dmu_buf_rele(dbuf, tag);
@@ -2285,41 +2289,31 @@ dsl_dir_remove_livelist(dsl_dir_t *dd, dmu_tx_t *tx, boolean_t total)
22852289
}
22862290

22872291
static int
2288-
dsl_dir_activity_in_progress(dsl_dir_t *dd, zfs_wait_activity_t activity,
2289-
boolean_t *in_progress)
2292+
dsl_dir_activity_in_progress(dsl_dir_t *dd, dsl_dataset_t *ds,
2293+
zfs_wait_activity_t activity, boolean_t *in_progress)
22902294
{
22912295
int error = 0;
2292-
zfs_dbgmsg("progress %px %d", dd, activity);
22932296

22942297
ASSERT(MUTEX_HELD(&dd->dd_activity_lock));
22952298

22962299
switch (activity) {
22972300
case ZFS_WAIT_DELETEQ: {
2298-
dsl_dataset_t *ds;
2299-
error = dsl_dataset_hold_obj(dd->dd_pool,
2300-
dsl_dir_phys(dd)->dd_head_dataset_obj, FTAG, &ds);
2301-
if (error != 0)
2302-
break;
23032301
objset_t *os;
23042302
error = dmu_objset_from_ds(ds, &os);
23052303
if (error != 0)
23062304
break;
23072305

23082306
uint64_t count, unlinked_obj;
2309-
zfs_dbgmsg("os %px", os);
23102307
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
23112308
&unlinked_obj);
23122309
if (error != 0) {
23132310
dsl_dataset_rele(ds, FTAG);
23142311
break;
23152312
}
2316-
zfs_dbgmsg("obj %ld", unlinked_obj);
23172313
error = zap_count(os, unlinked_obj, &count);
23182314

23192315
if (error == 0)
23202316
*in_progress = (count != 0);
2321-
2322-
dsl_dataset_rele(ds, FTAG);
23232317
break;
23242318
}
23252319
default:
@@ -2330,22 +2324,22 @@ dsl_dir_activity_in_progress(dsl_dir_t *dd, zfs_wait_activity_t activity,
23302324
}
23312325

23322326
int
2333-
dsl_dir_wait(dsl_dir_t *dd, zfs_wait_activity_t activity, boolean_t *waited)
2327+
dsl_dir_wait(dsl_dir_t *dd, dsl_dataset_t *ds, zfs_wait_activity_t activity,
2328+
boolean_t *waited)
23342329
{
23352330
int error = 0;
23362331
boolean_t in_progress;
2337-
zfs_dbgmsg("waiting %px %d", dd, activity);
23382332
mutex_enter(&dd->dd_activity_lock);
23392333
for (;;) {
2340-
error = dsl_dir_activity_in_progress(dd, activity,
2334+
error = dsl_dir_activity_in_progress(dd, ds, activity,
23412335
&in_progress);
23422336
if (error != 0 || !in_progress)
23432337
break;
23442338

23452339
*waited = B_TRUE;
23462340

23472341
if (cv_wait_sig(&dd->dd_activity_cv, &dd->dd_activity_lock) ==
2348-
0) {
2342+
0 || dd->dd_activity_cancelled) {
23492343
error = EINTR;
23502344
break;
23512345
}

module/zfs/zfs_ioctl.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,6 +4114,7 @@ zfs_ioc_wait_fs(const char *name, nvlist_t *innvl, nvlist_t *outnvl)
41144114
int error;
41154115
dsl_pool_t *dp;
41164116
dsl_dir_t *dd;
4117+
dsl_dataset_t *ds;
41174118

41184119
if (nvlist_lookup_int32(innvl, ZFS_WAIT_ACTIVITY, &activity) != 0)
41194120
return (EINVAL);
@@ -4125,10 +4126,21 @@ zfs_ioc_wait_fs(const char *name, nvlist_t *innvl, nvlist_t *outnvl)
41254126
return (error);
41264127
}
41274128

4128-
error = dsl_dir_wait(dd, activity, &waited);
4129-
dsl_dir_rele(dd, FTAG);
4129+
if ((error = dsl_dataset_hold_obj(dd->dd_pool,
4130+
dsl_dir_phys(dd)->dd_head_dataset_obj, FTAG, &ds)) != 0) {
4131+
dsl_pool_rele(dp, FTAG);
4132+
dsl_dir_rele(dd, FTAG);
4133+
return (error);
4134+
}
4135+
dsl_dataset_long_hold(ds, FTAG);
41304136
dsl_pool_rele(dp, FTAG);
41314137

4138+
error = dsl_dir_wait(dd, ds, activity, &waited);
4139+
4140+
dsl_dataset_long_rele(ds, FTAG);
4141+
dsl_dataset_rele(ds, FTAG);
4142+
dsl_dir_rele(dd, FTAG);
4143+
41324144
if (error == 0)
41334145
fnvlist_add_boolean_value(outnvl, ZFS_WAIT_WAITED, waited);
41344146

0 commit comments

Comments
 (0)