diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fa57247887e3..eb2db3bde236 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2093,16 +2093,17 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) | |||
2093 | struct inode *inode; | 2093 | struct inode *inode; |
2094 | int ret = 0, nr_unlink = 0, nr_truncate = 0; | 2094 | int ret = 0, nr_unlink = 0, nr_truncate = 0; |
2095 | 2095 | ||
2096 | path = btrfs_alloc_path(); | 2096 | if (!xchg(&root->clean_orphans, 0)) |
2097 | if (!path) | ||
2098 | return; | 2097 | return; |
2098 | |||
2099 | path = btrfs_alloc_path(); | ||
2100 | BUG_ON(!path); | ||
2099 | path->reada = -1; | 2101 | path->reada = -1; |
2100 | 2102 | ||
2101 | key.objectid = BTRFS_ORPHAN_OBJECTID; | 2103 | key.objectid = BTRFS_ORPHAN_OBJECTID; |
2102 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); | 2104 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); |
2103 | key.offset = (u64)-1; | 2105 | key.offset = (u64)-1; |
2104 | 2106 | ||
2105 | |||
2106 | while (1) { | 2107 | while (1) { |
2107 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 2108 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
2108 | if (ret < 0) { | 2109 | if (ret < 0) { |
@@ -3298,6 +3299,11 @@ void btrfs_delete_inode(struct inode *inode) | |||
3298 | } | 3299 | } |
3299 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 3300 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
3300 | 3301 | ||
3302 | if (root->fs_info->log_root_recovering) { | ||
3303 | BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan)); | ||
3304 | goto no_delete; | ||
3305 | } | ||
3306 | |||
3301 | if (inode->i_nlink > 0) { | 3307 | if (inode->i_nlink > 0) { |
3302 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); | 3308 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); |
3303 | goto no_delete; | 3309 | goto no_delete; |
@@ -3705,6 +3711,13 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
3705 | } | 3711 | } |
3706 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); | 3712 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); |
3707 | 3713 | ||
3714 | if (root != sub_root) { | ||
3715 | down_read(&root->fs_info->cleanup_work_sem); | ||
3716 | if (!(inode->i_sb->s_flags & MS_RDONLY)) | ||
3717 | btrfs_orphan_cleanup(sub_root); | ||
3718 | up_read(&root->fs_info->cleanup_work_sem); | ||
3719 | } | ||
3720 | |||
3708 | return inode; | 3721 | return inode; |
3709 | } | 3722 | } |
3710 | 3723 | ||