Skip to content

Commit adfb743

Browse files
committed
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
2 parents 86155d6 + 5ad448c commit adfb743

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

fs/iomap/buffered-io.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,16 @@ struct iomap_readpage_ctx {
205205
struct readahead_control *rac;
206206
};
207207

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,
209218
struct page *page)
210219
{
211220
const struct iomap *iomap = iomap_iter_srcmap(iter);
@@ -214,7 +223,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
214223
void *addr;
215224

216225
if (PageUptodate(page))
217-
return PAGE_SIZE - poff;
226+
return 0;
218227

219228
if (WARN_ON_ONCE(size > PAGE_SIZE - poff))
220229
return -EIO;
@@ -231,7 +240,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
231240
memset(addr + size, 0, PAGE_SIZE - poff - size);
232241
kunmap_local(addr);
233242
iomap_set_range_uptodate(page, poff, PAGE_SIZE - poff);
234-
return PAGE_SIZE - poff;
243+
return 0;
235244
}
236245

237246
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,
257266
sector_t sector;
258267

259268
if (iomap->type == IOMAP_INLINE)
260-
return min(iomap_read_inline_data(iter, page), length);
269+
return iomap_read_inline_data(iter, page);
261270

262271
/* zero post-eof blocks as the page may be mapped */
263272
iop = iomap_page_create(iter->inode, page);
@@ -370,6 +379,8 @@ static loff_t iomap_readahead_iter(const struct iomap_iter *iter,
370379
ctx->cur_page_in_bio = false;
371380
}
372381
ret = iomap_readpage_iter(iter, ctx, done);
382+
if (ret <= 0)
383+
return ret;
373384
}
374385

375386
return done;
@@ -580,15 +591,10 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
580591
static int iomap_write_begin_inline(const struct iomap_iter *iter,
581592
struct page *page)
582593
{
583-
int ret;
584-
585594
/* needs more work for the tailpacking case; disable for now */
586595
if (WARN_ON_ONCE(iomap_iter_srcmap(iter)->offset != 0))
587596
return -EIO;
588-
ret = iomap_read_inline_data(iter, page);
589-
if (ret < 0)
590-
return ret;
591-
return 0;
597+
return iomap_read_inline_data(iter, page);
592598
}
593599

594600
static int iomap_write_begin(const struct iomap_iter *iter, loff_t pos,

0 commit comments

Comments
 (0)