btrfs-progs: Print warning message if qgroup data is inconsistent

Before this patch, qgroup show won't check btrfs qgroup status, so even
the INCONSISTENT flags is set, user is not aware of it.

This patch will include BTRFS_QGROUP_STATUS_ITEM in the search range and
check the flag, if there is any flag meaning the inconsistence of qgroup
data, info user.

NOTE: There is several kernel bugs from INCONSISTENT flags is always set
to RUNNING flags is not cleared until umount.
So this warning will always be here if using a newer kernel fixing these
bugs.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
master
Qu Wenruo 2015-02-27 16:26:38 +08:00 committed by David Sterba
parent 0f67b5aa01
commit 22057607b4
1 changed files with 24 additions and 2 deletions

View File

@ -1017,6 +1017,20 @@ static void __filter_and_sort_qgroups(struct qgroup_lookup *all_qgroups,
n = rb_prev(n);
}
}
static inline void print_status_flag_warning(u64 flags)
{
if (!(flags & BTRFS_QGROUP_STATUS_FLAG_ON))
fprintf(stderr,
"WARNING: Quota disabled, qgroup data may be out of date\n");
else if (flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
fprintf(stderr,
"WARNING: Rescan is running, qgroup data may be incorrect\n");
else if (flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT)
fprintf(stderr,
"WARNING: Qgroup data inconsistent, rescan recommended\n");
}
static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
{
int ret;
@ -1040,7 +1054,7 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
sk->tree_id = BTRFS_QUOTA_TREE_OBJECTID;
sk->max_type = BTRFS_QGROUP_RELATION_KEY;
sk->min_type = BTRFS_QGROUP_INFO_KEY;
sk->min_type = BTRFS_QGROUP_STATUS_KEY;
sk->max_objectid = (u64)-1;
sk->max_offset = (u64)-1;
sk->max_transid = (u64)-1;
@ -1071,7 +1085,15 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
off);
off += sizeof(*sh);
if (sh->type == BTRFS_QGROUP_INFO_KEY) {
if (sh->type == BTRFS_QGROUP_STATUS_KEY) {
struct btrfs_qgroup_status_item *si;
u64 flags;
si = (struct btrfs_qgroup_status_item *)
(args.buf + off);
flags = btrfs_stack_qgroup_status_flags(si);
print_status_flag_warning(flags);
} else if (sh->type == BTRFS_QGROUP_INFO_KEY) {
info = (struct btrfs_qgroup_info_item *)
(args.buf + off);
a1 = btrfs_stack_qgroup_info_generation(info);