Skip to content

Commit 98321b5

Browse files
Andreas GruenbacherDarrick J. Wong
authored andcommitted
iomap: Add iomap_get_folio helper
Add an iomap_get_folio() helper that gets a folio reference based on an iomap iterator and an offset into the address space. Use it in iomap_write_begin(). Signed-off-by: Andreas Gruenbacher <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 40405dd commit 98321b5

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

fs/iomap/buffered-io.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,33 @@ bool iomap_is_partially_uptodate(struct folio *folio, size_t from, size_t count)
457457
}
458458
EXPORT_SYMBOL_GPL(iomap_is_partially_uptodate);
459459

460+
/**
461+
* iomap_get_folio - get a folio reference for writing
462+
* @iter: iteration structure
463+
* @pos: start offset of write
464+
*
465+
* Returns a locked reference to the folio at @pos, or an error pointer if the
466+
* folio could not be obtained.
467+
*/
468+
struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos)
469+
{
470+
unsigned fgp = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE | FGP_NOFS;
471+
struct folio *folio;
472+
473+
if (iter->flags & IOMAP_NOWAIT)
474+
fgp |= FGP_NOWAIT;
475+
476+
folio = __filemap_get_folio(iter->inode->i_mapping, pos >> PAGE_SHIFT,
477+
fgp, mapping_gfp_mask(iter->inode->i_mapping));
478+
if (folio)
479+
return folio;
480+
481+
if (iter->flags & IOMAP_NOWAIT)
482+
return ERR_PTR(-EAGAIN);
483+
return ERR_PTR(-ENOMEM);
484+
}
485+
EXPORT_SYMBOL_GPL(iomap_get_folio);
486+
460487
bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags)
461488
{
462489
trace_iomap_release_folio(folio->mapping->host, folio_pos(folio),
@@ -603,12 +630,8 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
603630
const struct iomap_page_ops *page_ops = iter->iomap.page_ops;
604631
const struct iomap *srcmap = iomap_iter_srcmap(iter);
605632
struct folio *folio;
606-
unsigned fgp = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE | FGP_NOFS;
607633
int status = 0;
608634

609-
if (iter->flags & IOMAP_NOWAIT)
610-
fgp |= FGP_NOWAIT;
611-
612635
BUG_ON(pos + len > iter->iomap.offset + iter->iomap.length);
613636
if (srcmap != &iter->iomap)
614637
BUG_ON(pos + len > srcmap->offset + srcmap->length);
@@ -625,12 +648,10 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
625648
return status;
626649
}
627650

628-
folio = __filemap_get_folio(iter->inode->i_mapping, pos >> PAGE_SHIFT,
629-
fgp, mapping_gfp_mask(iter->inode->i_mapping));
630-
if (!folio) {
631-
status = (iter->flags & IOMAP_NOWAIT) ? -EAGAIN : -ENOMEM;
651+
folio = iomap_get_folio(iter, pos);
652+
if (IS_ERR(folio)) {
632653
__iomap_put_folio(iter, pos, 0, NULL);
633-
return status;
654+
return PTR_ERR(folio);
634655
}
635656

636657
/*

include/linux/iomap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ int iomap_file_buffered_write_punch_delalloc(struct inode *inode,
261261
int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops);
262262
void iomap_readahead(struct readahead_control *, const struct iomap_ops *ops);
263263
bool iomap_is_partially_uptodate(struct folio *, size_t from, size_t count);
264+
struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos);
264265
bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags);
265266
void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len);
266267
int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,

0 commit comments

Comments
 (0)