Btrfs: Integrate metadata reservation with start_transaction
PATCH v2 6/12 Btrfs: Integrate metadata reservation with start_transaction
Besides simplify the code, this change makes sure all metadata reservation for normal metadata operations are released after committing transaction.
Changes since V1:
Add code that check if unlink and rmdir will free space.
Add ENOSPC handling for clone ioctl.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.h +18 -2
@@ -33,6 +33,7 @@struct btrfs_trans_handle ;struct btrfs_transaction ; +struct btrfs_pending_snapshot ;extern struct kmem_cache *btrfs_trans_handle_cachep;extern struct kmem_cache *btrfs_transaction_cachep;extern struct kmem_cache *btrfs_bit_radix_cachep;
@@ -969,6 +970,7 @@ struct btrfs_fs_info {int do_barriers;int closing;int log_root_recovering; +int enospc_unlink;u64 total_pinned;
@@ -1994,6 +1996,9 @@ void btrfs_put_block_group(struct btrfs_int btrfs_run_delayed_refs (struct btrfs_trans_handle *trans,struct btrfs_root *root,unsigned long count);int btrfs_lookup_extent (struct btrfs_root *root,u64 start,u64 len); +int btrfs_lookup_extent_info (struct btrfs_trans_handle *trans, +struct btrfs_root *root,u64 bytenr, +u64 num_bytes,u64 *refs,u64 *flags);int btrfs_pin_extent (struct btrfs_root *root,u64 bytenr,u64 num,int reserved); int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
@@ -2074,8 +2079,6 @@ u64 btrfs_reduce_alloc_profile(struct btvoid btrfs_set_inode_space_info (struct btrfs_root *root,struct inode *ionde);void btrfs_clear_space_info_full (struct btrfs_fs_info *info); -int btrfs_reserve_metadata_space (struct btrfs_root *root,int num_items); -int btrfs_unreserve_metadata_space (struct btrfs_root *root,int num_items);int btrfs_unreserve_metadata_for_delalloc (struct btrfs_root *root,struct inode *inode,int num_items); int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
@@ -2088,6 +2091,13 @@ void btrfs_delalloc_reserve_space(struct u64 bytes);void btrfs_delalloc_free_space (struct btrfs_root *root,struct inode *inode,u64 bytes); +int btrfs_trans_reserve_metadata (struct btrfs_trans_handle *trans, +struct btrfs_root *root, +int num_items,int *retries); +void btrfs_trans_release_metadata (struct btrfs_trans_handle *trans, +struct btrfs_root *root); +int btrfs_snap_reserve_metadata (struct btrfs_trans_handle *trans, +struct btrfs_pending_snapshot *pending);void btrfs_init_block_rsv (struct btrfs_block_rsv *rsv);struct btrfs_block_rsv *btrfs_alloc_block_rsv (struct btrfs_root *root); void btrfs_free_block_rsv(struct btrfs_root *root,
@@ -2295,6 +2305,12 @@ int btrfs_del_inode_ref(struct btrfs_trastruct btrfs_root *root, const char *name, int name_len, u64 inode_objectid, u64 ref_objectid, u64 *index); +struct btrfs_inode_ref * +btrfs_lookup_inode_ref (struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct btrfs_path *path, +const char *name,int name_len, +u64 inode_objectid,u64 ref_objectid,int mod);int btrfs_insert_empty_inode (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct btrfs_path *path,u64 objectid);
fs/btrfs/delayed-ref.c +0 -101
107 lines not on this page · raw message
fs/btrfs/delayed-ref.h +0 -3
@@ -167,9 +167,6 @@ int btrfs_add_delayed_extent_op(struct bstruct btrfs_delayed_ref_head *btrfs_find_delayed_ref_head (struct btrfs_trans_handle *trans,u64 bytenr);int btrfs_delayed_ref_pending (struct btrfs_trans_handle *trans,u64 bytenr); -int btrfs_lookup_extent_info (struct btrfs_trans_handle *trans, -struct btrfs_root *root,u64 bytenr, -u64 num_bytes,u64 *refs,u64 *flags); int btrfs_update_delayed_ref(struct btrfs_trans_handle *trans, u64 bytenr, u64 num_bytes, u64 orig_parent, u64 parent, u64 orig_ref_root, u64 ref_root,
fs/btrfs/disk-io.c +3 -3
@@ -1531,7 +1531,7 @@ static int transaction_kthread(void *arg goto sleep; }mutex_unlock (&root->fs_info->trans_mutex); - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_join_transaction (root,1 ); ret =btrfs_commit_transaction (trans, root); sleep:
@@ -2418,11 +2418,11 @@ int btrfs_commit_super(struct btrfs_rootdown_write (&root->fs_info->cleanup_work_sem);up_write (&root->fs_info->cleanup_work_sem); - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_join_transaction (root,1 ); ret =btrfs_commit_transaction (trans, root);BUG_ON (ret);/* run commit again to drop the original snapshot */ - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_join_transaction (root,1 );btrfs_commit_transaction (trans, root); ret =btrfs_write_and_wait_transaction (NULL , root);BUG_ON (ret);
fs/btrfs/extent-tree.c +169 -114
325 lines not on this page · raw message
fs/btrfs/file.c +6 -7
@@ -125,8 +125,7 @@ static noinline int dirty_and_release_pa end_of_last_block = start_pos + num_bytes -1 ; err =btrfs_set_extent_delalloc (inode, start_pos, end_of_last_block,NULL ); -if (err) -return err; +BUG_ON (err);for (i =0 ; i < num_pages; i++) {struct page *p = pages[i];
@@ -141,7 +140,7 @@ static noinline int dirty_and_release_pa* at this time. */ } -return err; +return 0 ; }/*
@@ -1007,7 +1006,7 @@ out_nolock: num_written = err;if ((file->f_flags &O_SYNC ) ||IS_SYNC (inode)) { - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 ); ret =btrfs_log_dentry_safe (trans, root, file->f_dentry);if (ret ==0 ) {
@@ -1103,9 +1102,9 @@ int btrfs_sync_file(struct file *file, sif (file && file->private_data)btrfs_ioctl_trans_end (file); - trans =btrfs_start_transaction (root,1 ); -if (!trans) { - ret = -ENOMEM ; + trans =btrfs_start_transaction (root,0 ); +if (IS_ERR (trans)) { + ret =PTR_ERR (trans); goto out; }
fs/btrfs/inode.c +257 -146
638 lines not on this page · raw message
fs/btrfs/inode-item.c +27 -0
@@ -49,6 +49,33 @@ static int find_name_in_backref(struct breturn 0 ; } +struct btrfs_inode_ref * +btrfs_lookup_inode_ref (struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct btrfs_path *path, +const char *name,int name_len, +u64 inode_objectid,u64 ref_objectid,int mod) +{ +struct btrfs_key key; +struct btrfs_inode_ref *ref; +int ins_len = mod <0 ?-1 :0 ; +int cow = mod !=0 ; +int ret; + + key.objectid = inode_objectid; + key.type =BTRFS_INODE_REF_KEY ; + key.offset = ref_objectid; + + ret =btrfs_search_slot (trans, root, &key, path, ins_len, cow); +if (ret <0 ) +return ERR_PTR (ret); +if (ret >0 ) +return NULL ; +if (!find_name_in_backref (path, name, name_len, &ref)) +return NULL ; +return ref; +} + int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len,
fs/btrfs/ioctl.c +80 -77
268 lines not on this page · raw message
fs/btrfs/relocation.c +9 -9
@@ -1648,7 +1648,7 @@ static noinline_for_stack int merge_relo }if (level ==0 && rc->stage ==UPDATE_DATA_PTRS ) { - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 ); leaf = path->nodes[0 ];btrfs_item_key_to_cpu (leaf, &key,0 );
@@ -1674,7 +1674,7 @@ static noinline_for_stack int merge_relowhile (1 ) { leaf =NULL ; replaced =0 ; - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 ); max_level = level; ret =walk_down_reloc_tree (reloc_root, path, &level);
@@ -1802,7 +1802,7 @@ static void merge_func(struct btrfs_workmerge_reloc_root (async->rc, root); - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 );btrfs_update_reloc_root (trans, root);btrfs_end_transaction (trans, root); }
@@ -3296,11 +3296,11 @@ static noinline_for_stack int relocate_b rc->create_reloc_root =1 ;set_reloc_control (rc); - trans =btrfs_start_transaction (rc->extent_root,1 ); + trans =btrfs_join_transaction (rc->extent_root,1 );btrfs_commit_transaction (trans, rc->extent_root);while (1 ) { - trans =btrfs_start_transaction (rc->extent_root,1 ); + trans =btrfs_start_transaction (rc->extent_root,0 ); ret =find_next_extent (trans, rc, path);if (ret <0 )
@@ -3410,7 +3410,7 @@ static noinline_for_stack int relocate_bsmp_mb ();if (rc->extents_found >0 ) { - trans =btrfs_start_transaction (rc->extent_root,1 ); + trans =btrfs_join_transaction (rc->extent_root,1 );btrfs_commit_transaction (trans, rc->extent_root); }
@@ -3419,7 +3419,7 @@ static noinline_for_stack int relocate_bunset_reloc_control (rc);/* get rid of pinned extents */ - trans =btrfs_start_transaction (rc->extent_root,1 ); + trans =btrfs_join_transaction (rc->extent_root,1 );btrfs_commit_transaction (trans, rc->extent_root);return err;
@@ -3474,7 +3474,7 @@ static struct inode *create_reloc_inode(if (IS_ERR (root))return ERR_CAST (root); - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,6 );BUG_ON (!trans); err =btrfs_find_free_objectid (trans, root, objectid, &objectid);
@@ -3618,7 +3618,7 @@ static noinline_for_stack int mark_garbastruct btrfs_trans_handle *trans;int ret; - trans =btrfs_start_transaction (root->fs_info->tree_root,1 ); + trans =btrfs_start_transaction (root->fs_info->tree_root,0 );memset (&root->root_item.drop_progress,0 ,sizeof (root->root_item.drop_progress));
fs/btrfs/super.c +1 -1
@@ -497,7 +497,7 @@ int btrfs_sync_fs(struct super_block *sbbtrfs_start_delalloc_inodes (root,0 );btrfs_wait_ordered_extents (root,0 ,0 ); - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 ); ret =btrfs_commit_transaction (trans, root);return ret; }
fs/btrfs/transaction.c +90 -41
224 lines not on this page · raw message
fs/btrfs/transaction.h +8 -5
@@ -57,8 +57,11 @@ struct btrfs_trans_handle {struct btrfs_pending_snapshot {struct dentry *dentry;struct btrfs_root *root; -char *name; -struct btrfs_key root_key; +struct btrfs_root *snap; +/* block reservation for the operation */ +struct btrfs_block_rsv block_rsv; +/* extra metadata reseration for relocation */ +int error;struct list_head list; };
@@ -85,11 +88,11 @@ static inline void btrfs_set_inode_last_int btrfs_end_transaction (struct btrfs_trans_handle *trans,struct btrfs_root *root);struct btrfs_trans_handle *btrfs_start_transaction (struct btrfs_root *root, -int num_blocks); +int num_items);struct btrfs_trans_handle *btrfs_join_transaction (struct btrfs_root *root, -int num_blocks); +int num_blocks);struct btrfs_trans_handle *btrfs_start_ioctl_transaction (struct btrfs_root *r, -int num_blocks); +int num_blocks);int btrfs_write_and_wait_transaction (struct btrfs_trans_handle *trans,struct btrfs_root *root); int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
fs/btrfs/volumes.c +7 -10
@@ -1096,7 +1096,7 @@ static int btrfs_rm_dev_item(struct btrfif (!path)return -ENOMEM ; - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 ); key.objectid =BTRFS_DEV_ITEMS_OBJECTID ; key.type =BTRFS_DEV_ITEM_KEY ; key.offset = device->devid;
@@ -1485,7 +1485,7 @@ int btrfs_init_new_device(struct btrfs_r goto error; } - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 );lock_chunks (root); device->barriers =1 ;
@@ -1750,9 +1750,10 @@ static int btrfs_relocate_chunk(struct b/* step one, relocate all the extents inside this chunk */ ret =btrfs_relocate_block_group (extent_root, chunk_offset); -BUG_ON (ret); +if (ret) +return ret; - trans =btrfs_start_transaction (root,1 ); + trans =btrfs_start_transaction (root,0 );BUG_ON (!trans);lock_chunks (root);
@@ -1924,7 +1925,7 @@ int btrfs_balance(struct btrfs_root *devbreak ;BUG_ON (ret); - trans =btrfs_start_transaction (dev_root,1 ); + trans =btrfs_start_transaction (dev_root,0 );BUG_ON (!trans); ret =btrfs_grow_device (trans, device, old_size);
@@ -2093,11 +2094,7 @@ again: }/* Shrinking succeeded, else we would be at "done". */ - trans =btrfs_start_transaction (root,1 ); -if (!trans) { - ret = -ENOMEM ; - goto done; - } + trans =btrfs_start_transaction (root,0 );lock_chunks (root); device->disk_total_bytes = new_size;
fs/btrfs/xattr.c +3 -9
@@ -154,15 +154,10 @@ int __btrfs_setxattr(struct btrfs_trans_if (trans)return do_setxattr (trans, inode, name, value, size, flags); - ret =btrfs_reserve_metadata_space (root,2 ); -if (ret) -return ret; + trans =btrfs_start_transaction (root,2 ); +if (IS_ERR (trans)) +return PTR_ERR (trans); - trans =btrfs_start_transaction (root,1 ); -if (!trans) { - ret = -ENOMEM ; - goto out; - }btrfs_set_trans_block_group (trans, inode); ret =do_setxattr (trans, inode, name, value, size, flags);
@@ -174,7 +169,6 @@ int __btrfs_setxattr(struct btrfs_trans_BUG_ON (ret); out:btrfs_end_transaction_throttle (trans, root); -btrfs_unreserve_metadata_space (root,2 );return ret; }