aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 844bb896f5ac..b8b2a3cbdbe1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -115,6 +115,31 @@ static struct extent_map *create_io_em(struct inode *inode, u64 start, u64 len,
115 u64 ram_bytes, int compress_type, 115 u64 ram_bytes, int compress_type,
116 int type); 116 int type);
117 117
118static void __endio_write_update_ordered(struct inode *inode,
119 const u64 offset, const u64 bytes,
120 const bool uptodate);
121
122/*
123 * Cleanup all submitted ordered extents in specified range to handle errors
124 * from the fill_dellaloc() callback.
125 *
126 * NOTE: caller must ensure that when an error happens, it can not call
127 * extent_clear_unlock_delalloc() to clear both the bits EXTENT_DO_ACCOUNTING
128 * and EXTENT_DELALLOC simultaneously, because that causes the reserved metadata
129 * to be released, which we want to happen only when finishing the ordered
130 * extent (btrfs_finish_ordered_io()). Also note that the caller of the
131 * fill_delalloc() callback already does proper cleanup for the first page of
132 * the range, that is, it invokes the callback writepage_end_io_hook() for the
133 * range of the first page.
134 */
135static inline void btrfs_cleanup_ordered_extents(struct inode *inode,
136 const u64 offset,
137 const u64 bytes)
138{
139 return __endio_write_update_ordered(inode, offset + PAGE_SIZE,
140 bytes - PAGE_SIZE, false);
141}
142
118static int btrfs_dirty_inode(struct inode *inode); 143static int btrfs_dirty_inode(struct inode *inode);
119 144
120#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 145#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
@@ -1536,6 +1561,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1536 ret = cow_file_range_async(inode, locked_page, start, end, 1561 ret = cow_file_range_async(inode, locked_page, start, end,
1537 page_started, nr_written); 1562 page_started, nr_written);
1538 } 1563 }
1564 if (ret)
1565 btrfs_cleanup_ordered_extents(inode, start, end - start + 1);
1539 return ret; 1566 return ret;
1540} 1567}
1541 1568
@@ -8154,17 +8181,26 @@ static void btrfs_endio_direct_read(struct bio *bio)
8154 bio_put(bio); 8181 bio_put(bio);
8155} 8182}
8156 8183
8157static void btrfs_endio_direct_write_update_ordered(struct inode *inode, 8184static void __endio_write_update_ordered(struct inode *inode,
8158 const u64 offset, 8185 const u64 offset, const u64 bytes,
8159 const u64 bytes, 8186 const bool uptodate)
8160 const int uptodate)
8161{ 8187{
8162 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 8188 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
8163 struct btrfs_ordered_extent *ordered = NULL; 8189 struct btrfs_ordered_extent *ordered = NULL;
8190 struct btrfs_workqueue *wq;
8191 btrfs_work_func_t func;
8164 u64 ordered_offset = offset; 8192 u64 ordered_offset = offset;
8165 u64 ordered_bytes = bytes; 8193 u64 ordered_bytes = bytes;
8166 int ret; 8194 int ret;
8167 8195
8196 if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
8197 wq = fs_info->endio_freespace_worker;
8198 func = btrfs_freespace_write_helper;
8199 } else {
8200 wq = fs_info->endio_write_workers;
8201 func = btrfs_endio_write_helper;
8202 }
8203
8168again: 8204again:
8169 ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, 8205 ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
8170 &ordered_offset, 8206 &ordered_offset,
@@ -8173,9 +8209,8 @@ again:
8173 if (!ret) 8209 if (!ret)
8174 goto out_test; 8210 goto out_test;
8175 8211
8176 btrfs_init_work(&ordered->work, btrfs_endio_write_helper, 8212 btrfs_init_work(&ordered->work, func, finish_ordered_fn, NULL, NULL);
8177 finish_ordered_fn, NULL, NULL); 8213 btrfs_queue_work(wq, &ordered->work);
8178 btrfs_queue_work(fs_info->endio_write_workers, &ordered->work);
8179out_test: 8214out_test:
8180 /* 8215 /*
8181 * our bio might span multiple ordered extents. If we haven't 8216 * our bio might span multiple ordered extents. If we haven't
@@ -8193,10 +8228,8 @@ static void btrfs_endio_direct_write(struct bio *bio)
8193 struct btrfs_dio_private *dip = bio->bi_private; 8228 struct btrfs_dio_private *dip = bio->bi_private;
8194 struct bio *dio_bio = dip->dio_bio; 8229 struct bio *dio_bio = dip->dio_bio;
8195 8230
8196 btrfs_endio_direct_write_update_ordered(dip->inode, 8231 __endio_write_update_ordered(dip->inode, dip->logical_offset,
8197 dip->logical_offset, 8232 dip->bytes, !bio->bi_error);
8198 dip->bytes,
8199 !bio->bi_error);
8200 8233
8201 kfree(dip); 8234 kfree(dip);
8202 8235
@@ -8557,10 +8590,10 @@ free_ordered:
8557 io_bio = NULL; 8590 io_bio = NULL;
8558 } else { 8591 } else {
8559 if (write) 8592 if (write)
8560 btrfs_endio_direct_write_update_ordered(inode, 8593 __endio_write_update_ordered(inode,
8561 file_offset, 8594 file_offset,
8562 dio_bio->bi_iter.bi_size, 8595 dio_bio->bi_iter.bi_size,
8563 0); 8596 false);
8564 else 8597 else
8565 unlock_extent(&BTRFS_I(inode)->io_tree, file_offset, 8598 unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,
8566 file_offset + dio_bio->bi_iter.bi_size - 1); 8599 file_offset + dio_bio->bi_iter.bi_size - 1);
@@ -8695,11 +8728,11 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
8695 */ 8728 */
8696 if (dio_data.unsubmitted_oe_range_start < 8729 if (dio_data.unsubmitted_oe_range_start <
8697 dio_data.unsubmitted_oe_range_end) 8730 dio_data.unsubmitted_oe_range_end)
8698 btrfs_endio_direct_write_update_ordered(inode, 8731 __endio_write_update_ordered(inode,
8699 dio_data.unsubmitted_oe_range_start, 8732 dio_data.unsubmitted_oe_range_start,
8700 dio_data.unsubmitted_oe_range_end - 8733 dio_data.unsubmitted_oe_range_end -
8701 dio_data.unsubmitted_oe_range_start, 8734 dio_data.unsubmitted_oe_range_start,
8702 0); 8735 false);
8703 } else if (ret >= 0 && (size_t)ret < count) 8736 } else if (ret >= 0 && (size_t)ret < count)
8704 btrfs_delalloc_release_space(inode, offset, 8737 btrfs_delalloc_release_space(inode, offset,
8705 count - (size_t)ret); 8738 count - (size_t)ret);