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-5.16-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull iomap fixes from Darrick Wong:
"A single iomap bug fix and a cleanup for 5.16-rc2.

The bug fix changes how iomap deals with reading from an inline data
region -- whereas the current code (incorrectly) lets the iomap read
iter try for more bytes after reading the inline region (which zeroes
the rest of the page!) and hopes the next iteration terminates, we
surveyed the inlinedata implementations and realized that all
inlinedata implementations also require that the inlinedata region end
at EOF, so we can simply terminate the read.

The second patch documents these assumptions in the code so that
they're not subtle implications anymore, and cleans up some of the
grosser parts of that function.

Summary:

- Fix an accounting problem where unaligned inline data reads can run
off the end of the read iomap iterator. iomap has historically
required that inline data mappings only exist at the end of a file,
though this wasn't documented anywhere.

- Document iomap_read_inline_data and change its return type to be
appropriate for the information that it's actually returning"

* tag 'iomap-5.16-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
iomap: iomap_read_inline_data cleanup
iomap: Fix inline extent handling in iomap_readpage

+16 -10
+16 -10
fs/iomap/buffered-io.c
··· 205 205 struct readahead_control *rac; 206 206 }; 207 207 208 - static loff_t iomap_read_inline_data(const struct iomap_iter *iter, 208 + /** 209 + * iomap_read_inline_data - copy inline data into the page cache 210 + * @iter: iteration structure 211 + * @page: page to copy to 212 + * 213 + * Copy the inline data in @iter into @page and zero out the rest of the page. 214 + * Only a single IOMAP_INLINE extent is allowed at the end of each file. 215 + * Returns zero for success to complete the read, or the usual negative errno. 216 + */ 217 + static int iomap_read_inline_data(const struct iomap_iter *iter, 209 218 struct page *page) 210 219 { 211 220 const struct iomap *iomap = iomap_iter_srcmap(iter); ··· 223 214 void *addr; 224 215 225 216 if (PageUptodate(page)) 226 - return PAGE_SIZE - poff; 217 + return 0; 227 218 228 219 if (WARN_ON_ONCE(size > PAGE_SIZE - poff)) 229 220 return -EIO; ··· 240 231 memset(addr + size, 0, PAGE_SIZE - poff - size); 241 232 kunmap_local(addr); 242 233 iomap_set_range_uptodate(page, poff, PAGE_SIZE - poff); 243 - return PAGE_SIZE - poff; 234 + return 0; 244 235 } 245 236 246 237 static inline bool iomap_block_needs_zeroing(const struct iomap_iter *iter, ··· 266 257 sector_t sector; 267 258 268 259 if (iomap->type == IOMAP_INLINE) 269 - return min(iomap_read_inline_data(iter, page), length); 260 + return iomap_read_inline_data(iter, page); 270 261 271 262 /* zero post-eof blocks as the page may be mapped */ 272 263 iop = iomap_page_create(iter->inode, page); ··· 379 370 ctx->cur_page_in_bio = false; 380 371 } 381 372 ret = iomap_readpage_iter(iter, ctx, done); 373 + if (ret <= 0) 374 + return ret; 382 375 } 383 376 384 377 return done; ··· 591 580 static int iomap_write_begin_inline(const struct iomap_iter *iter, 592 581 struct page *page) 593 582 { 594 - int ret; 595 - 596 583 /* needs more work for the tailpacking case; disable for now */ 597 584 if (WARN_ON_ONCE(iomap_iter_srcmap(iter)->offset != 0)) 598 585 return -EIO; 599 - ret = iomap_read_inline_data(iter, page); 600 - if (ret < 0) 601 - return ret; 602 - return 0; 586 + return iomap_read_inline_data(iter, page); 603 587 } 604 588 605 589 static int iomap_write_begin(const struct iomap_iter *iter, loff_t pos,