Re: [PATCH 1/2] btrfs-progs: cmds-check.c: supports inode nbytes fix in lowmem
Hi, The test flag override way only runs all tests in lowmem mode or not, but can't decide one test repair or not. I have some ideas below: 1.Create a hidden empty file under the test dir which need to be repaired.Edit tests/common.local:_skip_spec() to judge repair or not by the existence of hidden file. 2.Or just edit a test.sh under the test dir.I test my patches in this way but may the way is not grace enough. I'm wondering which one is perferred. Thanks Su On 01/17/2017 11:40 PM, David Sterba wrote: Hi, I have some comments, see below. On Mon, Jan 09, 2017 at 01:38:07PM +0800, Su Yue wrote: Added 'repair_inode_item' which dispatches functions such as 'repair_inode__nbytes_lowmem' to correct errors and 'struct inode_item_fix_info' to store correct values and errors. Signed-off-by: Su Yue--- cmds-check.c | 161 +++ 1 file changed, 152 insertions(+), 9 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index 1dba298..567ca80 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -371,6 +371,17 @@ struct root_item_info { }; /* + * Use inode_item_fix_info as function check_inode_item's arg. + */ +struct inode_item_fix_info { + u64 ino; + u64 isize; + u64 nbytes; + + int err; +}; + +/* * Error bit for low memory mode check. * * Currently no caller cares about it yet. Just internal use for error @@ -1866,13 +1877,16 @@ struct node_refs { static int update_nodes_refs(struct btrfs_root *root, u64 bytenr, struct node_refs *nrefs, u64 level); static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, - unsigned int ext_ref); - + unsigned int ext_ref, + struct inode_item_fix_info *info); +static int repair_inode_item(struct btrfs_root *root, +struct inode_item_fix_info *info); static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, struct node_refs *nrefs, int *level, int ext_ref) { struct extent_buffer *cur = path->nodes[0]; struct btrfs_key key; + struct inode_item_fix_info info; u64 cur_bytenr; u32 nritems; u64 first_ino = 0; @@ -1881,6 +1895,7 @@ static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, int ret = 0; /* Final return value */ int err = 0; /* Positive error bitmap */ + memset(, 0, sizeof(info)); cur_bytenr = cur->start; /* skip to first inode item or the first inode number change */ @@ -1900,8 +1915,26 @@ static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, path->slots[0] = i; again: - err |= check_inode_item(root, path, ext_ref); + err |= check_inode_item(root, path, ext_ref, ); + + if (repair && (err & ~LAST_ITEM)) { + ret = repair_inode_item(root, ); + if (ret < 0) + goto out; + /* +* if some errors was repaired, path shall be searched +* again since path has been changed +*/ + if (ret == 0) { + btrfs_item_key_to_cpu(path->nodes[0], , + path->slots[0]); + btrfs_release_path(path); + btrfs_search_slot(NULL, root, , path, 0, 0); + + cur = path->nodes[0]; + } + } if (err & LAST_ITEM) goto out; @@ -2211,7 +2244,8 @@ out: } static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, - unsigned int ext_ref); + unsigned int ext_ref, + struct inode_item_fix_info *info); static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path, int *level, struct node_refs *nrefs, int ext_ref) @@ -2293,7 +2327,7 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path, } ret = check_child_node(root, cur, path->slots[*level], next); - if (ret < 0) + if (ret < 0) break; if (btrfs_is_leaf(next)) @@ -2383,6 +2417,105 @@ out: return ret; } +/* + * Set inode's nbytes to correct value in @info + * + * Returns <0 means on error + * Returns 0 means successful repair + */ +static int repair_inode_nbytes_lowmem(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode_item_fix_info *info) +{ + struct btrfs_inode_item *ei; + struct btrfs_key key; + struct btrfs_path path; + int ret; + + ASSERT(info); + key.objectid
Re: [PATCH 1/2] btrfs-progs: cmds-check.c: supports inode nbytes fix in lowmem
Hi, I have some comments, see below. On Mon, Jan 09, 2017 at 01:38:07PM +0800, Su Yue wrote: > Added 'repair_inode_item' which dispatches functions such as > 'repair_inode__nbytes_lowmem' to correct errors and > 'struct inode_item_fix_info' to store correct values and errors. > > Signed-off-by: Su Yue> --- > cmds-check.c | 161 > +++ > 1 file changed, 152 insertions(+), 9 deletions(-) > > diff --git a/cmds-check.c b/cmds-check.c > index 1dba298..567ca80 100644 > --- a/cmds-check.c > +++ b/cmds-check.c > @@ -371,6 +371,17 @@ struct root_item_info { > }; > > /* > + * Use inode_item_fix_info as function check_inode_item's arg. > + */ > +struct inode_item_fix_info { > + u64 ino; > + u64 isize; > + u64 nbytes; > + > + int err; > +}; > + > +/* > * Error bit for low memory mode check. > * > * Currently no caller cares about it yet. Just internal use for error > @@ -1866,13 +1877,16 @@ struct node_refs { > static int update_nodes_refs(struct btrfs_root *root, u64 bytenr, >struct node_refs *nrefs, u64 level); > static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, > - unsigned int ext_ref); > - > + unsigned int ext_ref, > + struct inode_item_fix_info *info); > +static int repair_inode_item(struct btrfs_root *root, > + struct inode_item_fix_info *info); > static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path > *path, > struct node_refs *nrefs, int *level, int ext_ref) > { > struct extent_buffer *cur = path->nodes[0]; > struct btrfs_key key; > + struct inode_item_fix_info info; > u64 cur_bytenr; > u32 nritems; > u64 first_ino = 0; > @@ -1881,6 +1895,7 @@ static int process_one_leaf_v2(struct btrfs_root *root, > struct btrfs_path *path, > int ret = 0; /* Final return value */ > int err = 0; /* Positive error bitmap */ > > + memset(, 0, sizeof(info)); > cur_bytenr = cur->start; > > /* skip to first inode item or the first inode number change */ > @@ -1900,8 +1915,26 @@ static int process_one_leaf_v2(struct btrfs_root > *root, struct btrfs_path *path, > path->slots[0] = i; > > again: > - err |= check_inode_item(root, path, ext_ref); > + err |= check_inode_item(root, path, ext_ref, ); > + > + if (repair && (err & ~LAST_ITEM)) { > + ret = repair_inode_item(root, ); > > + if (ret < 0) > + goto out; > + /* > + * if some errors was repaired, path shall be searched > + * again since path has been changed > + */ > + if (ret == 0) { > + btrfs_item_key_to_cpu(path->nodes[0], , > + path->slots[0]); > + btrfs_release_path(path); > + btrfs_search_slot(NULL, root, , path, 0, 0); > + > + cur = path->nodes[0]; > + } > + } > if (err & LAST_ITEM) > goto out; > > @@ -2211,7 +2244,8 @@ out: > } > > static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, > - unsigned int ext_ref); > + unsigned int ext_ref, > + struct inode_item_fix_info *info); > > static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path > *path, >int *level, struct node_refs *nrefs, int ext_ref) > @@ -2293,7 +2327,7 @@ static int walk_down_tree_v2(struct btrfs_root *root, > struct btrfs_path *path, > } > > ret = check_child_node(root, cur, path->slots[*level], next); > - if (ret < 0) > + if (ret < 0) > break; > > if (btrfs_is_leaf(next)) > @@ -2383,6 +2417,105 @@ out: > return ret; > } > > +/* > + * Set inode's nbytes to correct value in @info > + * > + * Returns <0 means on error > + * Returns 0 means successful repair > + */ > +static int repair_inode_nbytes_lowmem(struct btrfs_trans_handle *trans, > + struct btrfs_root *root, > + struct inode_item_fix_info *info) > +{ > + struct btrfs_inode_item *ei; > + struct btrfs_key key; > + struct btrfs_path path; > + int ret; > + > + ASSERT(info); > + key.objectid = info->ino; > + key.type = BTRFS_INODE_ITEM_KEY; > + key.offset = 0; The path init call is missing here. > + > + ret = btrfs_search_slot(trans, root, , , 0, 1); > + if (ret < 0) > + goto out; > + if (ret > 0) { > + ret = -ENOENT; > + goto out; > + } > + > + ei = btrfs_item_ptr(path.nodes[0],
[PATCH 1/2] btrfs-progs: cmds-check.c: supports inode nbytes fix in lowmem
Added 'repair_inode_item' which dispatches functions such as 'repair_inode__nbytes_lowmem' to correct errors and 'struct inode_item_fix_info' to store correct values and errors. Signed-off-by: Su Yue--- cmds-check.c | 161 +++ 1 file changed, 152 insertions(+), 9 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index 1dba298..567ca80 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -371,6 +371,17 @@ struct root_item_info { }; /* + * Use inode_item_fix_info as function check_inode_item's arg. + */ +struct inode_item_fix_info { + u64 ino; + u64 isize; + u64 nbytes; + + int err; +}; + +/* * Error bit for low memory mode check. * * Currently no caller cares about it yet. Just internal use for error @@ -1866,13 +1877,16 @@ struct node_refs { static int update_nodes_refs(struct btrfs_root *root, u64 bytenr, struct node_refs *nrefs, u64 level); static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, - unsigned int ext_ref); - + unsigned int ext_ref, + struct inode_item_fix_info *info); +static int repair_inode_item(struct btrfs_root *root, +struct inode_item_fix_info *info); static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, struct node_refs *nrefs, int *level, int ext_ref) { struct extent_buffer *cur = path->nodes[0]; struct btrfs_key key; + struct inode_item_fix_info info; u64 cur_bytenr; u32 nritems; u64 first_ino = 0; @@ -1881,6 +1895,7 @@ static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, int ret = 0; /* Final return value */ int err = 0; /* Positive error bitmap */ + memset(, 0, sizeof(info)); cur_bytenr = cur->start; /* skip to first inode item or the first inode number change */ @@ -1900,8 +1915,26 @@ static int process_one_leaf_v2(struct btrfs_root *root, struct btrfs_path *path, path->slots[0] = i; again: - err |= check_inode_item(root, path, ext_ref); + err |= check_inode_item(root, path, ext_ref, ); + + if (repair && (err & ~LAST_ITEM)) { + ret = repair_inode_item(root, ); + if (ret < 0) + goto out; + /* +* if some errors was repaired, path shall be searched +* again since path has been changed +*/ + if (ret == 0) { + btrfs_item_key_to_cpu(path->nodes[0], , + path->slots[0]); + btrfs_release_path(path); + btrfs_search_slot(NULL, root, , path, 0, 0); + + cur = path->nodes[0]; + } + } if (err & LAST_ITEM) goto out; @@ -2211,7 +2244,8 @@ out: } static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, - unsigned int ext_ref); + unsigned int ext_ref, + struct inode_item_fix_info *info); static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path, int *level, struct node_refs *nrefs, int ext_ref) @@ -2293,7 +2327,7 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path, } ret = check_child_node(root, cur, path->slots[*level], next); - if (ret < 0) + if (ret < 0) break; if (btrfs_is_leaf(next)) @@ -2383,6 +2417,105 @@ out: return ret; } +/* + * Set inode's nbytes to correct value in @info + * + * Returns <0 means on error + * Returns 0 means successful repair + */ +static int repair_inode_nbytes_lowmem(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode_item_fix_info *info) +{ + struct btrfs_inode_item *ei; + struct btrfs_key key; + struct btrfs_path path; + int ret; + + ASSERT(info); + key.objectid = info->ino; + key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; + + ret = btrfs_search_slot(trans, root, , , 0, 1); + if (ret < 0) + goto out; + if (ret > 0) { + ret = -ENOENT; + goto out; + } + + ei = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_inode_item); + btrfs_set_inode_nbytes(path.nodes[0], ei, info->nbytes); + btrfs_mark_buffer_dirty(path.nodes[0]); + printf("reset nbytes for inode %llu root %llu\n", info->ino, + root->root_key.objectid);