On 2018/8/22 上午10:33, Su Yue wrote: > > >> Sent: Sunday, August 12, 2018 at 9:33 AM >> From: "Qu Wenruo" <w...@suse.com> >> To: linux-btrfs@vger.kernel.org, dan.meril...@gmail.com >> Subject: [PATCH] btrfs-progs: rescue: Add ability to disable quota offline >> >> Provide an offline tool to disable quota. >> >> For kernel which skip_balance doesn't work, there is no way to disable >> quota on huge fs with balance, as quota will cause balance to hang for a >> long long time for each tree block switch. >> > Make sense the use case. > >> So add an offline rescue tool to disable quota. >> > >> Reported-by: Dan Merillat <dan.meril...@gmail.com> >> Signed-off-by: Qu Wenruo <w...@suse.com> > > Some nitpicks below. > After fixes them, you can add tag: > > Reviewed-by: Su Yue <suy.f...@cn.fujitsu.com> > >> --- >> This can patch can be fetched from github repo: >> https://github.com/adam900710/btrfs-progs/tree/quota_disable >> --- >> Documentation/btrfs-rescue.asciidoc | 6 +++ >> cmds-rescue.c | 80 +++++++++++++++++++++++++++++ >> 2 files changed, 86 insertions(+) >> >> diff --git a/Documentation/btrfs-rescue.asciidoc >> b/Documentation/btrfs-rescue.asciidoc >> index f94a0ff2b45e..fb088c1a768a 100644 >> --- a/Documentation/btrfs-rescue.asciidoc >> +++ b/Documentation/btrfs-rescue.asciidoc >> @@ -31,6 +31,12 @@ help. >> NOTE: Since *chunk-recover* will scan the whole device, it will be *VERY* >> slow >> especially executed on a large device. >> >> +*disable-quota* <device>:: >> +disable quota offline >> ++ >> +Acts as a fallback method to disable quota for case where mount hangs due to >> +balance and quota. >> + >> *fix-device-size* <device>:: >> fix device size and super block total bytes values that are do not match >> + >> diff --git a/cmds-rescue.c b/cmds-rescue.c >> index 38c4ab9b2ef6..c7cd92427e9d 100644 >> --- a/cmds-rescue.c >> +++ b/cmds-rescue.c >> @@ -250,6 +250,84 @@ out: >> return !!ret; >> } >> >> +static const char * const cmd_rescue_disable_quota_usage[] = { >> + "btrfs rescue disable-quota <device>", >> + "Disable quota, especially useful for balance mount hang when quota >> enabled", >> + "", >> + NULL >> +}; >> + >> +static int cmd_rescue_disable_quota(int argc, char **argv) >> +{ >> + struct btrfs_trans_handle *trans; >> + struct btrfs_fs_info *fs_info; >> + struct btrfs_path path; >> + struct btrfs_root *root; >> + struct btrfs_qgroup_status_item *qi; >> + struct btrfs_key key; >> + char *devname; >> + int ret; >> + >> + clean_args_no_options(argc, argv, cmd_rescue_disable_quota_usage); >> + if (check_argc_exact(argc, 2)) >> + usage(cmd_rescue_disable_quota_usage); >> + >> + devname = argv[optind]; >> + ret = check_mounted(devname); >> + if (ret < 0) { >> + error("could not check mount status: %s", strerror(-ret)); >> + return !!ret; >> + } else if (ret) { >> + error("%s is currently mounted", devname); >> + return !!ret; >> + } >> + fs_info = open_ctree_fs_info(devname, 0, 0, 0, OPEN_CTREE_WRITES); > > Not undertstand why not add OPEN_CTREE_PARTIAL here? > The function is located in cmd-rescue, so may the FS is corrupted already?
Here I'm trying to avoid anything wrong with extent tree. In that case, even we only CoW one tree block, with corrupted extent tree we could screw up the whole fs further more. So I avoid OPEN_CTREE_PARTIAL here. > >> + if (!fs_info) { >> + error("could not open btrfs"); >> + ret = -EIO; >> + return !!ret; >> + } >> + root = fs_info->quota_root; >> + if (!root) { >> + printf("Quota is not enabled, no need to modify the fs\n"); >> + goto close; >> + } >> + btrfs_init_path(&path); >> + trans = btrfs_start_transaction(root, 1); >> + if (IS_ERR(trans)) { >> + ret = PTR_ERR(trans); >> + error("failed to start transaction: %s", strerror(-ret)); >> + goto close; >> + } >> + key.objectid = 0; >> + key.type = BTRFS_QGROUP_STATUS_KEY; >> + key.offset = 0; >> + ret = btrfs_search_slot(trans, root, &key, &path, 0, 1); >> + if (ret < 0) { >> + error("failed to search tree: %s", strerror(-ret)); >> + goto close; >> + } >> + if (ret > 0) { >> + printf( >> + "qgroup status item not found, not need to modify the fs"); > nits: s/qgroup/Qgroup and a linebreaker is needed. Oh, I forgot that, Thanks for pointing this out, Qu > >> + ret = 0; >> + goto release; >> + } >> + qi = btrfs_item_ptr(path.nodes[0], path.slots[0], >> + struct btrfs_qgroup_status_item); >> + btrfs_set_qgroup_status_flags(path.nodes[0], qi, >> + BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT); >> + btrfs_mark_buffer_dirty(path.nodes[0]); >> + ret = btrfs_commit_transaction(trans, root); >> + if (ret < 0) >> + error("failed to commit transaction: %s", strerror(-ret)); >> +release: >> + btrfs_release_path(&path); >> +close: >> + close_ctree(fs_info->tree_root); >> + return !!ret; >> +} >> + >> static const char rescue_cmd_group_info[] = >> "toolbox for specific rescue operations"; >> >> @@ -262,6 +340,8 @@ const struct cmd_group rescue_cmd_group = { >> { "zero-log", cmd_rescue_zero_log, cmd_rescue_zero_log_usage, >> NULL, 0}, >> { "fix-device-size", cmd_rescue_fix_device_size, >> cmd_rescue_fix_device_size_usage, NULL, 0}, >> + { "disable-quota", cmd_rescue_disable_quota, >> + cmd_rescue_disable_quota_usage, NULL, 0}, >> NULL_CMD_STRUCT >> } >> }; >> -- >> 2.18.0 >> >>
signature.asc
Description: OpenPGP digital signature