mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git
synced 2025-01-23 20:23:20 +08:00
btrfs-progs: fsck: fix a infinite loop on discount file extent repair
For a special case, discount file extent repair function will cause infinite loop. The case is, if the file loses all its extents, we won't have a hole to fill, causing repair function doing nothing. Since the I_ERR_DISCOUNT doesn't disappear, fsck will do an infinite loop. For such case, just puch hole to fill the whole range to fix it. Reported-by: Robert Munteanu <robert.munteanu@gmail.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
1ffa833a91
commit
773ede50c0
@ -2665,11 +2665,13 @@ static int repair_inode_discount_extent(struct btrfs_trans_handle *trans,
|
||||
{
|
||||
struct rb_node *node;
|
||||
struct file_extent_hole *hole;
|
||||
int found = 0;
|
||||
int ret = 0;
|
||||
|
||||
node = rb_first(&rec->holes);
|
||||
|
||||
while (node) {
|
||||
found = 1;
|
||||
hole = rb_entry(node, struct file_extent_hole, node);
|
||||
ret = btrfs_punch_hole(trans, root, rec->ino,
|
||||
hole->start, hole->len);
|
||||
@ -2683,6 +2685,13 @@ static int repair_inode_discount_extent(struct btrfs_trans_handle *trans,
|
||||
rec->errors &= ~I_ERR_FILE_EXTENT_DISCOUNT;
|
||||
node = rb_first(&rec->holes);
|
||||
}
|
||||
/* special case for a file losing all its file extent */
|
||||
if (!found) {
|
||||
ret = btrfs_punch_hole(trans, root, rec->ino, 0,
|
||||
round_up(rec->isize, root->sectorsize));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
printf("Fixed discount file extents for inode: %llu in root: %llu\n",
|
||||
rec->ino, root->objectid);
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user