mirror of
https://github.com/versity/scoutfs.git
synced 2026-08-18 13:16:55 +00:00
Index free extents by order of length
Allocators store free extents in two items, one sorted by their blkno position and the other by their precise length. The length index makes it easy to search for precise extent lengths, but it makes it hard to search for a large extent within a given blkno region. Skipping in the blkno dimension has to be done for every precise length value. We don't need that level of precision. If we index the extents by a coarser order of the length then we have a fixed number of orders in which we have to skip in the blkno dimension when searching within a specific region. This changes the length item to be stored at the log(8) order of the length of the extents. This groups extents into orders that are close to the human-friendly base 10 orders of magnitude. With this change the order field in the key no longer stores the precise extent length. To preserve the length of the extent we need to use another field. The only 64bit field remaining is the first which is a higher comparision priority than the type. So we use the highest comparison priority zone field to differentiate the position and order indexes and can now use all three 64bit fields in the key. Finally, we have to be careful when constructing a key to use _next when searching for a large extent. Previously keys were relying on the magic property that building a key from an extent length of 0 ended up at the key value -0 = 0. That only worked because we never stored zero length extents. We now store zero length orders so we can't use the negative trick anymore. We explicitly treat 0 length extents carefully when building keys and we subtract the order from U64_MAX to store the orders from largest to smallest. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+14
-8
@@ -57,6 +57,15 @@ static int write_block(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the order of the length of a free extent, which we define as
|
||||
* floor(log_8_(len)): 0..7 = 0, 8..63 = 1, etc.
|
||||
*/
|
||||
static u64 free_extent_order(u64 len)
|
||||
{
|
||||
return (flsll(len | 1) - 1) / 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the single btree block that contains the blkno and len indexed
|
||||
* items to store the given extent, and update the root to point to it.
|
||||
@@ -72,19 +81,16 @@ static int write_alloc_root(int fd, __le64 fsid,
|
||||
root->total_len = cpu_to_le64(len);
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.sk_zone = SCOUTFS_FREE_EXTENT_ZONE;
|
||||
key.sk_type = SCOUTFS_FREE_EXTENT_BLKNO_TYPE;
|
||||
key.skii_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
|
||||
key.sk_zone = SCOUTFS_FREE_EXTENT_BLKNO_ZONE;
|
||||
key.skfb_end = cpu_to_le64(start + len - 1);
|
||||
key.skfb_len = cpu_to_le64(len);
|
||||
btree_append_item(bt, &key, NULL, 0);
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.sk_zone = SCOUTFS_FREE_EXTENT_ZONE;
|
||||
key.sk_type = SCOUTFS_FREE_EXTENT_LEN_TYPE;
|
||||
key.skii_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
|
||||
key.skfl_neglen = cpu_to_le64(-len);
|
||||
key.skfl_blkno = cpu_to_le64(start);
|
||||
key.sk_zone = SCOUTFS_FREE_EXTENT_ORDER_ZONE;
|
||||
key.skfo_revord = cpu_to_le64(U64_MAX - free_extent_order(len));
|
||||
key.skfo_end = cpu_to_le64(start + len - 1);
|
||||
key.skfo_len = cpu_to_le64(len);
|
||||
btree_append_item(bt, &key, NULL, 0);
|
||||
|
||||
return write_block(fd, SCOUTFS_BLOCK_MAGIC_BTREE, fsid, seq, blkno,
|
||||
|
||||
+5
-5
@@ -362,17 +362,17 @@ static int print_mounted_client_entry(struct scoutfs_key *key, void *val,
|
||||
static int print_alloc_item(struct scoutfs_key *key, void *val,
|
||||
unsigned val_len, void *arg)
|
||||
{
|
||||
if (key->sk_type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE)
|
||||
if (key->sk_zone == SCOUTFS_FREE_EXTENT_BLKNO_ZONE)
|
||||
printf(" free extent: blkno %llu len %llu end %llu\n",
|
||||
le64_to_cpu(key->skfb_end) -
|
||||
le64_to_cpu(key->skfb_len) + 1,
|
||||
le64_to_cpu(key->skfb_len),
|
||||
le64_to_cpu(key->skfb_end));
|
||||
else
|
||||
printf(" free extent: blkno %llu len %llu neglen %lld\n",
|
||||
le64_to_cpu(key->skfl_blkno),
|
||||
-le64_to_cpu(key->skfl_neglen),
|
||||
(long long)le64_to_cpu(key->skfl_neglen));
|
||||
printf(" free extent: blkno %llu len %llu order %llu\n",
|
||||
le64_to_cpu(key->skfo_end) - le64_to_cpu(key->skfo_len) + 1,
|
||||
le64_to_cpu(key->skfo_len),
|
||||
(long long)(U64_MAX - le64_to_cpu(key->skfo_revord)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user