Browse Source

Btrfs: remove negative dentry when deleting subvolumne

The use of btrfs_dentry_delete is removing dentries from the
dcache when deleting subvolumne. btrfs_dentry_delete ignores
negative dentries. This is incorrect since if we don't remove
the negative dentry, its parent dentry can't be removed.

Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Yan, Zheng 15 years ago
parent
commit
efefb1438b
2 changed files with 8 additions and 5 deletions
  1. 7 5
      fs/btrfs/inode.c
  2. 1 0
      fs/btrfs/ioctl.c

+ 7 - 5
fs/btrfs/inode.c

@@ -3629,12 +3629,14 @@ static int btrfs_dentry_delete(struct dentry *dentry)
 {
 {
 	struct btrfs_root *root;
 	struct btrfs_root *root;
 
 
-	if (!dentry->d_inode)
-		return 0;
+	if (!dentry->d_inode && !IS_ROOT(dentry))
+		dentry = dentry->d_parent;
 
 
-	root = BTRFS_I(dentry->d_inode)->root;
-	if (btrfs_root_refs(&root->root_item) == 0)
-		return 1;
+	if (dentry->d_inode) {
+		root = BTRFS_I(dentry->d_inode)->root;
+		if (btrfs_root_refs(&root->root_item) == 0)
+			return 1;
+	}
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
fs/btrfs/ioctl.c

@@ -830,6 +830,7 @@ out_up_write:
 out_unlock:
 out_unlock:
 	mutex_unlock(&inode->i_mutex);
 	mutex_unlock(&inode->i_mutex);
 	if (!err) {
 	if (!err) {
+		shrink_dcache_sb(root->fs_info->sb);
 		btrfs_invalidate_inodes(dest);
 		btrfs_invalidate_inodes(dest);
 		d_delete(dentry);
 		d_delete(dentry);
 	}
 	}