linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Btrfs: eliminate the exceptional root_tree refs=0
@ 2013-09-05 14:58 Stefan Behrens
  2013-09-06  3:08 ` Miao Xie
  0 siblings, 1 reply; 4+ messages in thread
From: Stefan Behrens @ 2013-09-05 14:58 UTC (permalink / raw)
  To: linux-btrfs

The fact that btrfs_root_refs() returned 0 for the tree_root caused
bugs in the past, therefore it is set to 1 with this patch and
(hopefully) all affected code is adapted to this change.

I verified this change by temporarily adding WARN_ON() checks
everywhere where btrfs_root_refs() is used, checking whether the
logic of the code is changed by btrfs_root_refs() returning 1
instead of 0 for root->root_key.objectid == BTRFS_ROOT_TREE_OBJECTID.
With these added checks, I ran the xfstests './check -g auto'.

The two roots chunk_root and log_root_tree that are only referenced
by the superblock and the log_roots below the log_root_tree still
have btrfs_root_refs() == 0, only the tree_root is changed.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 fs/btrfs/disk-io.c   |  1 +
 fs/btrfs/inode-map.c |  3 +--
 fs/btrfs/inode.c     | 21 ++++++++-------------
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index fa8b2c6..ffc3e43 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2667,6 +2667,7 @@ retry_root_backup:
 
 	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
 	tree_root->commit_root = btrfs_root_node(tree_root);
+	btrfs_set_root_refs(&tree_root->root_item, 1);
 
 	location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
 	location.type = BTRFS_ROOT_ITEM_KEY;
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 2c66ddb..d11e1c6 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -412,8 +412,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
 		return 0;
 
 	/* Don't save inode cache if we are deleting this root */
-	if (btrfs_root_refs(&root->root_item) == 0 &&
-	    root != root->fs_info->tree_root)
+	if (btrfs_root_refs(&root->root_item) == 0)
 		return 0;
 
 	if (!btrfs_test_opt(root, INODE_MAP_CACHE))
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 26992ee..7d0ef55 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4472,8 +4472,10 @@ void btrfs_evict_inode(struct inode *inode)
 	trace_btrfs_inode_evict(inode);
 
 	truncate_inode_pages(&inode->i_data, 0);
-	if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
-			       btrfs_is_free_space_inode(inode)))
+	if (inode->i_nlink &&
+	    ((btrfs_root_refs(&root->root_item) != 0 &&
+	      root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) ||
+	     btrfs_is_free_space_inode(inode)))
 		goto no_delete;
 
 	if (is_bad_inode(inode)) {
@@ -4490,7 +4492,8 @@ void btrfs_evict_inode(struct inode *inode)
 	}
 
 	if (inode->i_nlink > 0) {
-		BUG_ON(btrfs_root_refs(&root->root_item) != 0);
+		BUG_ON(btrfs_root_refs(&root->root_item) != 0 &&
+		       root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID);
 		goto no_delete;
 	}
 
@@ -4731,14 +4734,7 @@ static void inode_tree_del(struct inode *inode)
 	}
 	spin_unlock(&root->inode_lock);
 
-	/*
-	 * Free space cache has inodes in the tree root, but the tree root has a
-	 * root_refs of 0, so this could end up dropping the tree root as a
-	 * snapshot, so we need the extra !root->fs_info->tree_root check to
-	 * make sure we don't drop it.
-	 */
-	if (empty && btrfs_root_refs(&root->root_item) == 0 &&
-	    root != root->fs_info->tree_root) {
+	if (empty && btrfs_root_refs(&root->root_item) == 0) {
 		synchronize_srcu(&root->fs_info->subvol_srcu);
 		spin_lock(&root->inode_lock);
 		empty = RB_EMPTY_ROOT(&root->inode_tree);
@@ -7872,8 +7868,7 @@ int btrfs_drop_inode(struct inode *inode)
 		return 1;
 
 	/* the snap/subvol tree is on deleting */
-	if (btrfs_root_refs(&root->root_item) == 0 &&
-	    root != root->fs_info->tree_root)
+	if (btrfs_root_refs(&root->root_item) == 0)
 		return 1;
 	else
 		return generic_drop_inode(inode);
-- 
1.8.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Btrfs: eliminate the exceptional root_tree refs=0
  2013-09-05 14:58 [PATCH] Btrfs: eliminate the exceptional root_tree refs=0 Stefan Behrens
@ 2013-09-06  3:08 ` Miao Xie
  2013-09-06  8:36   ` Stefan Behrens
  0 siblings, 1 reply; 4+ messages in thread
From: Miao Xie @ 2013-09-06  3:08 UTC (permalink / raw)
  To: Stefan Behrens; +Cc: linux-btrfs

On 	thu, 5 Sep 2013 16:58:43 +0200, Stefan Behrens wrote:
> The fact that btrfs_root_refs() returned 0 for the tree_root caused
> bugs in the past, therefore it is set to 1 with this patch and
> (hopefully) all affected code is adapted to this change.
> 
> I verified this change by temporarily adding WARN_ON() checks
> everywhere where btrfs_root_refs() is used, checking whether the
> logic of the code is changed by btrfs_root_refs() returning 1
> instead of 0 for root->root_key.objectid == BTRFS_ROOT_TREE_OBJECTID.
> With these added checks, I ran the xfstests './check -g auto'.
> 
> The two roots chunk_root and log_root_tree that are only referenced
> by the superblock and the log_roots below the log_root_tree still
> have btrfs_root_refs() == 0, only the tree_root is changed.
> 
> Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
> ---
>  fs/btrfs/disk-io.c   |  1 +
>  fs/btrfs/inode-map.c |  3 +--
>  fs/btrfs/inode.c     | 21 ++++++++-------------
>  3 files changed, 10 insertions(+), 15 deletions(-)
> 
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index fa8b2c6..ffc3e43 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -2667,6 +2667,7 @@ retry_root_backup:
>  
>  	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
>  	tree_root->commit_root = btrfs_root_node(tree_root);
> +	btrfs_set_root_refs(&tree_root->root_item, 1);
>  
>  	location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
>  	location.type = BTRFS_ROOT_ITEM_KEY;
> diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
> index 2c66ddb..d11e1c6 100644
> --- a/fs/btrfs/inode-map.c
> +++ b/fs/btrfs/inode-map.c
> @@ -412,8 +412,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
>  		return 0;
>  
>  	/* Don't save inode cache if we are deleting this root */
> -	if (btrfs_root_refs(&root->root_item) == 0 &&
> -	    root != root->fs_info->tree_root)
> +	if (btrfs_root_refs(&root->root_item) == 0)
>  		return 0;
>  
>  	if (!btrfs_test_opt(root, INODE_MAP_CACHE))
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 26992ee..7d0ef55 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -4472,8 +4472,10 @@ void btrfs_evict_inode(struct inode *inode)
>  	trace_btrfs_inode_evict(inode);
>  
>  	truncate_inode_pages(&inode->i_data, 0);
> -	if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
> -			       btrfs_is_free_space_inode(inode)))
> +	if (inode->i_nlink &&
> +	    ((btrfs_root_refs(&root->root_item) != 0 &&
> +	      root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) ||
> +	     btrfs_is_free_space_inode(inode)))

if (inode->i_nlink && btrfs_root_refs(&root->root_item)) {
}

is OK, because with this patch, the refs of the free space inodes' root(tree root)
should be 1. For the ino cache inodes' root(fs/file root), if the root is dead,
we can drop the ino cache inode safely. And if the root is not dead, the refs
should be > 0, we will skip the drop.

>  		goto no_delete;
>  
>  	if (is_bad_inode(inode)) {
> @@ -4490,7 +4492,8 @@ void btrfs_evict_inode(struct inode *inode)
>  	}
>  
>  	if (inode->i_nlink > 0) {
> -		BUG_ON(btrfs_root_refs(&root->root_item) != 0);
> +		BUG_ON(btrfs_root_refs(&root->root_item) != 0 &&
> +		       root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID);

This change is unnecessary because the refs of the root tree is 1 now.

>  		goto no_delete;
>  	}
>  
> @@ -4731,14 +4734,7 @@ static void inode_tree_del(struct inode *inode)
>  	}
>  	spin_unlock(&root->inode_lock);
>  
> -	/*
> -	 * Free space cache has inodes in the tree root, but the tree root has a
> -	 * root_refs of 0, so this could end up dropping the tree root as a
> -	 * snapshot, so we need the extra !root->fs_info->tree_root check to
> -	 * make sure we don't drop it.
> -	 */
> -	if (empty && btrfs_root_refs(&root->root_item) == 0 &&
> -	    root != root->fs_info->tree_root) {
> +	if (empty && btrfs_root_refs(&root->root_item) == 0) {
>  		synchronize_srcu(&root->fs_info->subvol_srcu);
>  		spin_lock(&root->inode_lock);
>  		empty = RB_EMPTY_ROOT(&root->inode_tree);
> @@ -7872,8 +7868,7 @@ int btrfs_drop_inode(struct inode *inode)
>  		return 1;
>  
>  	/* the snap/subvol tree is on deleting */
> -	if (btrfs_root_refs(&root->root_item) == 0 &&
> -	    root != root->fs_info->tree_root)
> +	if (btrfs_root_refs(&root->root_item) == 0)
>  		return 1;
>  	else
>  		return generic_drop_inode(inode);

The others is OK.

Thanks
Miao

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Btrfs: eliminate the exceptional root_tree refs=0
  2013-09-06  3:08 ` Miao Xie
@ 2013-09-06  8:36   ` Stefan Behrens
  2013-09-09 10:10     ` Miao Xie
  0 siblings, 1 reply; 4+ messages in thread
From: Stefan Behrens @ 2013-09-06  8:36 UTC (permalink / raw)
  To: miaox; +Cc: linux-btrfs

On Fri, 06 Sep 2013 11:08:16 +0800, Miao Xie wrote:
> On 	thu, 5 Sep 2013 16:58:43 +0200, Stefan Behrens wrote:
>> The fact that btrfs_root_refs() returned 0 for the tree_root caused
>> bugs in the past, therefore it is set to 1 with this patch and
>> (hopefully) all affected code is adapted to this change.
>>
>> I verified this change by temporarily adding WARN_ON() checks
>> everywhere where btrfs_root_refs() is used, checking whether the
>> logic of the code is changed by btrfs_root_refs() returning 1
>> instead of 0 for root->root_key.objectid == BTRFS_ROOT_TREE_OBJECTID.
>> With these added checks, I ran the xfstests './check -g auto'.
>>
>> The two roots chunk_root and log_root_tree that are only referenced
>> by the superblock and the log_roots below the log_root_tree still
>> have btrfs_root_refs() == 0, only the tree_root is changed.
>>
>> Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
>> ---
>>  fs/btrfs/disk-io.c   |  1 +
>>  fs/btrfs/inode-map.c |  3 +--
>>  fs/btrfs/inode.c     | 21 ++++++++-------------
>>  3 files changed, 10 insertions(+), 15 deletions(-)
>>
>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
>> index fa8b2c6..ffc3e43 100644
>> --- a/fs/btrfs/disk-io.c
>> +++ b/fs/btrfs/disk-io.c
>> @@ -2667,6 +2667,7 @@ retry_root_backup:
>>  
>>  	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
>>  	tree_root->commit_root = btrfs_root_node(tree_root);
>> +	btrfs_set_root_refs(&tree_root->root_item, 1);
>>  
>>  	location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
>>  	location.type = BTRFS_ROOT_ITEM_KEY;
>> diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
>> index 2c66ddb..d11e1c6 100644
>> --- a/fs/btrfs/inode-map.c
>> +++ b/fs/btrfs/inode-map.c
>> @@ -412,8 +412,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
>>  		return 0;
>>  
>>  	/* Don't save inode cache if we are deleting this root */
>> -	if (btrfs_root_refs(&root->root_item) == 0 &&
>> -	    root != root->fs_info->tree_root)
>> +	if (btrfs_root_refs(&root->root_item) == 0)
>>  		return 0;
>>  
>>  	if (!btrfs_test_opt(root, INODE_MAP_CACHE))
>> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
>> index 26992ee..7d0ef55 100644
>> --- a/fs/btrfs/inode.c
>> +++ b/fs/btrfs/inode.c
>> @@ -4472,8 +4472,10 @@ void btrfs_evict_inode(struct inode *inode)
>>  	trace_btrfs_inode_evict(inode);
>>  
>>  	truncate_inode_pages(&inode->i_data, 0);
>> -	if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
>> -			       btrfs_is_free_space_inode(inode)))
>> +	if (inode->i_nlink &&
>> +	    ((btrfs_root_refs(&root->root_item) != 0 &&
>> +	      root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) ||
>> +	     btrfs_is_free_space_inode(inode)))
> 
> if (inode->i_nlink && btrfs_root_refs(&root->root_item)) {
> }
> 
> is OK, because with this patch, the refs of the free space inodes' root(tree root)
> should be 1. For the ino cache inodes' root(fs/file root), if the root is dead,
> we can drop the ino cache inode safely. And if the root is not dead, the refs
> should be > 0, we will skip the drop.

Thank you for your comments!

It needs to be like this or it doesn't work. The code that you propose
changes the logic when close_ctree() calls iput(fs_info->btree_inode).
The if-condition in btrfs_evict_inode() used to be false for
fs_info->btree_inode before this patch and would become true. And the
system locks up in the middle of a './check -g auto' run with page cache
issues and I have also seen the OOM killer killing the entire test box.

But maybe you can propose how to make this if-statement more explicit
and readable, maybe by explicitly checking for inode ==
fs_info->btree_inode?


>>  		goto no_delete;
>>  
>>  	if (is_bad_inode(inode)) {
>> @@ -4490,7 +4492,8 @@ void btrfs_evict_inode(struct inode *inode)
>>  	}
>>  
>>  	if (inode->i_nlink > 0) {
>> -		BUG_ON(btrfs_root_refs(&root->root_item) != 0);
>> +		BUG_ON(btrfs_root_refs(&root->root_item) != 0 &&
>> +		       root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID);
> 
> This change is unnecessary because the refs of the root tree is 1 now.

Because of the thing above, this is needed.


> 
>>  		goto no_delete;
>>  	}
>>  
>> @@ -4731,14 +4734,7 @@ static void inode_tree_del(struct inode *inode)
>>  	}
>>  	spin_unlock(&root->inode_lock);
>>  
>> -	/*
>> -	 * Free space cache has inodes in the tree root, but the tree root has a
>> -	 * root_refs of 0, so this could end up dropping the tree root as a
>> -	 * snapshot, so we need the extra !root->fs_info->tree_root check to
>> -	 * make sure we don't drop it.
>> -	 */
>> -	if (empty && btrfs_root_refs(&root->root_item) == 0 &&
>> -	    root != root->fs_info->tree_root) {
>> +	if (empty && btrfs_root_refs(&root->root_item) == 0) {
>>  		synchronize_srcu(&root->fs_info->subvol_srcu);
>>  		spin_lock(&root->inode_lock);
>>  		empty = RB_EMPTY_ROOT(&root->inode_tree);
>> @@ -7872,8 +7868,7 @@ int btrfs_drop_inode(struct inode *inode)
>>  		return 1;
>>  
>>  	/* the snap/subvol tree is on deleting */
>> -	if (btrfs_root_refs(&root->root_item) == 0 &&
>> -	    root != root->fs_info->tree_root)
>> +	if (btrfs_root_refs(&root->root_item) == 0)
>>  		return 1;
>>  	else
>>  		return generic_drop_inode(inode);
> 
> The others is OK.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Btrfs: eliminate the exceptional root_tree refs=0
  2013-09-06  8:36   ` Stefan Behrens
@ 2013-09-09 10:10     ` Miao Xie
  0 siblings, 0 replies; 4+ messages in thread
From: Miao Xie @ 2013-09-09 10:10 UTC (permalink / raw)
  To: Stefan Behrens; +Cc: linux-btrfs

On Fri, 06 Sep 2013 10:36:48 +0200, Stefan Behrens wrote:
> On Fri, 06 Sep 2013 11:08:16 +0800, Miao Xie wrote:
>> On 	thu, 5 Sep 2013 16:58:43 +0200, Stefan Behrens wrote:
>>> The fact that btrfs_root_refs() returned 0 for the tree_root caused
>>> bugs in the past, therefore it is set to 1 with this patch and
>>> (hopefully) all affected code is adapted to this change.
>>>
>>> I verified this change by temporarily adding WARN_ON() checks
>>> everywhere where btrfs_root_refs() is used, checking whether the
>>> logic of the code is changed by btrfs_root_refs() returning 1
>>> instead of 0 for root->root_key.objectid == BTRFS_ROOT_TREE_OBJECTID.
>>> With these added checks, I ran the xfstests './check -g auto'.
>>>
>>> The two roots chunk_root and log_root_tree that are only referenced
>>> by the superblock and the log_roots below the log_root_tree still
>>> have btrfs_root_refs() == 0, only the tree_root is changed.
>>>
>>> Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
>>> ---
>>>  fs/btrfs/disk-io.c   |  1 +
>>>  fs/btrfs/inode-map.c |  3 +--
>>>  fs/btrfs/inode.c     | 21 ++++++++-------------
>>>  3 files changed, 10 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
>>> index fa8b2c6..ffc3e43 100644
>>> --- a/fs/btrfs/disk-io.c
>>> +++ b/fs/btrfs/disk-io.c
>>> @@ -2667,6 +2667,7 @@ retry_root_backup:
>>>  
>>>  	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
>>>  	tree_root->commit_root = btrfs_root_node(tree_root);
>>> +	btrfs_set_root_refs(&tree_root->root_item, 1);
>>>  
>>>  	location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
>>>  	location.type = BTRFS_ROOT_ITEM_KEY;
>>> diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
>>> index 2c66ddb..d11e1c6 100644
>>> --- a/fs/btrfs/inode-map.c
>>> +++ b/fs/btrfs/inode-map.c
>>> @@ -412,8 +412,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
>>>  		return 0;
>>>  
>>>  	/* Don't save inode cache if we are deleting this root */
>>> -	if (btrfs_root_refs(&root->root_item) == 0 &&
>>> -	    root != root->fs_info->tree_root)
>>> +	if (btrfs_root_refs(&root->root_item) == 0)
>>>  		return 0;
>>>  
>>>  	if (!btrfs_test_opt(root, INODE_MAP_CACHE))
>>> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
>>> index 26992ee..7d0ef55 100644
>>> --- a/fs/btrfs/inode.c
>>> +++ b/fs/btrfs/inode.c
>>> @@ -4472,8 +4472,10 @@ void btrfs_evict_inode(struct inode *inode)
>>>  	trace_btrfs_inode_evict(inode);
>>>  
>>>  	truncate_inode_pages(&inode->i_data, 0);
>>> -	if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
>>> -			       btrfs_is_free_space_inode(inode)))
>>> +	if (inode->i_nlink &&
>>> +	    ((btrfs_root_refs(&root->root_item) != 0 &&
>>> +	      root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) ||
>>> +	     btrfs_is_free_space_inode(inode)))
>>
>> if (inode->i_nlink && btrfs_root_refs(&root->root_item)) {
>> }
>>
>> is OK, because with this patch, the refs of the free space inodes' root(tree root)
>> should be 1. For the ino cache inodes' root(fs/file root), if the root is dead,
>> we can drop the ino cache inode safely. And if the root is not dead, the refs
>> should be > 0, we will skip the drop.
> 
> Thank you for your comments!
> 
> It needs to be like this or it doesn't work. The code that you propose
> changes the logic when close_ctree() calls iput(fs_info->btree_inode).
> The if-condition in btrfs_evict_inode() used to be false for
> fs_info->btree_inode before this patch and would become true. And the
> system locks up in the middle of a './check -g auto' run with page cache
> issues and I have also seen the OOM killer killing the entire test box.

It is strange, AFAIK, it is safe that the first if-condition in btrfs_evict_inode()
become true, and jump to no_delete, because we make sure we have synced all dirty pages
in btree inode into the disk and we are also sure we needn't remove the inode item in
the tree root. I think the bug you met was not introduced be the code I proposed.

Thanks
Miao

> 
> But maybe you can propose how to make this if-statement more explicit
> and readable, maybe by explicitly checking for inode ==
> fs_info->btree_inode?
> 
> 
>>>  		goto no_delete;
>>>  
>>>  	if (is_bad_inode(inode)) {
>>> @@ -4490,7 +4492,8 @@ void btrfs_evict_inode(struct inode *inode)
>>>  	}
>>>  
>>>  	if (inode->i_nlink > 0) {
>>> -		BUG_ON(btrfs_root_refs(&root->root_item) != 0);
>>> +		BUG_ON(btrfs_root_refs(&root->root_item) != 0 &&
>>> +		       root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID);
>>
>> This change is unnecessary because the refs of the root tree is 1 now.
> 
> Because of the thing above, this is needed.
> 
> 
>>
>>>  		goto no_delete;
>>>  	}
>>>  
>>> @@ -4731,14 +4734,7 @@ static void inode_tree_del(struct inode *inode)
>>>  	}
>>>  	spin_unlock(&root->inode_lock);
>>>  
>>> -	/*
>>> -	 * Free space cache has inodes in the tree root, but the tree root has a
>>> -	 * root_refs of 0, so this could end up dropping the tree root as a
>>> -	 * snapshot, so we need the extra !root->fs_info->tree_root check to
>>> -	 * make sure we don't drop it.
>>> -	 */
>>> -	if (empty && btrfs_root_refs(&root->root_item) == 0 &&
>>> -	    root != root->fs_info->tree_root) {
>>> +	if (empty && btrfs_root_refs(&root->root_item) == 0) {
>>>  		synchronize_srcu(&root->fs_info->subvol_srcu);
>>>  		spin_lock(&root->inode_lock);
>>>  		empty = RB_EMPTY_ROOT(&root->inode_tree);
>>> @@ -7872,8 +7868,7 @@ int btrfs_drop_inode(struct inode *inode)
>>>  		return 1;
>>>  
>>>  	/* the snap/subvol tree is on deleting */
>>> -	if (btrfs_root_refs(&root->root_item) == 0 &&
>>> -	    root != root->fs_info->tree_root)
>>> +	if (btrfs_root_refs(&root->root_item) == 0)
>>>  		return 1;
>>>  	else
>>>  		return generic_drop_inode(inode);
>>
>> The others is OK.
> 
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-09-09 10:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-05 14:58 [PATCH] Btrfs: eliminate the exceptional root_tree refs=0 Stefan Behrens
2013-09-06  3:08 ` Miao Xie
2013-09-06  8:36   ` Stefan Behrens
2013-09-09 10:10     ` Miao Xie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).