Compare commits

..

2 Commits

Author SHA1 Message Date
Zach Brown
55f9435fad 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>
2023-07-17 09:36:09 -07:00
Zach Brown
14901c39aa Merge pull request #129 from versity/zab/v1.14
v1.14 Release
2023-06-29 11:30:01 -07:00
3 changed files with 8 additions and 27 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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