On 2019/3/29 下午5:36, Nikolay Borisov wrote:
>
>
> On 25.03.19 г. 10:22 ч., Qu Wenruo wrote:
>> In root tree, we only have 2 types of inodes:
>> - ROOT_TREE_DIR inode
>> Its mode is fixed to 40755
>> - free space cache inodes
>> Its mode is fixed to 100600
>>
>> This patch will add the ability to repair such inodes to lowmem mode.
>> For fs/subvolume tree error, at least we haven't see such corruption
>> yet, so we don't need to rush to fix corruption in fs trees yet.
>>
>> The repair function, repair_imode() can be reused by later original mode
>> patch, so it's placed in check/mode-common.c.
>>
>> Signed-off-by: Qu Wenruo <w...@suse.com>
>> ---
>> check/mode-common.c | 48 +++++++++++++++++++++++++++++++++++++++++++
>> check/mode-common.h | 2 ++
>> check/mode-lowmem.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-
>> 3 files changed, 99 insertions(+), 1 deletion(-)
>>
>> diff --git a/check/mode-common.c b/check/mode-common.c
>> index fed102b0ce7a..1c150a3d5a7c 100644
>> --- a/check/mode-common.c
>> +++ b/check/mode-common.c
>> @@ -795,3 +795,51 @@ out:
>> btrfs_release_path(&path);
>> return ret;
>> }
>> +
>> +/*
>> + * Reset inode mode with invalid mode to its known correct value.
>> + *
>> + * Only support free space cache inode and root tree dir inode of root tree.
>> + * Caller should ensure such condition.
>> + *
>> + * Return 0 if repair is done, @path will point to the correct inode item.
>> + * Return <0 for errors.
>> + */
>> +int repair_imode(struct btrfs_trans_handle *trans, struct btrfs_root *root,
>> + struct btrfs_path *path, u64 ino)
>> +{
>
> How about renaming this function to reset_imode/set_imode:
>
> reset_imode and make it take a u32 parameter for the imode.
[snip]
>> + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
>> + ASSERT(key.type == BTRFS_INODE_ITEM_KEY);
>> + if (key.objectid != BTRFS_ROOT_TREE_DIR_OBJECTID &&
>> + !is_fstree(key.objectid)) {
>> + error("unsupported ino %llu", key.objectid);
>> + return -ENOTTY;
>> + }
>> +
>> + trans = btrfs_start_transaction(root, 1);
>> + if (IS_ERR(trans)) {
>> + ret = PTR_ERR(trans);
>> + errno = -ret;
>> + error("failed to start transaction: %m");
>> + return ret;
>> + }
>> + btrfs_release_path(path);
>> +
>> + ret = repair_imode(trans, root, path, key.objectid);
>
> And calling it here with the correct parameter based on whether ino is
> BTRFS_ROOT_TREE_DIR_OBJECTID. Also move the asserts from reset_imode to
> this function.
Makes sense.
I'll go that direction.
Thanks,
Qu
>
> Otherwise you are separating the checks/asserts across 2 function and
> this is somewhat cumbersome to follow.
>