struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work);
/* Metadata reads are checked and repaired by the submitter. */
- if (is_data_bbio(bbio))
+ if (bio_op(&bbio->bio) == REQ_OP_READ && is_data_bbio(bbio))
btrfs_check_read_bio(bbio, bbio->bio.bi_private);
else
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
if (bio->bi_status)
btrfs_log_dev_io_error(bio, dev);
- if (bio_op(bio) == REQ_OP_READ) {
+ if (bio_op(bio) == REQ_OP_READ || bbio->uncached_io) {
INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work);
queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);
} else {
ASSERT(bio_ctrl->end_io_func);
if (bio_ctrl->bbio &&
- !btrfs_bio_is_contig(bio_ctrl, folio, disk_bytenr, pg_offset))
+ !btrfs_bio_is_contig(bio_ctrl, folio, disk_bytenr, pg_offset)) {
+ if (folio_test_uncached(folio))
+ bio_ctrl->bbio->uncached_io = true;
submit_one_bio(bio_ctrl);
+ }
do {
u32 len = size;
len = bio_ctrl->len_to_oe_boundary;
}
+ if (folio_test_uncached(folio))
+ bio_ctrl->bbio->uncached_io = true;
+
if (!bio_add_folio(&bio_ctrl->bbio->bio, folio, len, pg_offset)) {
/* bio full: move on to a new one */
submit_one_bio(bio_ctrl);
static noinline int prepare_pages(struct inode *inode, struct page **pages,
size_t num_pages, loff_t pos,
size_t write_bytes, bool force_uptodate,
- bool nowait)
+ bool nowait, bool uncached)
{
int i;
unsigned long index = pos >> PAGE_SHIFT;
int ret = 0;
int faili;
+ if (uncached)
+ fgp_flags |= FGP_UNCACHED;
for (i = 0; i < num_pages; i++) {
again:
pages[i] = pagecache_get_page(inode->i_mapping, index + i,
* contents of pages from loop to loop
*/
ret = prepare_pages(inode, pages, num_pages,
- pos, write_bytes, force_page_uptodate, false);
+ pos, write_bytes, force_page_uptodate,
+ false, iocb->ki_flags & IOCB_UNCACHED);
if (ret) {
btrfs_delalloc_release_extents(BTRFS_I(inode),
reserve_bytes);
btrfs_set_inode_last_sub_trans(inode);
if (num_sync > 0) {
+ generic_uncached_write(iocb, num_sync);
num_sync = generic_write_sync(iocb, num_sync);
if (num_sync < 0)
num_written = num_sync;
.compat_ioctl = btrfs_compat_ioctl,
#endif
.remap_file_range = btrfs_remap_file_range,
- .fop_flags = FOP_BUFFER_RASYNC | FOP_BUFFER_WASYNC,
+ .fop_flags = FOP_BUFFER_RASYNC | FOP_BUFFER_WASYNC | FOP_UNCACHED,
};
int btrfs_fdatawrite_range(struct btrfs_inode *inode, loff_t start, loff_t end)