mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-19 06:26:28 +00:00
Fix partial preallocation when _contig_only = 0
Data preallocation attempts to allocate large aligned regions of extents. It tried to fill the hole around a write offset that didn't contain an extent. It missed the case where there can be multiple extents between the start of the region and the hole. It could try to overwrite these additional existing extents and writes could return EINVAL. We fix this by trimming the preallocation to start at the write offset if there are any extents in the region before the write offset. The data preallocation test output has to be updated now that allocation extents won't grow towards the start of the region when there are existing extents. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+6
-8
@@ -458,11 +458,9 @@ static int alloc_block(struct super_block *sb, struct inode *inode,
|
||||
/*
|
||||
* 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).
|
||||
* that contains iblock. We'd have to add a bit of plumbing
|
||||
* to find previous extents so we only search for a next
|
||||
* extent from the front of the region and from iblock.
|
||||
*/
|
||||
div64_u64_rem(iblock, opts.data_prealloc_blocks, &rem);
|
||||
start = iblock - rem;
|
||||
@@ -473,15 +471,15 @@ static int alloc_block(struct super_block *sb, struct inode *inode,
|
||||
|
||||
/* 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;
|
||||
count -= iblock - start;
|
||||
start = iblock;
|
||||
/* 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 */
|
||||
/* trim count by next extent after iblock */
|
||||
if (found.len && found.start > start && found.start < start + count)
|
||||
count = (found.start - start);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,6 @@ wrote blk 39
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
55.. 1:
|
||||
@@ -143,10 +142,8 @@ wrote blk 44
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
55.. 1:
|
||||
@@ -167,10 +164,8 @@ wrote blk 48
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -193,10 +188,8 @@ wrote blk 62
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -221,10 +214,8 @@ wrote blk 67
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -252,10 +243,8 @@ wrote blk 73
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -285,10 +274,8 @@ wrote blk 86
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -304,7 +291,6 @@ wrote blk 86
|
||||
73.. 1:
|
||||
74.. 5: unwritten
|
||||
79.. 2:
|
||||
81.. 5: unwritten
|
||||
86.. 1:
|
||||
87.. 2:
|
||||
95.. 1: eof
|
||||
@@ -320,10 +306,8 @@ wrote blk 92
|
||||
25.. 1:
|
||||
26.. 6: unwritten
|
||||
32.. 1:
|
||||
33.. 6: unwritten
|
||||
39.. 1:
|
||||
40.. 1:
|
||||
41.. 3: unwritten
|
||||
44.. 1:
|
||||
45.. 3: unwritten
|
||||
48.. 1:
|
||||
@@ -339,10 +323,8 @@ wrote blk 92
|
||||
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
|
||||
|
||||
@@ -168,7 +168,8 @@ print_extents_found $prefix
|
||||
# the start, and one at the end.
|
||||
#
|
||||
# Let's keep this last because it creates a ton of output to read
|
||||
# through.
|
||||
# through. The correct output is tied to preallocation strategy so it
|
||||
# has to be verified each time we change preallocation.
|
||||
#
|
||||
echo "== block writes into region allocs hole"
|
||||
t_set_sysfs_mount_option 0 data_prealloc_blocks 8
|
||||
|
||||
Reference in New Issue
Block a user