Btrfs: Update metadata reservation for delayed allocation
PATCH v2 7/12 Btrfs: Update metadata reservation for delayed allocation
Introduce metadata reservation context for delayed allocation and update various related functions.
This patch also introduces EXTENT_FIRST_DELALLOC control bit for set/clear_extent_bit. It tells set/clear_bit_hook whether they are processing the first extent_state with EXTENT_DELALLOC bit set. This change is important if set/clear_extent_bit involves multiple extent_state.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/btrfs_inode.h +1 -1
@@ -137,8 +137,8 @@ struct btrfs_inode {* of extent items we've reserved metadata for. */ spinlock_t accounting_lock; +atomic_t outstanding_extents;int reserved_extents; -int outstanding_extents;/* * ordered_data_close is set by truncate when a file that used
fs/btrfs/ctree.h +6 -13
@@ -2078,19 +2078,8 @@ int btrfs_remove_block_group(struct btrfu64 btrfs_reduce_alloc_profile (struct btrfs_root *root,u64 flags);void 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_unreserve_metadata_for_delalloc (struct btrfs_root *root, -struct inode *inode,int num_items); -int btrfs_reserve_metadata_for_delalloc (struct btrfs_root *root, -struct inode *inode,int num_items); -int btrfs_check_data_free_space (struct btrfs_root *root,struct inode *inode, -u64 bytes); -void btrfs_free_reserved_data_space (struct btrfs_root *root, -struct inode *inode,u64 bytes); -void btrfs_delalloc_reserve_space (struct btrfs_root *root,struct inode *inode, -u64 bytes); -void btrfs_delalloc_free_space (struct btrfs_root *root,struct inode *inode, -u64 bytes); +int btrfs_check_data_free_space (struct inode *inode,u64 bytes); +void btrfs_free_reserved_data_space (struct inode *inode,u64 bytes);int btrfs_trans_reserve_metadata (struct btrfs_trans_handle *trans,struct btrfs_root *root,int num_items,int *retries);
@@ -2098,6 +2087,10 @@ void btrfs_trans_release_metadata(struct struct btrfs_root *root);int btrfs_snap_reserve_metadata (struct btrfs_trans_handle *trans,struct btrfs_pending_snapshot *pending); +int btrfs_delalloc_reserve_metadata (struct inode *inode,u64 num_bytes); +void btrfs_delalloc_release_metadata (struct inode *inode,u64 num_bytes); +int btrfs_delalloc_reserve_space (struct inode *inode,u64 num_bytes); +void btrfs_delalloc_release_space (struct inode *inode,u64 num_bytes);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,
fs/btrfs/extent_io.c +30 -33
196 lines not on this page · raw message
fs/btrfs/extent_io.h +5 -3
@@ -16,7 +16,9 @@#define EXTENT_BOUNDARY (1 << 9)#define EXTENT_NODATASUM (1 << 10)#define EXTENT_DO_ACCOUNTING (1 << 11) +#define EXTENT_FIRST_DELALLOC (1 << 12)#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) +#define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC)/* flags for bio submission */ #define EXTENT_BIO_COMPRESSED 1
@@ -69,10 +71,10 @@ struct extent_io_ops { struct extent_state *state);int (*writepage_end_io_hook)(struct page *page,u64 start,u64 end,struct extent_state *state,int uptodate); -int (*set_bit_hook)(struct inode *inode,u64 start,u64 end, -unsigned long old,unsigned long bits); +int (*set_bit_hook)(struct inode *inode,struct extent_state *state, +int *bits);int (*clear_bit_hook)(struct inode *inode,struct extent_state *state, -unsigned long bits); +int *bits);int (*merge_extent_hook)(struct inode *inode,struct extent_state *new,struct extent_state *other);
fs/btrfs/extent-tree.c +121 -240
424 lines not on this page · raw message
fs/btrfs/file.c +6 -21
@@ -851,13 +851,6 @@ static ssize_t btrfs_file_write(struct fvfs_check_frozen (inode->i_sb,SB_FREEZE_WRITE ); -/* do the reserve before the mutex lock in case we have to do some -* flushing. We wouldn't deadlock, but this is more polite. -*/ - err =btrfs_reserve_metadata_for_delalloc (root, inode,1 ); -if (err) - goto out_nolock; -mutex_lock (&inode->i_mutex); current->backing_dev_info = inode->i_mapping->backing_dev_info;
@@ -920,7 +913,7 @@ static ssize_t btrfs_file_write(struct fWARN_ON (num_pages > nrptrs);memset (pages,0 ,sizeof (struct page *) * nrptrs); - ret =btrfs_check_data_free_space (root, inode, write_bytes); + ret =btrfs_delalloc_reserve_space (inode, write_bytes);if (ret) goto out;
@@ -928,26 +921,20 @@ static ssize_t btrfs_file_write(struct f pos, first_index, last_index, write_bytes);if (ret) { -btrfs_free_reserved_data_space (root, inode, - write_bytes); +btrfs_delalloc_release_space (inode, write_bytes); goto out; } ret =btrfs_copy_from_user (pos, num_pages, write_bytes, pages, buf); -if (ret) { -btrfs_free_reserved_data_space (root, inode, - write_bytes); -btrfs_drop_pages (pages, num_pages); - goto out; +if (ret ==0 ) { +dirty_and_release_pages (NULL , root, file, pages, + num_pages, pos, write_bytes); } - ret =dirty_and_release_pages (NULL , root, file, pages, - num_pages, pos, write_bytes);btrfs_drop_pages (pages, num_pages);if (ret) { -btrfs_free_reserved_data_space (root, inode, - write_bytes); +btrfs_delalloc_release_space (inode, write_bytes); goto out; }
@@ -974,9 +961,7 @@ out:mutex_unlock (&inode->i_mutex);if (ret) err = ret; -btrfs_unreserve_metadata_for_delalloc (root, inode,1 ); -out_nolock:kfree (pages);if (pinned[0 ])page_cache_release (pinned[0 ]);
fs/btrfs/inode.c +53 -78
326 lines not on this page · raw message
fs/btrfs/ioctl.c +10 -19
@@ -586,19 +586,9 @@ static int btrfs_defrag_file(struct fileif (range->flags &BTRFS_DEFRAG_RANGE_COMPRESS )BTRFS_I (inode)->force_compress =1 ; - ret =btrfs_check_data_free_space (root, inode,PAGE_CACHE_SIZE ); -if (ret) { - ret = -ENOSPC ; -break ; - } - - ret =btrfs_reserve_metadata_for_delalloc (root, inode,1 ); -if (ret) { -btrfs_free_reserved_data_space (root, inode, -PAGE_CACHE_SIZE ); - ret = -ENOSPC ; -break ; - } + ret =btrfs_delalloc_reserve_space (inode,PAGE_CACHE_SIZE ); +if (ret) + goto err_unlock; again:if (inode->i_size ==0 || i > ((inode->i_size -1 ) >>PAGE_CACHE_SHIFT )) {
@@ -607,8 +597,10 @@ again: } page =grab_cache_page (inode->i_mapping, i); -if (!page) +if (!page) { + ret = -ENOMEM ; goto err_reservations; + }if (!PageUptodate (page)) {btrfs_readpage (NULL , page);
@@ -616,6 +608,7 @@ again:if (!PageUptodate (page)) {unlock_page (page);page_cache_release (page); + ret = -EIO ; goto err_reservations; } }
@@ -629,8 +622,7 @@ again:wait_on_page_writeback (page);if (PageDirty (page)) { -btrfs_free_reserved_data_space (root, inode, -PAGE_CACHE_SIZE ); +btrfs_delalloc_release_space (inode,PAGE_CACHE_SIZE ); goto loop_unlock; }
@@ -668,7 +660,6 @@ loop_unlock:page_cache_release (page);mutex_unlock (&inode->i_mutex); -btrfs_unreserve_metadata_for_delalloc (root, inode,1 );balance_dirty_pages_ratelimited_nr (inode->i_mapping,1 ); i++; }
@@ -698,9 +689,9 @@ loop_unlock:return 0 ; err_reservations: +btrfs_delalloc_release_space (inode,PAGE_CACHE_SIZE ); +err_unlock:mutex_unlock (&inode->i_mutex); -btrfs_free_reserved_data_space (root, inode,PAGE_CACHE_SIZE ); -btrfs_unreserve_metadata_for_delalloc (root, inode,1 );return ret; }
fs/btrfs/ordered-data.c +0 -7
@@ -312,13 +312,6 @@ static int __btrfs_remove_ordered_extent tree->last =NULL ;set_bit (BTRFS_ORDERED_COMPLETE , &entry->flags); -spin_lock (&BTRFS_I (inode)->accounting_lock); -WARN_ON (!BTRFS_I (inode)->outstanding_extents); -BTRFS_I (inode)->outstanding_extents--; -spin_unlock (&BTRFS_I (inode)->accounting_lock); -btrfs_unreserve_metadata_for_delalloc (BTRFS_I (inode)->root, - inode,1 ); -spin_lock (&root->fs_info->ordered_extent_lock);list_del_init (&entry->root_extent_list);