Re: [PATCH] btrfs-progs: rescue: Add ability to disable quota offline

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2018/8/21 下午3:14, Misono Tomohiro wrote:
> On 2018/08/12 10:33, Qu Wenruo wrote:
>> 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.
>>
>> So add an offline rescue tool to disable quota.
>>
>> Reported-by: Dan Merillat <dan.merillat@xxxxxxxxx>
>> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
>> ---
>> 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);
>> +	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");
>> +		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);
> 
> This is not what "btrfs quota disable" does (completely removes quota tree),
> so I think it is better to have different name other than "disable-quota"
> (I'm not sure about good name, maybe suspend?).

Yep, it is not the same as "btrfs quota disable", but the end result is
the same. Quota will be disabled, leaving quota tree as is.

Quota tree can be re-initialized just by re-enabling quota.

As long as the end result is the same, I doubt if it's really needed to
use a different name.

> 
> btw, maybe we should add this ability to online fs too so that we can
> temporally disable quota during balance while keeping limit/inheritance settings?

For balance, I'm considering to skip unmodified subtrees to speed up the
balance.

Temporarily disable quota has one big disadvantage, we need to rescan
quota, although that is much better than balance hang, it still brings
extra performance hit for later rescan.

Thanks,
Qu

> 
> Thanks,
> Misono
> 
>> +	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
>>  	}
>>  };
>>
> 

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux