From: Qu Wenruo Date: Wed, 5 Aug 2015 08:03:13 +0000 (+0800) Subject: btrfs-progs: fsck: fix a infinite loop on discount file extent repair X-Git-Tag: upstream/4.16.1~2079 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=773ede50c002a28eabc16b5afa43951993170ab3;p=platform%2Fupstream%2Fbtrfs-progs.git 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 Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- diff --git a/cmds-check.c b/cmds-check.c index 31ed589..4fa8709 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -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: