Pull iomap fixes from Darrick Wong: "A handful of bugfixes for the iomap code. There's nothing especially exciting here, just fixes for UBSAN (not KASAN as I erroneously wrote in the tag message) warnings about undefined behavior in the SEEK_DATA/SEEK_HOLE code, and some reshuffling of per-page block state info to fix some problems with gfs2. - Fix KASAN warnings due to integer overflow in SEEK_DATA/SEEK_HOLE - Fix assertion errors when using inlinedata files on gfs2" * tag 'iomap-5.14-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: iomap: Don't create iomap_page objects in iomap_page_mkwrite_actor iomap: Don't create iomap_page objects for inline files iomap: Permit pages without an iop to enter writeback iomap: remove the length variable in iomap_seek_hole iomap: remove the length variable in iomap_seek_data
Unified · Split
| @@ -215,6 +215,7 @@ iomap_read_inline_data(struct inode *inode, struct page *page, · 214 unmodified lines | |||
| 215 | if (PageUptodate(page)) | 215 | if (PageUptodate(page)) |
| 216 | return; | 216 | return; |
| 217 | 217 | ||
| 218 | BUG_ON(page_has_private(page)); | ||
| 218 | BUG_ON(page->index); | 219 | BUG_ON(page->index); |
| 219 | BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data)); | 220 | BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data)); |
| 220 | 221 | ||
| @@ -239,7 +240,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, · 18 unmodified lines | |||
| 239 | { | 240 | { |
| 240 | struct iomap_readpage_ctx *ctx = data; | 241 | struct iomap_readpage_ctx *ctx = data; |
| 241 | struct page *page = ctx->cur_page; | 242 | struct page *page = ctx->cur_page; |
| 242 | struct iomap_page *iop = iomap_page_create(inode, page); | 243 | struct iomap_page *iop; |
| 243 | bool same_page = false, is_contig = false; | 244 | bool same_page = false, is_contig = false; |
| 244 | loff_t orig_pos = pos; | 245 | loff_t orig_pos = pos; |
| 245 | unsigned poff, plen; | 246 | unsigned poff, plen; |
| @@ -252,6 +253,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, · 6 unmodified lines | |||
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | /* zero post-eof blocks as the page may be mapped */ | 255 | /* zero post-eof blocks as the page may be mapped */ |
| 256 | iop = iomap_page_create(inode, page); | ||
| 255 | iomap_adjust_read_range(inode, iop, &pos, length, &poff, &plen); | 257 | iomap_adjust_read_range(inode, iop, &pos, length, &poff, &plen); |
| 256 | if (plen == 0) | 258 | if (plen == 0) |
| 257 | goto done; | 259 | goto done; |
| @@ -967,7 +969,6 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length, · 709 unmodified lines | |||
| 967 | block_commit_write(page, 0, length); | 969 | block_commit_write(page, 0, length); |
| 968 | } else { | 970 | } else { |
| 969 | WARN_ON_ONCE(!PageUptodate(page)); | 971 | WARN_ON_ONCE(!PageUptodate(page)); |
| 970 | iomap_page_create(inode, page); | ||
| 971 | set_page_dirty(page); | 972 | set_page_dirty(page); |
| 972 | } | 973 | } |
| 973 | 974 | ||
| @@ -1304,14 +1305,13 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, · 330 unmodified lines | |||
| 1304 | struct writeback_control *wbc, struct inode *inode, | 1305 | struct writeback_control *wbc, struct inode *inode, |
| 1305 | struct page *page, u64 end_offset) | 1306 | struct page *page, u64 end_offset) |
| 1306 | { | 1307 | { |
| 1307 | struct iomap_page *iop = to_iomap_page(page); | 1308 | struct iomap_page *iop = iomap_page_create(inode, page); |
| 1308 | struct iomap_ioend *ioend, *next; | 1309 | struct iomap_ioend *ioend, *next; |
| 1309 | unsigned len = i_blocksize(inode); | 1310 | unsigned len = i_blocksize(inode); |
| 1310 | u64 file_offset; /* file offset of page */ | 1311 | u64 file_offset; /* file offset of page */ |
| 1311 | int error = 0, count = 0, i; | 1312 | int error = 0, count = 0, i; |
| 1312 | LIST_HEAD(submit_list); | 1313 | LIST_HEAD(submit_list); |
| 1313 | 1314 | ||
| 1314 | WARN_ON_ONCE(i_blocks_per_page(inode, page) > 1 && !iop); | ||
| 1315 | WARN_ON_ONCE(iop && atomic_read(&iop->write_bytes_pending) != 0); | 1315 | WARN_ON_ONCE(iop && atomic_read(&iop->write_bytes_pending) != 0); |
| 1316 | 1316 | ||
| 1317 | /* | 1317 | /* |
| @@ -35,23 +35,20 @@ loff_t · 34 unmodified lines | |||
| 35 | iomap_seek_hole(struct inode *inode, loff_t offset, const struct iomap_ops *ops) | 35 | iomap_seek_hole(struct inode *inode, loff_t offset, const struct iomap_ops *ops) |
| 36 | { | 36 | { |
| 37 | loff_t size = i_size_read(inode); | 37 | loff_t size = i_size_read(inode); |
| 38 | loff_t length = size - offset; | ||
| 39 | loff_t ret; | 38 | loff_t ret; |
| 40 | 39 | ||
| 41 | /* Nothing to be found before or beyond the end of the file. */ | 40 | /* Nothing to be found before or beyond the end of the file. */ |
| 42 | if (offset < 0 || offset >= size) | 41 | if (offset < 0 || offset >= size) |
| 43 | return -ENXIO; | 42 | return -ENXIO; |
| 44 | 43 | ||
| 45 | while (length > 0) { | 44 | while (offset < size) { |
| 46 | ret = iomap_apply(inode, offset, length, IOMAP_REPORT, ops, | 45 | ret = iomap_apply(inode, offset, size - offset, IOMAP_REPORT, |
| 47 | &offset, iomap_seek_hole_actor); | 46 | ops, &offset, iomap_seek_hole_actor); |
| 48 | if (ret < 0) | 47 | if (ret < 0) |
| 49 | return ret; | 48 | return ret; |
| 50 | if (ret == 0) | 49 | if (ret == 0) |
| 51 | break; | 50 | break; |
| 52 | |||
| 53 | offset += ret; | 51 | offset += ret; |
| 54 | length -= ret; | ||
| 55 | } | 52 | } |
| 56 | 53 | ||
| 57 | return offset; | 54 | return offset; |
| @@ -83,27 +80,23 @@ loff_t · 25 unmodified lines | |||
| 83 | iomap_seek_data(struct inode *inode, loff_t offset, const struct iomap_ops *ops) | 80 | iomap_seek_data(struct inode *inode, loff_t offset, const struct iomap_ops *ops) |
| 84 | { | 81 | { |
| 85 | loff_t size = i_size_read(inode); | 82 | loff_t size = i_size_read(inode); |
| 86 | loff_t length = size - offset; | ||
| 87 | loff_t ret; | 83 | loff_t ret; |
| 88 | 84 | ||
| 89 | /* Nothing to be found before or beyond the end of the file. */ | 85 | /* Nothing to be found before or beyond the end of the file. */ |
| 90 | if (offset < 0 || offset >= size) | 86 | if (offset < 0 || offset >= size) |
| 91 | return -ENXIO; | 87 | return -ENXIO; |
| 92 | 88 | ||
| 93 | while (length > 0) { | 89 | while (offset < size) { |
| 94 | ret = iomap_apply(inode, offset, length, IOMAP_REPORT, ops, | 90 | ret = iomap_apply(inode, offset, size - offset, IOMAP_REPORT, |
| 95 | &offset, iomap_seek_data_actor); | 91 | ops, &offset, iomap_seek_data_actor); |
| 96 | if (ret < 0) | 92 | if (ret < 0) |
| 97 | return ret; | 93 | return ret; |
| 98 | if (ret == 0) | 94 | if (ret == 0) |
| 99 | break; | 95 | return offset; |
| 100 | |||
| 101 | offset += ret; | 96 | offset += ret; |
| 102 | length -= ret; | ||
| 103 | } | 97 | } |
| 104 | 98 | ||
| 105 | if (length <= 0) | 99 | /* We've reached the end of the file without finding data */ |
| 106 | return -ENXIO; | 100 | return -ENXIO; |
| 107 | return offset; | ||
| 108 | } | 101 | } |
| 109 | EXPORT_SYMBOL_GPL(iomap_seek_data); | 102 | EXPORT_SYMBOL_GPL(iomap_seek_data); |