mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-04 23:27:05 +00:00
scoutfs: fix alloc eio for free region
It's possible for the next segno to fall at the end of an allocation region that doesn't have any bits set. The code shouldn't return -EIO in that case, it should carry on to the next region. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+20
-16
@@ -131,31 +131,35 @@ int scoutfs_alloc_segno(struct super_block *sb, u64 *segno)
|
||||
ind = sal->next_segno >> SCOUTFS_ALLOC_REGION_SHIFT;
|
||||
nr = sal->next_segno & SCOUTFS_ALLOC_REGION_MASK;
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
reg = scoutfs_ring_lookup_next(&sal->ring, &ind);
|
||||
} while (reg == NULL && ind && (ind = 0, nr = 0, 1));
|
||||
if (reg == NULL && ind != 0) {
|
||||
ind = 0;
|
||||
nr = 0;
|
||||
continue;
|
||||
}
|
||||
if (IS_ERR_OR_NULL(reg)) {
|
||||
if (IS_ERR(reg))
|
||||
ret = PTR_ERR(reg);
|
||||
else
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(reg)) {
|
||||
if (IS_ERR(reg))
|
||||
ret = PTR_ERR(reg);
|
||||
else
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
nr = find_next_bit_le(reg->bits, SCOUTFS_ALLOC_REGION_BITS, nr);
|
||||
if (nr < SCOUTFS_ALLOC_REGION_BITS)
|
||||
break;
|
||||
|
||||
/* possible for nr to be after all free bits, keep going */
|
||||
ind++;
|
||||
nr = 0;
|
||||
}
|
||||
|
||||
scoutfs_ring_dirty(&sal->ring, reg);
|
||||
|
||||
nr = find_next_bit_le(reg->bits, SCOUTFS_ALLOC_REGION_BITS, nr);
|
||||
if (nr >= SCOUTFS_ALLOC_REGION_BITS) {
|
||||
/* XXX corruption? shouldn't find empty regions */
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ind = le64_to_cpu(reg->index);
|
||||
|
||||
clear_bit_le(nr, reg->bits);
|
||||
|
||||
if (empty_region(reg))
|
||||
scoutfs_ring_delete(&sal->ring, reg);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user