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>
{
struct rb_node *node;
struct file_extent_hole *hole;
{
struct rb_node *node;
struct file_extent_hole *hole;
int ret = 0;
node = rb_first(&rec->holes);
while (node) {
int ret = 0;
node = rb_first(&rec->holes);
while (node) {
hole = rb_entry(node, struct file_extent_hole, node);
ret = btrfs_punch_hole(trans, root, rec->ino,
hole->start, hole->len);
hole = rb_entry(node, struct file_extent_hole, node);
ret = btrfs_punch_hole(trans, root, rec->ino,
hole->start, hole->len);
rec->errors &= ~I_ERR_FILE_EXTENT_DISCOUNT;
node = rb_first(&rec->holes);
}
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:
printf("Fixed discount file extents for inode: %llu in root: %llu\n",
rec->ino, root->objectid);
out: