btrfs-progs: qgroup-verify: Don't treat qgroup difference as error if the fs hasn't initialized a rescan
During fstests/btrfs/166, it's possible to hit a certain case where qgroup is just enabled but rescan hasn't kicked in. Since at qgroup enable time, we set the flag INCONSISTENT, and let later rescan clear that flag. If power loss occurs before the rescan starts, it's possible we get a qgroup status item with ON|INCONSISTENT but without the RESCAN flag. And in that case, it will definitely cause difference in qgroup accounting as all numbers in the qgroup tree are 0. Fix this false alert by also checking rescan progress from btrfs_status_item. And if we find rescan progress is still 0, INCONSISTENT flag set and no RESCAN flag set, we won't treat it as an error. Reported-by: Lu Fengqi <lufq.fnst@cn.fujitsu.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
4dca0ccf3d
commit
1d5b2ad921
|
@ -84,6 +84,7 @@ static struct counts_tree {
|
||||||
unsigned int num_groups;
|
unsigned int num_groups;
|
||||||
unsigned int rescan_running:1;
|
unsigned int rescan_running:1;
|
||||||
unsigned int qgroup_inconsist:1;
|
unsigned int qgroup_inconsist:1;
|
||||||
|
u64 scan_progress;
|
||||||
} counts = { .root = RB_ROOT };
|
} counts = { .root = RB_ROOT };
|
||||||
|
|
||||||
static LIST_HEAD(bad_qgroups);
|
static LIST_HEAD(bad_qgroups);
|
||||||
|
@ -922,6 +923,7 @@ static void read_qgroup_status(struct extent_buffer *eb, int slot,
|
||||||
counts->qgroup_inconsist = !!(flags &
|
counts->qgroup_inconsist = !!(flags &
|
||||||
BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT);
|
BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT);
|
||||||
counts->rescan_running = !!(flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN);
|
counts->rescan_running = !!(flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN);
|
||||||
|
counts->scan_progress = btrfs_qgroup_status_rescan(eb, status_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_quota_info(struct btrfs_fs_info *info)
|
static int load_quota_info(struct btrfs_fs_info *info)
|
||||||
|
@ -1319,6 +1321,7 @@ int report_qgroups(int all)
|
||||||
struct rb_node *node;
|
struct rb_node *node;
|
||||||
struct qgroup_count *c;
|
struct qgroup_count *c;
|
||||||
bool found_err = false;
|
bool found_err = false;
|
||||||
|
bool skip_err = false;
|
||||||
|
|
||||||
if (!repair && counts.rescan_running) {
|
if (!repair && counts.rescan_running) {
|
||||||
if (all) {
|
if (all) {
|
||||||
|
@ -1330,6 +1333,15 @@ int report_qgroups(int all)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* It's possible that rescan hasn't been initialized yet.
|
||||||
|
*/
|
||||||
|
if (counts.qgroup_inconsist && !counts.rescan_running &&
|
||||||
|
counts.rescan_running == 0) {
|
||||||
|
printf(
|
||||||
|
"Rescan hasn't been initialzied, a difference in qgroup accounting is expected\n");
|
||||||
|
skip_err = true;
|
||||||
|
}
|
||||||
if (counts.qgroup_inconsist && !counts.rescan_running)
|
if (counts.qgroup_inconsist && !counts.rescan_running)
|
||||||
fprintf(stderr, "Qgroup are marked as inconsistent.\n");
|
fprintf(stderr, "Qgroup are marked as inconsistent.\n");
|
||||||
node = rb_first(&counts.root);
|
node = rb_first(&counts.root);
|
||||||
|
@ -1343,7 +1355,7 @@ int report_qgroups(int all)
|
||||||
|
|
||||||
node = rb_next(node);
|
node = rb_next(node);
|
||||||
}
|
}
|
||||||
if (found_err)
|
if (found_err && !skip_err)
|
||||||
return -EUCLEAN;
|
return -EUCLEAN;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue