Skip to content

Commit 38f73b6

Browse files
committed
Fix ENOSPC for extended quota
When unlinking multiple files from a pool at 100% capacity, it was possible for ENOSPC to be returned after the first few unlinks. This issue was fixed previously by PR #13172 but then this was again introduced by PR #13839. This is resolved using the existing mechanism of returning ERESTART when over quota as long as we know enough space will shortly be available after processing the pending deferred frees. Also, updated the existing testcase which reliably reproduced the issue without this patch. Reviewed-by: Dipak Ghosh <[email protected]> Signed-off-by: Akash B <[email protected]>
1 parent 2e2a46e commit 38f73b6

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

module/zfs/dsl_dir.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
2727
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
2828
* Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
29+
* Copyright (c) 2023 Hewlett Packard Enterprise Development LP.
2930
*/
3031

3132
#include <sys/dmu.h>
@@ -1358,6 +1359,10 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree,
13581359
ext_quota = 0;
13591360

13601361
if (used_on_disk >= quota) {
1362+
if (retval == ENOSPC && (used_on_disk - quota) <
1363+
dsl_pool_deferred_space(dd->dd_pool)) {
1364+
retval = SET_ERROR(ERESTART);
1365+
}
13611366
/* Quota exceeded */
13621367
mutex_exit(&dd->dd_lock);
13631368
DMU_TX_STAT_BUMP(dmu_tx_quota);
@@ -1366,8 +1371,6 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree,
13661371
if (est_inflight > 0 || used_on_disk < quota) {
13671372
retval = SET_ERROR(ERESTART);
13681373
} else {
1369-
ASSERT3U(used_on_disk, >=, quota);
1370-
13711374
if (retval == ENOSPC && (used_on_disk - quota) <
13721375
dsl_pool_deferred_space(dd->dd_pool)) {
13731376
retval = SET_ERROR(ERESTART);

tests/zfs-tests/tests/functional/no_space/enospc_rm.ksh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#
1818
# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
1919
# Copyright (c) 2022 by Lawrence Livermore National Security, LLC.
20+
# Copyright (c) 2023 Hewlett Packard Enterprise Development LP.
2021
#
2122

2223
. $STF_SUITE/include/libtest.shlib
@@ -51,11 +52,20 @@ log_must zfs create $TESTPOOL/$TESTFS
5152
log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
5253
log_must zfs set compression=off $TESTPOOL/$TESTFS
5354

54-
log_note "Writing files until ENOSPC."
55+
log_note "Writing Big(1G) files until ENOSPC."
5556
log_mustnot_expect "No space left on device" fio --name=test \
5657
--fallocate=none --rw=write --bs=1M --size=1G --numjobs=4 \
5758
--sync=1 --directory=$TESTDIR/ --group_reporting
5859

60+
log_must rm $TESTDIR/test.*
61+
log_must test -z "$(ls -A $TESTDIR)"
62+
sync_pool $TESTPOOL true
63+
64+
log_note "Writing small(10M) files until ENOSPC."
65+
log_mustnot_expect "No space left on device" fio --name=test \
66+
--fallocate=none --rw=write --bs=1M --size=10M --numjobs=200 \
67+
--sync=1 --directory=$TESTDIR/ --group_reporting
68+
5969
log_must rm $TESTDIR/test.*
6070
log_must test -z "$(ls -A $TESTDIR)"
6171

0 commit comments

Comments
 (0)