Fixes for 5.16-rc2:
- 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. -----BEGIN PGP SIGNATURE----- iQIyBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAmGehZoACgkQ+H93GTRK tOu7ig/44n/PzNzFv0dLAadoanBH/d3uMDs/s9DBWw6s7RYU0wjUMHgGyla9vFgT aw0xxLZfppvk59Gkme5WPiv/ksRwB9ZcWvEFUOMX/zt55uSNueCXCVpckduf9j29 gKUzFvRGVssBQ2ACHvuH/s6c6hF9EOhCHadREHinqemU3zg/+eH/+L+dgHIitzMg WiGdWEaojQX8brxD4kH7xfsNUbuFwCNO5UbGtndzsK/5b/8QGXIXOUrJ0JbefoBf Kscz4opZjfJIuGjczhIhollgV0jihMOH3OIJYfHQHVOUGVwQ/2epHo2cwq6Wujk0 3qXsjuYloR5xkyQwoLfr382BBO4teQW75nNUt+ez4tvwYs7Ck3U1oOFG+j3KiU/P gsMcSPzgQIiFdU1DRR5r6li6daLJJWK34PeZ4DtE0zFUKwslSUKytv+pT99yNPTG xkhvdU6R4jchUOPJCZCh8zdARhofTiaxrLPlZ0xKenqxlLxdMm+W0fCkuGFrLHSq g39CGJhuPe7OexK8lBY9fQ08zwI7LJIx/vQGQ3hbqZaxq14uCZVr/nGwcXlzBhzl BufZslO9Aj/eG1/MzwSN/xDTo3Jl+RuCs9lBgpg8pu6WNzueXbRMQnURy6Vf47Ua U6Awq0OrGbippg4Y7P/IiyYDKjFWPjgftYRJhoosxxfbO00BSA== =hIEG -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
adfb743ac0
@ -205,7 +205,16 @@ struct iomap_readpage_ctx {
|
||||
struct readahead_control *rac;
|
||||
};
|
||||
|
||||
static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
|
||||
/**
|
||||
* iomap_read_inline_data - copy inline data into the page cache
|
||||
* @iter: iteration structure
|
||||
* @page: page to copy to
|
||||
*
|
||||
* Copy the inline data in @iter into @page and zero out the rest of the page.
|
||||
* Only a single IOMAP_INLINE extent is allowed at the end of each file.
|
||||
* Returns zero for success to complete the read, or the usual negative errno.
|
||||
*/
|
||||
static int iomap_read_inline_data(const struct iomap_iter *iter,
|
||||
struct page *page)
|
||||
{
|
||||
const struct iomap *iomap = iomap_iter_srcmap(iter);
|
||||
@ -214,7 +223,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
|
||||
void *addr;
|
||||
|
||||
if (PageUptodate(page))
|
||||
return PAGE_SIZE - poff;
|
||||
return 0;
|
||||
|
||||
if (WARN_ON_ONCE(size > PAGE_SIZE - poff))
|
||||
return -EIO;
|
||||
@ -231,7 +240,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
|
||||
memset(addr + size, 0, PAGE_SIZE - poff - size);
|
||||
kunmap_local(addr);
|
||||
iomap_set_range_uptodate(page, poff, PAGE_SIZE - poff);
|
||||
return PAGE_SIZE - poff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool iomap_block_needs_zeroing(const struct iomap_iter *iter,
|
||||
@ -257,7 +266,7 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
|
||||
sector_t sector;
|
||||
|
||||
if (iomap->type == IOMAP_INLINE)
|
||||
return min(iomap_read_inline_data(iter, page), length);
|
||||
return iomap_read_inline_data(iter, page);
|
||||
|
||||
/* zero post-eof blocks as the page may be mapped */
|
||||
iop = iomap_page_create(iter->inode, page);
|
||||
@ -370,6 +379,8 @@ static loff_t iomap_readahead_iter(const struct iomap_iter *iter,
|
||||
ctx->cur_page_in_bio = false;
|
||||
}
|
||||
ret = iomap_readpage_iter(iter, ctx, done);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return done;
|
||||
@ -580,15 +591,10 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
|
||||
static int iomap_write_begin_inline(const struct iomap_iter *iter,
|
||||
struct page *page)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* needs more work for the tailpacking case; disable for now */
|
||||
if (WARN_ON_ONCE(iomap_iter_srcmap(iter)->offset != 0))
|
||||
return -EIO;
|
||||
ret = iomap_read_inline_data(iter, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
return iomap_read_inline_data(iter, page);
|
||||
}
|
||||
|
||||
static int iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
|
||||
|
Loading…
Reference in New Issue
Block a user