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>
This commit is contained in:
@ -2093,16 +2093,17 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
|
||||
struct inode *inode;
|
||||
int ret = 0, nr_unlink = 0, nr_truncate = 0;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
if (!xchg(&root->clean_orphans, 0))
|
||||
return;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
BUG_ON(!path);
|
||||
path->reada = -1;
|
||||
|
||||
key.objectid = BTRFS_ORPHAN_OBJECTID;
|
||||
btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY);
|
||||
key.offset = (u64)-1;
|
||||
|
||||
|
||||
while (1) {
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0) {
|
||||
@ -3298,6 +3299,11 @@ void btrfs_delete_inode(struct inode *inode)
|
||||
}
|
||||
btrfs_wait_ordered_range(inode, 0, (u64)-1);
|
||||
|
||||
if (root->fs_info->log_root_recovering) {
|
||||
BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan));
|
||||
goto no_delete;
|
||||
}
|
||||
|
||||
if (inode->i_nlink > 0) {
|
||||
BUG_ON(btrfs_root_refs(&root->root_item) != 0);
|
||||
goto no_delete;
|
||||
@ -3705,6 +3711,13 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
|
||||
}
|
||||
srcu_read_unlock(&root->fs_info->subvol_srcu, index);
|
||||
|
||||
if (root != sub_root) {
|
||||
down_read(&root->fs_info->cleanup_work_sem);
|
||||
if (!(inode->i_sb->s_flags & MS_RDONLY))
|
||||
btrfs_orphan_cleanup(sub_root);
|
||||
up_read(&root->fs_info->cleanup_work_sem);
|
||||
}
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user