/* * defrag a given btree. If cacheonly == 1, this won't read from the disk, * otherwise every leaf in the btree is read and defragged. */ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) { struct btrfs_fs_info *info = root->fs_info; int ret; struct btrfs_trans_handle *trans; unsigned long nr; smp_mb(); if (root->defrag_running) return 0; trans = btrfs_start_transaction(root, 1); while (1) { root->defrag_running = 1; ret = btrfs_defrag_leaves(trans, root, cacheonly); nr = trans->blocks_used; btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(info->tree_root, nr); cond_resched(); trans = btrfs_start_transaction(root, 1); if (root->fs_info->closing || ret != -EAGAIN) break; } root->defrag_running = 0; smp_mb(); btrfs_end_transaction(trans, root); return 0; }
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) { struct btrfs_fs_info *info = root->fs_info; struct btrfs_trans_handle *trans; int ret; unsigned long nr; if (xchg(&root->defrag_running, 1)) return 0; while (1) { trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) return PTR_ERR(trans); ret = btrfs_defrag_leaves(trans, root, cacheonly); nr = trans->blocks_used; btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(info->tree_root, nr); cond_resched(); if (root->fs_info->closing || ret != -EAGAIN) break; } root->defrag_running = 0; return ret; }