diff options
Diffstat (limited to 'fs/iomap')
| -rw-r--r-- | fs/iomap/bio.c | 13 | ||||
| -rw-r--r-- | fs/iomap/buffered-io.c | 2 | ||||
| -rw-r--r-- | fs/iomap/direct-io.c | 7 | ||||
| -rw-r--r-- | fs/iomap/ioend.c | 8 |
4 files changed, 23 insertions, 7 deletions
diff --git a/fs/iomap/bio.c b/fs/iomap/bio.c index 4504f4633f17..0f31e35567b4 100644 --- a/fs/iomap/bio.c +++ b/fs/iomap/bio.c @@ -78,15 +78,23 @@ u32 iomap_finish_ioend_buffered_read(struct iomap_ioend *ioend) return __iomap_read_end_io(&ioend->io_bio, ioend->io_error); } -static void iomap_bio_submit_read(const struct iomap_iter *iter, - struct iomap_read_folio_ctx *ctx) +void iomap_bio_submit_read_endio(const struct iomap_iter *iter, + struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io) { struct bio *bio = ctx->read_ctx; + bio->bi_end_io = end_io; if (iter->iomap.flags & IOMAP_F_INTEGRITY) fs_bio_integrity_alloc(bio); submit_bio(bio); } +EXPORT_SYMBOL_GPL(iomap_bio_submit_read_endio); + +static void iomap_bio_submit_read(const struct iomap_iter *iter, + struct iomap_read_folio_ctx *ctx) +{ + return iomap_bio_submit_read_endio(iter, ctx, iomap_read_end_io); +} static struct bio_set *iomap_read_bio_set(struct iomap_read_folio_ctx *ctx) { @@ -127,7 +135,6 @@ static void iomap_read_alloc_bio(const struct iomap_iter *iter, if (ctx->rac) bio->bi_opf |= REQ_RAHEAD; bio->bi_iter.bi_sector = iomap_sector(iomap, iter->pos); - bio->bi_end_io = iomap_read_end_io; bio_add_folio_nofail(bio, folio, plen, offset_in_folio(folio, iter->pos)); ctx->read_ctx = bio; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index d55b936e6986..5fa9a2c7e30e 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -850,7 +850,7 @@ static int __iomap_write_begin(const struct iomap_iter *iter, if (status < 0) fserror_report_io(iter->inode, FSERR_BUFFERED_READ, pos, - len, status, GFP_NOFS); + plen, status, GFP_NOFS); if (status) return status; } diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index b36ee619cdcd..9fedf367c3eb 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -369,7 +369,7 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter, */ if ((op & REQ_ATOMIC) && WARN_ON_ONCE(ret != iomap_length(iter))) { ret = -EINVAL; - goto out_put_bio; + goto out_bio_release_pages; } if (iter->iomap.flags & IOMAP_F_INTEGRITY) { @@ -393,6 +393,11 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter, iomap_dio_submit_bio(iter, dio, bio, pos); return ret; +out_bio_release_pages: + if (dio->flags & IOMAP_DIO_BOUNCE) + bio_iov_iter_unbounce(bio, true, false); + else + bio_release_pages(bio, false); out_put_bio: bio_put(bio); return ret; diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c index acf3cf98b23a..2d5611f6cc57 100644 --- a/fs/iomap/ioend.c +++ b/fs/iomap/ioend.c @@ -297,8 +297,12 @@ new_ioend: * appending writes. */ ioend->io_size += map_len; - if (ioend->io_offset + ioend->io_size > end_pos) - ioend->io_size = end_pos - ioend->io_offset; + if (ioend->io_offset + ioend->io_size > end_pos) { + if (ioend->io_offset >= end_pos) + ioend->io_size = 0; + else + ioend->io_size = end_pos - ioend->io_offset; + } wbc_account_cgroup_owner(wpc->wbc, folio, map_len); return map_len; |
