Skip to content

Commit 4ee7722

Browse files
committed
Merge tag 'zonefs-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs
Pull zonefs fixes from Damien Le Moal: - Make sure to always invalidate the last page of an inode straddling inode->i_size to avoid data inconsistencies with appended data when the device zone write granularity does not match the page size. - Do not propagate iomap -ENOBLK error to userspace and use -EBUSY instead. * tag 'zonefs-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs: zonefs: Do not propagate iomap_dio_rw() ENOTBLK error to user space zonefs: Always invalidate last cached page on append write
2 parents ffe78bb + 77af13b commit 4ee7722

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

fs/zonefs/file.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
382382
struct zonefs_zone *z = zonefs_inode_zone(inode);
383383
struct block_device *bdev = inode->i_sb->s_bdev;
384384
unsigned int max = bdev_max_zone_append_sectors(bdev);
385+
pgoff_t start, end;
385386
struct bio *bio;
386387
ssize_t size = 0;
387388
int nr_pages;
@@ -390,6 +391,19 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
390391
max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
391392
iov_iter_truncate(from, max);
392393

394+
/*
395+
* If the inode block size (zone write granularity) is smaller than the
396+
* page size, we may be appending data belonging to the last page of the
397+
* inode straddling inode->i_size, with that page already cached due to
398+
* a buffered read or readahead. So make sure to invalidate that page.
399+
* This will always be a no-op for the case where the block size is
400+
* equal to the page size.
401+
*/
402+
start = iocb->ki_pos >> PAGE_SHIFT;
403+
end = (iocb->ki_pos + iov_iter_count(from) - 1) >> PAGE_SHIFT;
404+
if (invalidate_inode_pages2_range(inode->i_mapping, start, end))
405+
return -EBUSY;
406+
393407
nr_pages = iov_iter_npages(from, BIO_MAX_VECS);
394408
if (!nr_pages)
395409
return 0;
@@ -567,11 +581,21 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
567581
append = sync;
568582
}
569583

570-
if (append)
584+
if (append) {
571585
ret = zonefs_file_dio_append(iocb, from);
572-
else
586+
} else {
587+
/*
588+
* iomap_dio_rw() may return ENOTBLK if there was an issue with
589+
* page invalidation. Overwrite that error code with EBUSY to
590+
* be consistent with zonefs_file_dio_append() return value for
591+
* similar issues.
592+
*/
573593
ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
574594
&zonefs_write_dio_ops, 0, NULL, 0);
595+
if (ret == -ENOTBLK)
596+
ret = -EBUSY;
597+
}
598+
575599
if (zonefs_zone_is_seq(z) &&
576600
(ret > 0 || ret == -EIOCBQUEUED)) {
577601
if (ret > 0)

0 commit comments

Comments
 (0)