|
@@ -1302,40 +1302,42 @@ static void btrfs_async_run_delayed_root(struct btrfs_work *work)
|
|
if (!path)
|
|
if (!path)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
-again:
|
|
|
|
- if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND / 2)
|
|
|
|
- goto free_path;
|
|
|
|
|
|
+ do {
|
|
|
|
+ if (atomic_read(&delayed_root->items) <
|
|
|
|
+ BTRFS_DELAYED_BACKGROUND / 2)
|
|
|
|
+ break;
|
|
|
|
|
|
- delayed_node = btrfs_first_prepared_delayed_node(delayed_root);
|
|
|
|
- if (!delayed_node)
|
|
|
|
- goto free_path;
|
|
|
|
|
|
+ delayed_node = btrfs_first_prepared_delayed_node(delayed_root);
|
|
|
|
+ if (!delayed_node)
|
|
|
|
+ break;
|
|
|
|
|
|
- path->leave_spinning = 1;
|
|
|
|
- root = delayed_node->root;
|
|
|
|
|
|
+ path->leave_spinning = 1;
|
|
|
|
+ root = delayed_node->root;
|
|
|
|
|
|
- trans = btrfs_join_transaction(root);
|
|
|
|
- if (IS_ERR(trans))
|
|
|
|
- goto release_path;
|
|
|
|
|
|
+ trans = btrfs_join_transaction(root);
|
|
|
|
+ if (IS_ERR(trans)) {
|
|
|
|
+ btrfs_release_path(path);
|
|
|
|
+ btrfs_release_prepared_delayed_node(delayed_node);
|
|
|
|
+ total_done++;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- block_rsv = trans->block_rsv;
|
|
|
|
- trans->block_rsv = &root->fs_info->delayed_block_rsv;
|
|
|
|
|
|
+ block_rsv = trans->block_rsv;
|
|
|
|
+ trans->block_rsv = &root->fs_info->delayed_block_rsv;
|
|
|
|
|
|
- __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
|
|
|
|
|
|
+ __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
|
|
|
|
|
|
- trans->block_rsv = block_rsv;
|
|
|
|
- btrfs_end_transaction(trans);
|
|
|
|
- btrfs_btree_balance_dirty_nodelay(root->fs_info);
|
|
|
|
|
|
+ trans->block_rsv = block_rsv;
|
|
|
|
+ btrfs_end_transaction(trans);
|
|
|
|
+ btrfs_btree_balance_dirty_nodelay(root->fs_info);
|
|
|
|
|
|
-release_path:
|
|
|
|
- btrfs_release_path(path);
|
|
|
|
- total_done++;
|
|
|
|
|
|
+ btrfs_release_path(path);
|
|
|
|
+ btrfs_release_prepared_delayed_node(delayed_node);
|
|
|
|
+ total_done++;
|
|
|
|
|
|
- btrfs_release_prepared_delayed_node(delayed_node);
|
|
|
|
- if ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK) ||
|
|
|
|
- total_done < async_work->nr)
|
|
|
|
- goto again;
|
|
|
|
|
|
+ } while ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK)
|
|
|
|
+ || total_done < async_work->nr);
|
|
|
|
|
|
-free_path:
|
|
|
|
btrfs_free_path(path);
|
|
btrfs_free_path(path);
|
|
out:
|
|
out:
|
|
wake_up(&delayed_root->wait);
|
|
wake_up(&delayed_root->wait);
|