aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2024-05-10 15:35:20 -0400
committerBrian Behlendorf <[email protected]>2024-05-29 08:54:19 -0700
commitfa4b1a404e12d3b883c86d8ea13d8c1203addce0 (patch)
treeee35cd10ae2342fc76cd87db9bda070f0fe99db1
parent4c484d66b7f8fe595fdb89d91797e3e8fa686dab (diff)
ZAP: Fix leaf references on zap_expand_leaf() errors
Depending on kind of error zap_expand_leaf() may return with or without valid leaf reference held. Make sure it returns NULL if due to error it has no leaf to return. Make its callers to check the returned leaf pointer, and release the leaf if it is not NULL. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes #12366 Closes #16159
-rw-r--r--module/zfs/zap.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/module/zfs/zap.c b/module/zfs/zap.c
index da86defb4..e8e02bf0c 100644
--- a/module/zfs/zap.c
+++ b/module/zfs/zap.c
@@ -635,6 +635,7 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l,
uint64_t object = zap->zap_object;
zap_put_leaf(l);
+ *lp = l = NULL;
zap_unlockdir(zap, tag);
err = zap_lockdir(os, object, tx, RW_WRITER,
FALSE, FALSE, tag, &zn->zn_zap);
@@ -844,21 +845,17 @@ retry:
} else if (err == EAGAIN) {
err = zap_expand_leaf(zn, l, tag, tx, &l);
zap = zn->zn_zap; /* zap_expand_leaf() may change zap */
- if (err == 0) {
+ if (err == 0)
goto retry;
- } else if (err == ENOSPC) {
- /*
- * If we failed to expand the leaf, then bailout
- * as there is no point trying
- * zap_put_leaf_maybe_grow_ptrtbl().
- */
- return (err);
- }
}
out:
- if (zap != NULL)
- zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
+ if (l != NULL) {
+ if (err == ENOSPC)
+ zap_put_leaf(l);
+ else
+ zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
+ }
return (err);
}
@@ -915,8 +912,12 @@ retry:
goto retry;
}
- if (zap != NULL)
- zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
+ if (l != NULL) {
+ if (err == ENOSPC)
+ zap_put_leaf(l);
+ else
+ zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
+ }
return (err);
}