Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'iomap-6.6-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull iomap fixes from Darrick Wong:

- Return EIO on bad inputs to iomap_to_bh instead of BUGging, to deal
less poorly with block device io racing with block device resizing

- Fix a stale page data exposure bug introduced in 6.6-rc1 when
unsharing a file range that is not in the page cache

* tag 'iomap-6.6-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
iomap: convert iomap_unshare_iter to use large folios
iomap: don't skip reading in !uptodate folios when unsharing a range
iomap: handle error conditions more gracefully in iomap_to_bh

+32 -23
+14 -11
fs/buffer.c
··· 2011 2011 } 2012 2012 EXPORT_SYMBOL(folio_zero_new_buffers); 2013 2013 2014 - static void 2014 + static int 2015 2015 iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, 2016 2016 const struct iomap *iomap) 2017 2017 { ··· 2025 2025 * current block, then do not map the buffer and let the caller 2026 2026 * handle it. 2027 2027 */ 2028 - BUG_ON(offset >= iomap->offset + iomap->length); 2028 + if (offset >= iomap->offset + iomap->length) 2029 + return -EIO; 2029 2030 2030 2031 switch (iomap->type) { 2031 2032 case IOMAP_HOLE: ··· 2038 2037 if (!buffer_uptodate(bh) || 2039 2038 (offset >= i_size_read(inode))) 2040 2039 set_buffer_new(bh); 2041 - break; 2040 + return 0; 2042 2041 case IOMAP_DELALLOC: 2043 2042 if (!buffer_uptodate(bh) || 2044 2043 (offset >= i_size_read(inode))) ··· 2046 2045 set_buffer_uptodate(bh); 2047 2046 set_buffer_mapped(bh); 2048 2047 set_buffer_delay(bh); 2049 - break; 2048 + return 0; 2050 2049 case IOMAP_UNWRITTEN: 2051 2050 /* 2052 2051 * For unwritten regions, we always need to ensure that regions ··· 2063 2062 bh->b_blocknr = (iomap->addr + offset - iomap->offset) >> 2064 2063 inode->i_blkbits; 2065 2064 set_buffer_mapped(bh); 2066 - break; 2065 + return 0; 2066 + default: 2067 + WARN_ON_ONCE(1); 2068 + return -EIO; 2067 2069 } 2068 2070 } 2069 2071 ··· 2107 2103 clear_buffer_new(bh); 2108 2104 if (!buffer_mapped(bh)) { 2109 2105 WARN_ON(bh->b_size != blocksize); 2110 - if (get_block) { 2106 + if (get_block) 2111 2107 err = get_block(inode, block, bh, 1); 2112 - if (err) 2113 - break; 2114 - } else { 2115 - iomap_to_bh(inode, block, bh, iomap); 2116 - } 2108 + else 2109 + err = iomap_to_bh(inode, block, bh, iomap); 2110 + if (err) 2111 + break; 2117 2112 2118 2113 if (buffer_new(bh)) { 2119 2114 clean_bdev_bh_alias(bh);
+18 -12
fs/iomap/buffered-io.c
··· 640 640 size_t poff, plen; 641 641 642 642 /* 643 - * If the write completely overlaps the current folio, then 643 + * If the write or zeroing completely overlaps the current folio, then 644 644 * entire folio will be dirtied so there is no need for 645 645 * per-block state tracking structures to be attached to this folio. 646 + * For the unshare case, we must read in the ondisk contents because we 647 + * are not changing pagecache contents. 646 648 */ 647 - if (pos <= folio_pos(folio) && 649 + if (!(iter->flags & IOMAP_UNSHARE) && pos <= folio_pos(folio) && 648 650 pos + len >= folio_pos(folio) + folio_size(folio)) 649 651 return 0; 650 652 ··· 1263 1261 const struct iomap *srcmap = iomap_iter_srcmap(iter); 1264 1262 loff_t pos = iter->pos; 1265 1263 loff_t length = iomap_length(iter); 1266 - long status = 0; 1267 1264 loff_t written = 0; 1268 1265 1269 1266 /* don't bother with blocks that are not shared to start with */ ··· 1273 1272 return length; 1274 1273 1275 1274 do { 1276 - unsigned long offset = offset_in_page(pos); 1277 - unsigned long bytes = min_t(loff_t, PAGE_SIZE - offset, length); 1278 1275 struct folio *folio; 1276 + int status; 1277 + size_t offset; 1278 + size_t bytes = min_t(u64, SIZE_MAX, length); 1279 1279 1280 1280 status = iomap_write_begin(iter, pos, bytes, &folio); 1281 1281 if (unlikely(status)) 1282 1282 return status; 1283 - if (iter->iomap.flags & IOMAP_F_STALE) 1283 + if (iomap->flags & IOMAP_F_STALE) 1284 1284 break; 1285 1285 1286 - status = iomap_write_end(iter, pos, bytes, bytes, folio); 1287 - if (WARN_ON_ONCE(status == 0)) 1286 + offset = offset_in_folio(folio, pos); 1287 + if (bytes > folio_size(folio) - offset) 1288 + bytes = folio_size(folio) - offset; 1289 + 1290 + bytes = iomap_write_end(iter, pos, bytes, bytes, folio); 1291 + if (WARN_ON_ONCE(bytes == 0)) 1288 1292 return -EIO; 1289 1293 1290 1294 cond_resched(); 1291 1295 1292 - pos += status; 1293 - written += status; 1294 - length -= status; 1296 + pos += bytes; 1297 + written += bytes; 1298 + length -= bytes; 1295 1299 1296 1300 balance_dirty_pages_ratelimited(iter->inode->i_mapping); 1297 - } while (length); 1301 + } while (length > 0); 1298 1302 1299 1303 return written; 1300 1304 }