mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-06 20:16:25 +00:00
Merge pull request #128 from versity/zab/prealloc_fragmentation
Zab/prealloc fragmentation
This commit is contained in:
@@ -456,11 +456,13 @@ static int alloc_block(struct super_block *sb, struct inode *inode,
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Preallocation of aligned regions only preallocates if
|
||||
* the aligned region contains no extents at all. This
|
||||
* could be fooled by offline sparse extents but we
|
||||
* don't want to iterate over all offline extents in the
|
||||
* aligned region.
|
||||
* Preallocation within aligned regions tries to
|
||||
* allocate an extent to fill the hole in the region
|
||||
* that contains iblock. We search for a next extent
|
||||
* from the start of the region. If it's at the start
|
||||
* we might have to search again to find an existing
|
||||
* extent at the end of the region. (This next could be
|
||||
* given to us by the caller).
|
||||
*/
|
||||
div64_u64_rem(iblock, opts.data_prealloc_blocks, &rem);
|
||||
start = iblock - rem;
|
||||
@@ -468,8 +470,20 @@ static int alloc_block(struct super_block *sb, struct inode *inode,
|
||||
ret = scoutfs_ext_next(sb, &data_ext_ops, &args, start, 1, &found);
|
||||
if (ret < 0 && ret != -ENOENT)
|
||||
goto out;
|
||||
if (found.len && found.start < start + count)
|
||||
count = 1;
|
||||
|
||||
/* trim count if there's an extent in the region before iblock */
|
||||
if (found.len && found.start < iblock) {
|
||||
count -= (found.start + found.len) - start;
|
||||
start = found.start + found.len;
|
||||
/* see if there's also an extent after iblock */
|
||||
ret = scoutfs_ext_next(sb, &data_ext_ops, &args, iblock, 1, &found);
|
||||
if (ret < 0 && ret != -ENOENT)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* trim count by a next extent in the region */
|
||||
if (found.len && found.start > start && found.start < start + count)
|
||||
count = (found.start - start);
|
||||
}
|
||||
|
||||
/* overall prealloc limit */
|
||||
@@ -1253,6 +1267,7 @@ int scoutfs_data_move_blocks(struct inode *from, u64 from_off,
|
||||
from_iblock = from_off >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
count = (byte_len + SCOUTFS_BLOCK_SM_MASK) >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
to_iblock = to_off >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
from_start = from_iblock;
|
||||
|
||||
/* only move extent blocks inside i_size, careful not to wrap */
|
||||
from_size = i_size_read(from);
|
||||
@@ -1329,7 +1344,7 @@ int scoutfs_data_move_blocks(struct inode *from, u64 from_off,
|
||||
|
||||
/* find the next extent to move */
|
||||
ret = scoutfs_ext_next(sb, &data_ext_ops, &from_args,
|
||||
from_iblock, 1, &ext);
|
||||
from_start, 1, &ext);
|
||||
if (ret < 0) {
|
||||
if (ret == -ENOENT) {
|
||||
done = true;
|
||||
@@ -1417,6 +1432,12 @@ int scoutfs_data_move_blocks(struct inode *from, u64 from_off,
|
||||
i_size_read(from);
|
||||
i_size_write(to, to_size);
|
||||
}
|
||||
|
||||
/* find next after moved extent, avoiding wrapping */
|
||||
if (from_start + len < from_start)
|
||||
from_start = from_iblock + count + 1;
|
||||
else
|
||||
from_start += len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,3 +24,325 @@
|
||||
/mnt/test/test/data-prealloc/file-2: 5 extents found
|
||||
/mnt/test/test/data-prealloc/file-1: 3 extents found
|
||||
/mnt/test/test/data-prealloc/file-2: 3 extents found
|
||||
== block writes into region allocs hole
|
||||
wrote blk 24
|
||||
wrote blk 32
|
||||
wrote blk 40
|
||||
wrote blk 55
|
||||
wrote blk 63
|
||||
wrote blk 71
|
||||
wrote blk 72
|
||||
wrote blk 79
|
||||
wrote blk 80
|
||||
wrote blk 87
|
||||
wrote blk 88
|
||||
wrote blk 95
|
||||
before:
|
||||
24.. 1:
|
||||
32.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 0 at pos 0
|
||||
wrote blk 0
|
||||
0.. 1:
|
||||
1.. 7: unwritten
|
||||
24.. 1:
|
||||
32.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 0 at pos 1
|
||||
wrote blk 15
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
24.. 1:
|
||||
32.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 0 at pos 2
|
||||
wrote blk 19
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
32.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 1 at pos 0
|
||||
wrote blk 25
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 1 at pos 1
|
||||
wrote blk 39
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 1 at pos 2
|
||||
wrote blk 44
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 2 at pos 0
|
||||
wrote blk 48
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 2 at pos 1
|
||||
wrote blk 62
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
56.. 6: unwritten
|
||||
62.. 1:
|
||||
63.. 1:
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 2 at pos 2
|
||||
wrote blk 67
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
56.. 6: unwritten
|
||||
62.. 1:
|
||||
63.. 1:
|
||||
64.. 3: unwritten
|
||||
67.. 1:
|
||||
68.. 3: unwritten
|
||||
71.. 2:
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 3 at pos 0
|
||||
wrote blk 73
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
56.. 6: unwritten
|
||||
62.. 1:
|
||||
63.. 1:
|
||||
64.. 3: unwritten
|
||||
67.. 1:
|
||||
68.. 3: unwritten
|
||||
71.. 2:
|
||||
73.. 1:
|
||||
74.. 5: unwritten
|
||||
79.. 2:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 3 at pos 1
|
||||
wrote blk 86
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
56.. 6: unwritten
|
||||
62.. 1:
|
||||
63.. 1:
|
||||
64.. 3: unwritten
|
||||
67.. 1:
|
||||
68.. 3: unwritten
|
||||
71.. 2:
|
||||
73.. 1:
|
||||
74.. 5: unwritten
|
||||
79.. 2:
|
||||
81.. 5: unwritten
|
||||
86.. 1:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
writing into existing 3 at pos 2
|
||||
wrote blk 92
|
||||
0.. 1:
|
||||
1.. 14: unwritten
|
||||
15.. 1:
|
||||
16.. 3: unwritten
|
||||
19.. 1:
|
||||
20.. 4: unwritten
|
||||
24.. 1:
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
49.. 6: unwritten
|
||||
55.. 1:
|
||||
56.. 6: unwritten
|
||||
62.. 1:
|
||||
63.. 1:
|
||||
64.. 3: unwritten
|
||||
67.. 1:
|
||||
68.. 3: unwritten
|
||||
71.. 2:
|
||||
73.. 1:
|
||||
74.. 5: unwritten
|
||||
79.. 2:
|
||||
81.. 5: unwritten
|
||||
86.. 1:
|
||||
87.. 2:
|
||||
89.. 3: unwritten
|
||||
92.. 1:
|
||||
93.. 2: unwritten
|
||||
95.. 1: eof
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
#
|
||||
t_require_commands scoutfs stat filefrag dd touch truncate
|
||||
|
||||
write_block()
|
||||
{
|
||||
local file="$1"
|
||||
local blk="$2"
|
||||
|
||||
dd if=/dev/zero of="$file" bs=4096 seek=$blk count=1 conv=notrunc status=none
|
||||
echo "wrote blk $blk"
|
||||
}
|
||||
|
||||
write_forwards()
|
||||
{
|
||||
local prefix="$1"
|
||||
@@ -70,6 +79,25 @@ print_extents_found()
|
||||
filefrag "$prefix"* 2>&1 | grep "extent.*found" | t_filter_fs
|
||||
}
|
||||
|
||||
#
|
||||
# print the logical start, len, and flags if they're there.
|
||||
#
|
||||
print_logical_extents()
|
||||
{
|
||||
local file="$1"
|
||||
|
||||
filefrag -v -b4096 "$file" 2>&1 | t_filter_fs | awk '
|
||||
($1 ~ /[0-9]+:/) {
|
||||
if ($NF !~ /[0-9]+:/) {
|
||||
flags=$NF
|
||||
} else {
|
||||
flags=""
|
||||
}
|
||||
print $2, $6, flags
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
t_save_all_sysfs_mount_options data_prealloc_blocks
|
||||
t_save_all_sysfs_mount_options data_prealloc_contig_only
|
||||
restore_options()
|
||||
@@ -133,4 +161,70 @@ t_set_sysfs_mount_option 0 data_prealloc_contig_only 0
|
||||
write_forwards $prefix 3
|
||||
print_extents_found $prefix
|
||||
|
||||
#
|
||||
# prepare aligned regions of 8 blocks that we'll write into.
|
||||
# We'll right into the first, last, and middle block of each
|
||||
# region which was prepared with no existing extents, one at
|
||||
# the start, and one at the end.
|
||||
#
|
||||
# Let's keep this last because it creates a ton of output to read
|
||||
# through.
|
||||
#
|
||||
echo "== block writes into region allocs hole"
|
||||
t_set_sysfs_mount_option 0 data_prealloc_blocks 8
|
||||
t_set_sysfs_mount_option 0 data_prealloc_contig_only 1
|
||||
touch "$prefix"
|
||||
truncate -s 0 "$prefix"
|
||||
|
||||
# write initial blocks in regions
|
||||
base=0
|
||||
for sides in 0 1 2 3; do
|
||||
for i in 0 1 2; do
|
||||
case "$sides" in
|
||||
# none
|
||||
0) ;;
|
||||
# left
|
||||
1) write_block $prefix $((base + 0)) ;;
|
||||
# right
|
||||
2) write_block $prefix $((base + 7)) ;;
|
||||
# both
|
||||
3) write_block $prefix $((base + 0))
|
||||
write_block $prefix $((base + 7)) ;;
|
||||
esac
|
||||
((base+=8))
|
||||
done
|
||||
done
|
||||
|
||||
echo before:
|
||||
print_logical_extents "$prefix"
|
||||
|
||||
# now write into the first, middle, and last empty block of each
|
||||
t_set_sysfs_mount_option 0 data_prealloc_contig_only 0
|
||||
base=0
|
||||
for sides in 0 1 2 3; do
|
||||
for i in 0 1 2; do
|
||||
echo "writing into existing $sides at pos $i"
|
||||
case "$sides" in
|
||||
# none
|
||||
0) left=$base; right=$((base + 7));;
|
||||
# left
|
||||
1) left=$((base + 1)); right=$((base + 7));;
|
||||
# right
|
||||
2) left=$((base)); right=$((base + 6));;
|
||||
# both
|
||||
3) left=$((base + 1)); right=$((base + 6));;
|
||||
esac
|
||||
case "$i" in
|
||||
# start
|
||||
0) write_block $prefix $left ;;
|
||||
# end
|
||||
1) write_block $prefix $right ;;
|
||||
# mid (both has 6 blocks internally)
|
||||
2) write_block $prefix $((left + 3)) ;;
|
||||
esac
|
||||
print_logical_extents "$prefix"
|
||||
((base+=8))
|
||||
done
|
||||
done
|
||||
|
||||
t_pass
|
||||
|
||||
Reference in New Issue
Block a user