aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2009-11-12 04:34:40 -0500
committerChris Mason <chris.mason@oracle.com>2009-12-17 12:33:33 -0500
commitc71bf099abddf3e0fdc27f251ba76fca1461d49a (patch)
tree0b682ad2b49aeaf9ac774c40be4b7549c1d079fe /fs/btrfs/inode.c
parentc216775458a2ee345d9412a2770c2916acfb5d30 (diff)
Btrfs: Avoid orphan inodes cleanup while replaying log
We do log replay in a single transaction, so it's not good to do unbound operations. This patch cleans up orphan inodes cleanup after replaying the log. It also avoids doing other unbound operations such as truncating a file during replaying log. These unbound operations are postponed to the orphan inode cleanup stage. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c19
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