Btrfs: Metadata ENOSPC handling for balance
PATCH v2 12/12 Btrfs: Metadata ENOSPC handling for balance
This patch adds metadata ENOSPC handling for the balance code. It is consisted by following major changes:
1. Avoid COW tree leave in the phrase of merging tree.
2. Handle interaction with snapshot creation.
3. make the backref cache can continue in existence cross transactions.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.c +3 -0
@@ -446,6 +446,9 @@ static noinline int __btrfs_cow_block(stupdate_ref_for_cow (trans, root, buf, cow, &last_ref); +if (root->ref_cows) +btrfs_reloc_cow_block (trans, root, buf, cow); +if (buf == root->node) {WARN_ON (parent && parent != buf); if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
fs/btrfs/ctree.h +10 -1
@@ -2204,7 +2204,8 @@ static inline int btrfs_insert_empty_iteint btrfs_next_leaf (struct btrfs_root *root,struct btrfs_path *path);int btrfs_prev_leaf (struct btrfs_root *root,struct btrfs_path *path);int btrfs_leaf_free_space (struct btrfs_root *root,struct extent_buffer *leaf); -int btrfs_drop_snapshot (struct btrfs_root *root,int update_ref); +int btrfs_drop_snapshot (struct btrfs_root *root, +struct btrfs_block_rsv *block_rsv,int update_ref); int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *node,
@@ -2478,4 +2479,12 @@ int btrfs_update_reloc_root(struct btrfs struct btrfs_root *root);int btrfs_recover_relocation (struct btrfs_root *root);int btrfs_reloc_clone_csums (struct inode *inode,u64 file_pos,u64 len); +void btrfs_reloc_cow_block (struct btrfs_trans_handle *trans, +struct btrfs_root *root,struct extent_buffer *buf, +struct extent_buffer *cow); +void btrfs_reloc_pre_snapshot (struct btrfs_trans_handle *trans, +struct btrfs_pending_snapshot *pending, +u64 *bytes_to_reserve); +void btrfs_reloc_post_snapshot (struct btrfs_trans_handle *trans, +struct btrfs_pending_snapshot *pending);#endif
fs/btrfs/extent-tree.c +9 -14
@@ -5874,7 +5874,8 @@ static noinline int walk_up_tree(struct* also make sure backrefs for the shared block and all lower level * blocks are properly updated. */ -int btrfs_drop_snapshot (struct btrfs_root *root,int update_ref) +int btrfs_drop_snapshot (struct btrfs_root *root, +struct btrfs_block_rsv *block_rsv,int update_ref) {struct btrfs_path *path;struct btrfs_trans_handle *trans;
@@ -5893,6 +5894,8 @@ int btrfs_drop_snapshot(struct btrfs_rooBUG_ON (!wc); trans =btrfs_start_transaction (tree_root,0 ); +if (block_rsv) + trans->block_rsv = block_rsv;if (btrfs_disk_key_objectid (&root_item->drop_progress) ==0 ) { level =btrfs_header_level (root->node);
@@ -5980,24 +5983,16 @@ int btrfs_drop_snapshot(struct btrfs_roo }BUG_ON (wc->level ==0 ); -if (trans->transaction->in_commit || - trans->transaction->delayed_refs.flushing) { +if (btrfs_should_end_transaction (trans, tree_root)) { ret =btrfs_update_root (trans, tree_root, &root->root_key, root_item);BUG_ON (ret); -btrfs_end_transaction (trans, tree_root); +btrfs_end_transaction_throttle (trans, tree_root); trans =btrfs_start_transaction (tree_root,0 ); -if (IS_ERR (trans)) -return PTR_ERR (trans); - }else { -unsigned long update; - update = trans->delayed_ref_updates; - trans->delayed_ref_updates =0 ; -if (update) -btrfs_run_delayed_refs (trans, tree_root, - update); +if (block_rsv) + trans->block_rsv = block_rsv; } }btrfs_release_path (root, path);
@@ -6025,7 +6020,7 @@ int btrfs_drop_snapshot(struct btrfs_rookfree (root); } out: -btrfs_end_transaction (trans, tree_root); +btrfs_end_transaction_throttle (trans, tree_root);kfree (wc);btrfs_free_path (path);return err;
fs/btrfs/relocation.c +1143 -736
2,778 lines not on this page · raw message
fs/btrfs/transaction.c +4 -2
@@ -852,6 +852,7 @@ static noinline int create_pending_snaps goto fail; } +btrfs_reloc_pre_snapshot (trans, pending, &to_reserve);btrfs_orphan_pre_snapshot (trans, pending, &to_reserve);if (to_reserve >0 ) {
@@ -923,6 +924,7 @@ static noinline int create_pending_snaps pending->snap =btrfs_read_fs_root_no_name (root->fs_info, &key);BUG_ON (IS_ERR (pending->snap)); +btrfs_reloc_post_snapshot (trans, pending);btrfs_orphan_post_snapshot (trans, pending); fail:kfree (new_root_item);
@@ -1212,9 +1214,9 @@ int btrfs_clean_old_snapshots(struct btrif (btrfs_header_backref_rev (root->node) <BTRFS_MIXED_BACKREF_REV ) -btrfs_drop_snapshot (root,0 ); +btrfs_drop_snapshot (root,NULL ,0 );else -btrfs_drop_snapshot (root,1 ); +btrfs_drop_snapshot (root,NULL ,1 ); }return 0 ; }