Re: [PATCH 1/2] btrfs-progs: cmds-check.c: supports inode nbytes fix in lowmem

2017-01-19 Thread Su Yue

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

2017-01-17 Thread David Sterba
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

2017-01-08 Thread Su Yue
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);