Re: [PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-11-06 Thread Qu Wenruo



On 2018/11/7 下午3:04, Su Yanjun  wrote:
> 
> 
> On 11/7/2018 2:38 PM, Qu Wenruo wrote:
>>
>> On 2018/11/7 下午2:21, Su Yanjun  wrote:
>>>
>>> On 10/24/2018 8:45 AM, Qu Wenruo wrote:
 On 2018/10/23 下午5:41, Su Yue wrote:
> From: Su Yanjun 
>
> In original mode, if some file extent item has unaligned extent
> backref,
> fixup_extent_refs can't repair it. This patch will check extent
> alignment
> then delete file extent with unaligned extent backref.
 This looks a little strange to me.

 You mean, an unaligned FILE EXTENT has an unaligned EXTENT_ITEM?

 Then why not just delete the EXTENT_ITEM directly? No need to go back
 checking if it has a corresponding EXTENT_DATA since unaligned one is
 definitely corrupted.

 For corrupted EXTENT_DATA, it should get deleted when we check fs tree.

 This would save you a lot of codes.

 Thanks,
 Qu
>>> The situation is that the file extent has wrong extent backref, actually
>>> it doesn't exist.
>> Did you mean extent EXTENT_ITEM key's objectid is unaligned?
>>
>> Would you please give an example on this case? Like:
>> ( EXTENT_DATA 
>>     disk bytenr  disk len 
>>
>> And its backref like:
>> ( EXTENT_ITEM )
>>
>> And then mark where the number is incorrect.
>>
>> Thanks,
>> Qu
> 
> As in /btrfs-progs/tests/fsck-tests/001-bad-file-extent-bytenr case:
> 
> item 7 key (257 EXTENT_DATA 0) itemoff 3453 itemsize 53
> 
>     generation 6 type 1 (regular)
> 
>     extent data disk byte 755944791 nr 1048576
>     ^
> 
>     extent data offset 0 nr 1048576 ram 1048576
> 
>     extent compression 0 (none)

Then there is no "unaligned extent backref".

It's just a unaligned disk bytenr of a file extent.
Nothing to do with backref.

Please update the commit message to avoid such confusing words, and
include above info, which is pretty easy to understand.

Thanks,
Qu

> 
> Thanks,
> 
> Su
> 
>>> Thanks,
>>> Su
>>>
>>>
>>>
>>>
>>>
>>
> 
> 
> 


Re: [PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-11-06 Thread Su Yanjun




On 11/7/2018 2:38 PM, Qu Wenruo wrote:


On 2018/11/7 下午2:21, Su Yanjun  wrote:


On 10/24/2018 8:45 AM, Qu Wenruo wrote:

On 2018/10/23 下午5:41, Su Yue wrote:

From: Su Yanjun 

In original mode, if some file extent item has unaligned extent backref,
fixup_extent_refs can't repair it. This patch will check extent
alignment
then delete file extent with unaligned extent backref.

This looks a little strange to me.

You mean, an unaligned FILE EXTENT has an unaligned EXTENT_ITEM?

Then why not just delete the EXTENT_ITEM directly? No need to go back
checking if it has a corresponding EXTENT_DATA since unaligned one is
definitely corrupted.

For corrupted EXTENT_DATA, it should get deleted when we check fs tree.

This would save you a lot of codes.

Thanks,
Qu

The situation is that the file extent has wrong extent backref, actually
it doesn't exist.

Did you mean extent EXTENT_ITEM key's objectid is unaligned?

Would you please give an example on this case? Like:
( EXTENT_DATA 
disk bytenr  disk len 

And its backref like:
( EXTENT_ITEM )

And then mark where the number is incorrect.

Thanks,
Qu


As in /btrfs-progs/tests/fsck-tests/001-bad-file-extent-bytenr case:

item 7 key (257 EXTENT_DATA 0) itemoff 3453 itemsize 53

    generation 6 type 1 (regular)

    extent data disk byte 755944791 nr 1048576
    ^

    extent data offset 0 nr 1048576 ram 1048576

    extent compression 0 (none)

Thanks,

Su


Thanks,
Su













Re: [PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-11-06 Thread Qu Wenruo



On 2018/11/7 下午2:21, Su Yanjun  wrote:
> 
> 
> On 10/24/2018 8:45 AM, Qu Wenruo wrote:
>>
>> On 2018/10/23 下午5:41, Su Yue wrote:
>>> From: Su Yanjun 
>>>
>>> In original mode, if some file extent item has unaligned extent backref,
>>> fixup_extent_refs can't repair it. This patch will check extent
>>> alignment
>>> then delete file extent with unaligned extent backref.
>> This looks a little strange to me.
>>
>> You mean, an unaligned FILE EXTENT has an unaligned EXTENT_ITEM?
>>
>> Then why not just delete the EXTENT_ITEM directly? No need to go back
>> checking if it has a corresponding EXTENT_DATA since unaligned one is
>> definitely corrupted.
>>
>> For corrupted EXTENT_DATA, it should get deleted when we check fs tree.
>>
>> This would save you a lot of codes.
>>
>> Thanks,
>> Qu
> The situation is that the file extent has wrong extent backref, actually
> it doesn't exist.

Did you mean extent EXTENT_ITEM key's objectid is unaligned?

Would you please give an example on this case? Like:
( EXTENT_DATA 
   disk bytenr  disk len 

And its backref like:
( EXTENT_ITEM )

And then mark where the number is incorrect.

Thanks,
Qu

> 
> Thanks,
> Su
> 
> 
> 
> 
> 


Re: [PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-11-06 Thread Su Yanjun




On 10/24/2018 8:45 AM, Qu Wenruo wrote:


On 2018/10/23 下午5:41, Su Yue wrote:

From: Su Yanjun 

In original mode, if some file extent item has unaligned extent backref,
fixup_extent_refs can't repair it. This patch will check extent alignment
then delete file extent with unaligned extent backref.

This looks a little strange to me.

You mean, an unaligned FILE EXTENT has an unaligned EXTENT_ITEM?

Then why not just delete the EXTENT_ITEM directly? No need to go back
checking if it has a corresponding EXTENT_DATA since unaligned one is
definitely corrupted.

For corrupted EXTENT_DATA, it should get deleted when we check fs tree.

This would save you a lot of codes.

Thanks,
Qu
The situation is that the file extent has wrong extent backref, actually 
it doesn't exist.


Thanks,
Su







Re: [PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-10-23 Thread Qu Wenruo



On 2018/10/23 下午5:41, Su Yue wrote:
> From: Su Yanjun 
> 
> In original mode, if some file extent item has unaligned extent backref,
> fixup_extent_refs can't repair it. This patch will check extent alignment
> then delete file extent with unaligned extent backref.

This looks a little strange to me.

You mean, an unaligned FILE EXTENT has an unaligned EXTENT_ITEM?

Then why not just delete the EXTENT_ITEM directly? No need to go back
checking if it has a corresponding EXTENT_DATA since unaligned one is
definitely corrupted.

For corrupted EXTENT_DATA, it should get deleted when we check fs tree.

This would save you a lot of codes.

Thanks,
Qu

> 
> Signed-off-by: Su Yanjun 
> ---
>  check/main.c  | 278 +-
>  check/mode-original.h |  13 ++
>  ctree.h   |   2 +
>  disk-io.c |   1 +
>  4 files changed, 293 insertions(+), 1 deletion(-)
> 
> diff --git a/check/main.c b/check/main.c
> index 90d9fd570287..b5e68b3241e5 100644
> --- a/check/main.c
> +++ b/check/main.c
> @@ -460,6 +460,8 @@ static struct inode_record *clone_inode_rec(struct 
> inode_record *orig_rec)
>   struct inode_backref *backref;
>   struct inode_backref *orig;
>   struct inode_backref *tmp;
> + struct unaligned_extent_rec_t *src;
> + struct unaligned_extent_rec_t *dst;
>   struct rb_node *rb;
>   size_t size;
>   int ret;
> @@ -470,6 +472,7 @@ static struct inode_record *clone_inode_rec(struct 
> inode_record *orig_rec)
>   memcpy(rec, orig_rec, sizeof(*rec));
>   rec->refs = 1;
>   INIT_LIST_HEAD(>backrefs);
> + INIT_LIST_HEAD(>unaligned_extent_recs);
>   rec->holes = RB_ROOT;
>  
>   list_for_each_entry(orig, _rec->backrefs, list) {
> @@ -483,6 +486,17 @@ static struct inode_record *clone_inode_rec(struct 
> inode_record *orig_rec)
>   list_add_tail(>list, >backrefs);
>   }
>  
> + list_for_each_entry(src, _rec->unaligned_extent_recs, list) {
> + size = sizeof(*src);
> + dst = malloc(size);
> + if (!dst) {
> + ret = -ENOMEM;
> + goto cleanup;
> + }
> + memcpy(dst, src, size);
> + list_add_tail(>list, >unaligned_extent_recs);
> + }
> +
>   ret = copy_file_extent_holes(>holes, _rec->holes);
>   if (ret < 0)
>   goto cleanup_rb;
> @@ -506,6 +520,13 @@ cleanup:
>   free(orig);
>   }
>  
> + if (!list_empty(>unaligned_extent_recs))
> + list_for_each_entry_safe(src, dst, >unaligned_extent_recs,
> + list) {
> + list_del(>list);
> + free(src);
> + }
> +
>   free(rec);
>  
>   return ERR_PTR(ret);
> @@ -643,6 +664,7 @@ static struct inode_record *get_inode_rec(struct 
> cache_tree *inode_cache,
>   rec->extent_start = (u64)-1;
>   rec->refs = 1;
>   INIT_LIST_HEAD(>backrefs);
> + INIT_LIST_HEAD(>unaligned_extent_recs);
>   rec->holes = RB_ROOT;
>  
>   node = malloc(sizeof(*node));
> @@ -664,6 +686,18 @@ static struct inode_record *get_inode_rec(struct 
> cache_tree *inode_cache,
>   return rec;
>  }
>  
> +static void free_unaligned_extent_recs(struct list_head 
> *unaligned_extent_recs)
> +{
> + struct unaligned_extent_rec_t *urec;
> +
> + while (!list_empty(unaligned_extent_recs)) {
> + urec = list_entry(unaligned_extent_recs->next,
> + struct unaligned_extent_rec_t, list);
> + list_del(>list);
> + free(urec);
> + }
> +}
> +
>  static void free_inode_rec(struct inode_record *rec)
>  {
>   struct inode_backref *backref;
> @@ -676,6 +710,7 @@ static void free_inode_rec(struct inode_record *rec)
>   list_del(>list);
>   free(backref);
>   }
> + free_unaligned_extent_recs(>unaligned_extent_recs);
>   free_file_extent_holes(>holes);
>   free(rec);
>  }
> @@ -2474,18 +2509,154 @@ out:
>   return ret;
>  }
>  
> +static int btrfs_delete_item(struct btrfs_trans_handle *trans,
> + struct btrfs_root *root, struct btrfs_key *key)
> +{
> + struct btrfs_path path;
> + int ret = 0;
> +
> + btrfs_init_path();
> +
> + ret = btrfs_search_slot(trans, root, key, , -1, 1);
> + if (ret) {
> + if (ret > 0)
> + ret = -ENOENT;
> +
> + btrfs_release_path();
> + return ret;
> + }
> +
> + ret = btrfs_del_item(trans, root, );
> +
> + btrfs_release_path();
> + return ret;
> +}
> +
> +static int find_file_extent_offset_by_bytenr(struct btrfs_root *root,
> + u64 owner, u64 bytenr, u64 *offset_ret)
> +{
> + int ret = 0;
> + struct btrfs_path path;
> + struct btrfs_key key;
> + struct btrfs_key found_key;
> + struct 

[PATCH 11/13] btrfs-progs: check: Delete file extent item with unaligned extent backref

2018-10-23 Thread Su Yue
From: Su Yanjun 

In original mode, if some file extent item has unaligned extent backref,
fixup_extent_refs can't repair it. This patch will check extent alignment
then delete file extent with unaligned extent backref.

Signed-off-by: Su Yanjun 
---
 check/main.c  | 278 +-
 check/mode-original.h |  13 ++
 ctree.h   |   2 +
 disk-io.c |   1 +
 4 files changed, 293 insertions(+), 1 deletion(-)

diff --git a/check/main.c b/check/main.c
index 90d9fd570287..b5e68b3241e5 100644
--- a/check/main.c
+++ b/check/main.c
@@ -460,6 +460,8 @@ static struct inode_record *clone_inode_rec(struct 
inode_record *orig_rec)
struct inode_backref *backref;
struct inode_backref *orig;
struct inode_backref *tmp;
+   struct unaligned_extent_rec_t *src;
+   struct unaligned_extent_rec_t *dst;
struct rb_node *rb;
size_t size;
int ret;
@@ -470,6 +472,7 @@ static struct inode_record *clone_inode_rec(struct 
inode_record *orig_rec)
memcpy(rec, orig_rec, sizeof(*rec));
rec->refs = 1;
INIT_LIST_HEAD(>backrefs);
+   INIT_LIST_HEAD(>unaligned_extent_recs);
rec->holes = RB_ROOT;
 
list_for_each_entry(orig, _rec->backrefs, list) {
@@ -483,6 +486,17 @@ static struct inode_record *clone_inode_rec(struct 
inode_record *orig_rec)
list_add_tail(>list, >backrefs);
}
 
+   list_for_each_entry(src, _rec->unaligned_extent_recs, list) {
+   size = sizeof(*src);
+   dst = malloc(size);
+   if (!dst) {
+   ret = -ENOMEM;
+   goto cleanup;
+   }
+   memcpy(dst, src, size);
+   list_add_tail(>list, >unaligned_extent_recs);
+   }
+
ret = copy_file_extent_holes(>holes, _rec->holes);
if (ret < 0)
goto cleanup_rb;
@@ -506,6 +520,13 @@ cleanup:
free(orig);
}
 
+   if (!list_empty(>unaligned_extent_recs))
+   list_for_each_entry_safe(src, dst, >unaligned_extent_recs,
+   list) {
+   list_del(>list);
+   free(src);
+   }
+
free(rec);
 
return ERR_PTR(ret);
@@ -643,6 +664,7 @@ static struct inode_record *get_inode_rec(struct cache_tree 
*inode_cache,
rec->extent_start = (u64)-1;
rec->refs = 1;
INIT_LIST_HEAD(>backrefs);
+   INIT_LIST_HEAD(>unaligned_extent_recs);
rec->holes = RB_ROOT;
 
node = malloc(sizeof(*node));
@@ -664,6 +686,18 @@ static struct inode_record *get_inode_rec(struct 
cache_tree *inode_cache,
return rec;
 }
 
+static void free_unaligned_extent_recs(struct list_head *unaligned_extent_recs)
+{
+   struct unaligned_extent_rec_t *urec;
+
+   while (!list_empty(unaligned_extent_recs)) {
+   urec = list_entry(unaligned_extent_recs->next,
+   struct unaligned_extent_rec_t, list);
+   list_del(>list);
+   free(urec);
+   }
+}
+
 static void free_inode_rec(struct inode_record *rec)
 {
struct inode_backref *backref;
@@ -676,6 +710,7 @@ static void free_inode_rec(struct inode_record *rec)
list_del(>list);
free(backref);
}
+   free_unaligned_extent_recs(>unaligned_extent_recs);
free_file_extent_holes(>holes);
free(rec);
 }
@@ -2474,18 +2509,154 @@ out:
return ret;
 }
 
+static int btrfs_delete_item(struct btrfs_trans_handle *trans,
+   struct btrfs_root *root, struct btrfs_key *key)
+{
+   struct btrfs_path path;
+   int ret = 0;
+
+   btrfs_init_path();
+
+   ret = btrfs_search_slot(trans, root, key, , -1, 1);
+   if (ret) {
+   if (ret > 0)
+   ret = -ENOENT;
+
+   btrfs_release_path();
+   return ret;
+   }
+
+   ret = btrfs_del_item(trans, root, );
+
+   btrfs_release_path();
+   return ret;
+}
+
+static int find_file_extent_offset_by_bytenr(struct btrfs_root *root,
+   u64 owner, u64 bytenr, u64 *offset_ret)
+{
+   int ret = 0;
+   struct btrfs_path path;
+   struct btrfs_key key;
+   struct btrfs_key found_key;
+   struct btrfs_file_extent_item *fi;
+   struct extent_buffer *leaf;
+   u64 disk_bytenr;
+   int slot;
+
+   btrfs_init_path();
+
+   key.objectid = owner;
+   key.type = BTRFS_INODE_ITEM_KEY;
+   key.offset = 0;
+
+   ret = btrfs_search_slot(NULL, root, , , 0, 0);
+   if (ret) {
+   if (ret > 0)
+   ret = -ENOENT;
+   btrfs_release_path();
+   return ret;
+   }
+
+   btrfs_release_path();
+
+   key.objectid = owner;
+   key.type = BTRFS_EXTENT_DATA_KEY;
+