Add ZAP shrinking support (review fixes)
Sponsored-by: iXsystems, Inc. Sponsored-by: Klara, Inc. Signed-off-by: Alexander Stetsenko <alex.stetsenko@klarasystems.com>
This commit is contained in:
parent
94c323bf39
commit
ee467c3eda
|
@ -631,22 +631,14 @@ zap_set_idx_range_to_blk(zap_t *zap, uint64_t idx, uint64_t nptrs, uint64_t blk,
|
||||||
#define ZAP_PREFIX_HASH(pref, pref_len) ((pref) << (64 - (pref_len)))
|
#define ZAP_PREFIX_HASH(pref, pref_len) ((pref) << (64 - (pref_len)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This checks whether a leaf with prefix/len exists and returns its blkid.
|
* Each leaf has single range of entries (block pointers) in the ZAP ptrtbl.
|
||||||
*
|
* If two leaves are siblings, their ranges are adjecent and contain the same
|
||||||
* The prefix/len correspond to a distinct range of entries in ptrtbl.
|
* number of entries. In order to find out if a leaf has a sibling, we need to
|
||||||
* If all range entries contain the same value (blkid) and only the range
|
* check the range corresponding to the sibling leaf. There is no need to check
|
||||||
* entries contain this blkid, then there exists a leaf with this blkid and
|
* all entries in the range, we only need to check the frist and the last one.
|
||||||
* given prefix/len.
|
|
||||||
*
|
|
||||||
* We don't have to check all entries in the range. Instead, we can check only
|
|
||||||
* the first and the last one. If both contain the same blkid, then we check
|
|
||||||
* the neighbor entries (entry before the first and entry after the last).
|
|
||||||
*
|
|
||||||
* A leaf with prefix/len exists if
|
|
||||||
* (first == last AND before-first != blkid AND after-last != blkid).
|
|
||||||
*/
|
*/
|
||||||
static uint64_t
|
static uint64_t
|
||||||
zap_check_leaf_by_ptrtbl(zap_t *zap, uint64_t prefix, uint64_t prefix_len)
|
check_sibling_ptrtbl_range(zap_t *zap, uint64_t prefix, uint64_t prefix_len)
|
||||||
{
|
{
|
||||||
ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
|
ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
|
||||||
|
|
||||||
|
@ -654,7 +646,6 @@ zap_check_leaf_by_ptrtbl(zap_t *zap, uint64_t prefix, uint64_t prefix_len)
|
||||||
uint64_t idx = ZAP_HASH_IDX(h, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
|
uint64_t idx = ZAP_HASH_IDX(h, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
|
||||||
uint64_t pref_diff = zap_f_phys(zap)->zap_ptrtbl.zt_shift - prefix_len;
|
uint64_t pref_diff = zap_f_phys(zap)->zap_ptrtbl.zt_shift - prefix_len;
|
||||||
uint64_t nptrs = (1 << pref_diff);
|
uint64_t nptrs = (1 << pref_diff);
|
||||||
int slbit = prefix & 1;
|
|
||||||
uint64_t first;
|
uint64_t first;
|
||||||
uint64_t last;
|
uint64_t last;
|
||||||
|
|
||||||
|
@ -666,45 +657,8 @@ zap_check_leaf_by_ptrtbl(zap_t *zap, uint64_t prefix, uint64_t prefix_len)
|
||||||
if (zap_idx_to_blk(zap, idx + nptrs - 1, &last) != 0)
|
if (zap_idx_to_blk(zap, idx + nptrs - 1, &last) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Check the last possible sibling entry. If the first entry and the
|
|
||||||
* last one differs it is not a sibling.
|
|
||||||
*/
|
|
||||||
if (first != last)
|
if (first != last)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
|
||||||
* If there are entries after the last one, check it as well.
|
|
||||||
* It should not be the same as the last entry, otherwise it is
|
|
||||||
* not a sibling.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Check the entry before the first one.
|
|
||||||
*/
|
|
||||||
if (slbit == 0 && idx > 0) {
|
|
||||||
uint64_t before_first;
|
|
||||||
|
|
||||||
if (zap_idx_to_blk(zap, idx - 1, &before_first) != 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if (before_first == first)
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check the entry after the last one.
|
|
||||||
*/
|
|
||||||
if (slbit == 1 &&
|
|
||||||
idx + nptrs < (1UL << zap_f_phys(zap)->zap_ptrtbl.zt_shift)) {
|
|
||||||
uint64_t after_last;
|
|
||||||
|
|
||||||
if (zap_idx_to_blk(zap, idx + nptrs, &after_last) != 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if (last == after_last)
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (first);
|
return (first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1521,7 +1475,8 @@ zap_trunc(zap_t *zap)
|
||||||
|
|
||||||
for (uint64_t idx = 0; idx < nentries; idx++) {
|
for (uint64_t idx = 0; idx < nentries; idx++) {
|
||||||
uint64_t blk;
|
uint64_t blk;
|
||||||
zap_idx_to_blk(zap, idx, &blk);
|
if (zap_idx_to_blk(zap, idx, &blk) != 0)
|
||||||
|
return;
|
||||||
if (blk > lastblk)
|
if (blk > lastblk)
|
||||||
lastblk = blk;
|
lastblk = blk;
|
||||||
}
|
}
|
||||||
|
@ -1564,8 +1519,7 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
|
||||||
uint64_t hash = zn->zn_hash;
|
uint64_t hash = zn->zn_hash;
|
||||||
uint64_t prefix = zap_leaf_phys(l)->l_hdr.lh_prefix;
|
uint64_t prefix = zap_leaf_phys(l)->l_hdr.lh_prefix;
|
||||||
uint64_t prefix_len = zap_leaf_phys(l)->l_hdr.lh_prefix_len;
|
uint64_t prefix_len = zap_leaf_phys(l)->l_hdr.lh_prefix_len;
|
||||||
boolean_t trunc = 0;
|
boolean_t trunc = B_FALSE;
|
||||||
int nshrunk = 0;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
|
ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
|
||||||
|
@ -1586,14 +1540,12 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
|
||||||
uint64_t sl_hash = ZAP_PREFIX_HASH(sl_prefix, prefix_len);
|
uint64_t sl_hash = ZAP_PREFIX_HASH(sl_prefix, prefix_len);
|
||||||
int slbit = prefix & 1;
|
int slbit = prefix & 1;
|
||||||
|
|
||||||
ASSERT3U(zt_shift, ==, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
|
ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
|
||||||
ASSERT3S(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if there is a sibling by reading prttbl ptrs.
|
* Check if there is a sibling by reading ptrtbl ptrs.
|
||||||
*/
|
*/
|
||||||
if (zap_check_leaf_by_ptrtbl(zap, sl_prefix, prefix_len) == 0)
|
if (check_sibling_ptrtbl_range(zap, sl_prefix, prefix_len) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1645,6 +1597,7 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
|
||||||
rw_enter(&zap->zap_rwlock, RW_WRITER);
|
rw_enter(&zap->zap_rwlock, RW_WRITER);
|
||||||
dmu_buf_will_dirty(zap->zap_dbuf, tx);
|
dmu_buf_will_dirty(zap->zap_dbuf, tx);
|
||||||
|
|
||||||
|
zt_shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift;
|
||||||
writer = B_TRUE;
|
writer = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1719,8 +1672,6 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
|
||||||
|
|
||||||
prefix = zap_leaf_phys(l)->l_hdr.lh_prefix;
|
prefix = zap_leaf_phys(l)->l_hdr.lh_prefix;
|
||||||
prefix_len = zap_leaf_phys(l)->l_hdr.lh_prefix_len;
|
prefix_len = zap_leaf_phys(l)->l_hdr.lh_prefix_len;
|
||||||
|
|
||||||
nshrunk++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trunc)
|
if (trunc)
|
||||||
|
|
Loading…
Reference in New Issue