diff options
-rw-r--r-- | fs/bcachefs/data_update.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 59 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 44 | ||||
-rw-r--r-- | fs/bcachefs/io.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/io_types.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/reflink.c | 2 |
6 files changed, 64 insertions, 50 deletions
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c index 658868048c22..9d1290ff179a 100644 --- a/fs/bcachefs/data_update.c +++ b/fs/bcachefs/data_update.c @@ -226,7 +226,7 @@ int bch2_data_update_index_update(struct bch_write_op *op) bch2_trans_update(&trans, &iter, insert, BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?: bch2_trans_commit(&trans, &op->res, - &op->journal_seq, + NULL, BTREE_INSERT_NOFAIL| m->data_opts.btree_insert_flags); if (!ret) { @@ -320,7 +320,6 @@ int bch2_data_update_init(struct bch_fs *c, struct data_update *m, m->op.flags |= BCH_WRITE_PAGES_STABLE| BCH_WRITE_PAGES_OWNED| BCH_WRITE_DATA_ENCODED| - BCH_WRITE_FROM_INTERNAL| BCH_WRITE_MOVE| m->data_opts.write_flags; m->op.compression_type = diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index dff103a66780..3c3fa95215ac 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -78,6 +78,7 @@ struct dio_write { struct mm_struct *mm; unsigned loop:1, sync:1, + flush:1, free_iov:1; struct quota_res quota_res; u64 written; @@ -2056,6 +2057,9 @@ static noinline bool bch2_dio_write_check_allocated(struct dio_write *dio) dio->op.opts.compression != 0); } +static void bch2_dio_write_loop_async(struct bch_write_op *); +static __always_inline long bch2_dio_write_done(struct dio_write *dio); + /* * We're going to return -EIOCBQUEUED, but we haven't finished consuming the * iov_iter yet, so we need to stash a copy of the iovec: it might be on the @@ -2093,7 +2097,43 @@ static noinline int bch2_dio_write_copy_iov(struct dio_write *dio) return 0; } -static void bch2_dio_write_loop_async(struct bch_write_op *); +static void bch2_dio_write_flush_done(struct closure *cl) +{ + struct dio_write *dio = container_of(cl, struct dio_write, op.cl); + struct bch_fs *c = dio->op.c; + + closure_debug_destroy(cl); + + dio->op.error = bch2_journal_error(&c->journal); + + bch2_dio_write_done(dio); +} + +static noinline void bch2_dio_write_flush(struct dio_write *dio) +{ + struct bch_fs *c = dio->op.c; + struct bch_inode_unpacked inode; + int ret; + + dio->flush = 0; + + closure_init(&dio->op.cl, NULL); + + if (!dio->op.error) { + ret = bch2_inode_find_by_inum(c, inode_inum(dio->inode), &inode); + if (ret) + dio->op.error = ret; + else + bch2_journal_flush_seq_async(&c->journal, inode.bi_journal_seq, &dio->op.cl); + } + + if (dio->sync) { + closure_sync(&dio->op.cl); + closure_debug_destroy(&dio->op.cl); + } else { + continue_at(&dio->op.cl, bch2_dio_write_flush_done, NULL); + } +} static __always_inline long bch2_dio_write_done(struct dio_write *dio) { @@ -2101,13 +2141,21 @@ static __always_inline long bch2_dio_write_done(struct dio_write *dio) struct kiocb *req = dio->req; struct bch_inode_info *inode = dio->inode; bool sync = dio->sync; - long ret = dio->op.error ?: ((long) dio->written << 9); + long ret; + + if (unlikely(dio->flush)) { + bch2_dio_write_flush(dio); + if (!sync) + return -EIOCBQUEUED; + } bch2_pagecache_block_put(&inode->ei_pagecache_lock); bch2_quota_reservation_put(c, inode, &dio->quota_res); if (dio->free_iov) kfree(dio->iter.__iov); + + ret = dio->op.error ?: ((long) dio->written << 9); bio_put(&dio->op.wbio.bio); /* inode->i_dio_count is our ref on inode and thus bch_fs */ @@ -2215,9 +2263,6 @@ static long bch2_dio_write_loop(struct dio_write *dio) if (sync) dio->op.flags |= BCH_WRITE_SYNC; - if ((req->ki_flags & IOCB_DSYNC) && - !c->opts.journal_flush_disabled) - dio->op.flags |= BCH_WRITE_FLUSH; dio->op.flags |= BCH_WRITE_CHECK_ENOSPC; ret = bch2_disk_reservation_get(c, &dio->op.res, bio_sectors(bio), @@ -2332,6 +2377,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter) dio->mm = current->mm; dio->loop = false; dio->sync = is_sync_kiocb(req) || extending; + dio->flush = iocb_is_dsync(req) && !c->opts.journal_flush_disabled; dio->free_iov = false; dio->quota_res.sectors = 0; dio->written = 0; @@ -3050,8 +3096,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, } ret = bch2_extent_update(&trans, inode_inum(inode), &iter, - &reservation.k_i, - &disk_res, NULL, + &reservation.k_i, &disk_res, 0, &i_sectors_delta, true); if (ret) goto bkey_err; diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index e754f57c1342..701bfc8ce0e4 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -273,7 +273,6 @@ int bch2_extent_update(struct btree_trans *trans, struct btree_iter *iter, struct bkey_i *k, struct disk_reservation *disk_res, - u64 *journal_seq, u64 new_i_size, s64 *i_sectors_delta_total, bool check_enospc) @@ -374,7 +373,7 @@ int bch2_extent_update(struct btree_trans *trans, } ret = bch2_trans_update(trans, iter, k, 0) ?: - bch2_trans_commit(trans, disk_res, journal_seq, + bch2_trans_commit(trans, disk_res, NULL, BTREE_INSERT_NOCHECK_RW| BTREE_INSERT_NOFAIL); err: @@ -438,8 +437,7 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter, bch2_cut_back(end_pos, &delete); ret = bch2_extent_update(trans, inum, iter, &delete, - &disk_res, NULL, - 0, i_sectors_delta, false); + &disk_res, 0, i_sectors_delta, false); bch2_disk_reservation_put(c, &disk_res); } @@ -507,7 +505,7 @@ static int bch2_write_index_default(struct bch_write_op *op) BTREE_ITER_SLOTS|BTREE_ITER_INTENT); ret = bch2_extent_update(&trans, inum, &iter, sk.k, - &op->res, &op->journal_seq, + &op->res, op->new_i_size, &op->i_sectors_delta, op->flags & BCH_WRITE_CHECK_ENOSPC); bch2_trans_iter_exit(&trans, &iter); @@ -596,14 +594,11 @@ void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c, static void __bch2_write(struct bch_write_op *); -static void __bch2_write_done(struct closure *cl) +static void bch2_write_done(struct closure *cl) { struct bch_write_op *op = container_of(cl, struct bch_write_op, cl); struct bch_fs *c = op->c; - if (!op->error && (op->flags & BCH_WRITE_FLUSH)) - op->error = bch2_journal_error(&c->journal); - bch2_disk_reservation_put(c, &op->res); percpu_ref_put(&c->writes); bch2_keylist_free(&op->insert_keys, op->inline_keys); @@ -616,21 +611,6 @@ static void __bch2_write_done(struct closure *cl) op->end_io(op); } -static __always_inline void bch2_write_done(struct bch_write_op *op) -{ - if (likely(!(op->flags & BCH_WRITE_FLUSH) || op->error)) { - __bch2_write_done(&op->cl); - } else if (!(op->flags & BCH_WRITE_SYNC)) { - bch2_journal_flush_seq_async(&op->c->journal, - op->journal_seq, - &op->cl); - continue_at(&op->cl, __bch2_write_done, index_update_wq(op)); - } else { - bch2_journal_flush_seq(&op->c->journal, op->journal_seq); - __bch2_write_done(&op->cl); - } -} - static noinline int bch2_write_drop_io_error_ptrs(struct bch_write_op *op) { struct keylist *keys = &op->insert_keys; @@ -789,16 +769,10 @@ unlock: __bch2_write_index(op); - if (!(op->flags & BCH_WRITE_DONE)) { + if (!(op->flags & BCH_WRITE_DONE)) __bch2_write(op); - } else if (!op->error && (op->flags & BCH_WRITE_FLUSH)) { - bch2_journal_flush_seq_async(&op->c->journal, - op->journal_seq, - &op->cl); - continue_at(&op->cl, __bch2_write_done, index_update_wq(op)); - } else { - __bch2_write_done(&op->cl); - } + else + bch2_write_done(&op->cl); } } @@ -1347,7 +1321,7 @@ err: if (!(op->flags & BCH_WRITE_DONE)) goto again; - bch2_write_done(op); + bch2_write_done(&op->cl); } else { continue_at(&op->cl, bch2_write_index, NULL); } @@ -1395,7 +1369,7 @@ static void bch2_write_data_inline(struct bch_write_op *op, unsigned data_len) __bch2_write_index(op); err: - bch2_write_done(op); + bch2_write_done(&op->cl); } /** diff --git a/fs/bcachefs/io.h b/fs/bcachefs/io.h index 9322484135f9..faf2c2057828 100644 --- a/fs/bcachefs/io.h +++ b/fs/bcachefs/io.h @@ -31,7 +31,6 @@ const char *bch2_blk_status_to_str(blk_status_t); enum bch_write_flags { __BCH_WRITE_ALLOC_NOWAIT, __BCH_WRITE_CACHED, - __BCH_WRITE_FLUSH, __BCH_WRITE_DATA_ENCODED, __BCH_WRITE_PAGES_STABLE, __BCH_WRITE_PAGES_OWNED, @@ -48,7 +47,6 @@ enum bch_write_flags { #define BCH_WRITE_ALLOC_NOWAIT (1U << __BCH_WRITE_ALLOC_NOWAIT) #define BCH_WRITE_CACHED (1U << __BCH_WRITE_CACHED) -#define BCH_WRITE_FLUSH (1U << __BCH_WRITE_FLUSH) #define BCH_WRITE_DATA_ENCODED (1U << __BCH_WRITE_DATA_ENCODED) #define BCH_WRITE_PAGES_STABLE (1U << __BCH_WRITE_PAGES_STABLE) #define BCH_WRITE_PAGES_OWNED (1U << __BCH_WRITE_PAGES_OWNED) @@ -75,7 +73,7 @@ int bch2_sum_sector_overwrites(struct btree_trans *, struct btree_iter *, struct bkey_i *, bool *, bool *, s64 *, s64 *); int bch2_extent_update(struct btree_trans *, subvol_inum, struct btree_iter *, struct bkey_i *, - struct disk_reservation *, u64 *, u64, s64 *, bool); + struct disk_reservation *, u64, s64 *, bool); int bch2_fpunch_at(struct btree_trans *, struct btree_iter *, subvol_inum, u64, s64 *); @@ -104,7 +102,6 @@ static inline void bch2_write_op_init(struct bch_write_op *op, struct bch_fs *c, op->version = ZERO_VERSION; op->write_point = (struct write_point_specifier) { 0 }; op->res = (struct disk_reservation) { 0 }; - op->journal_seq = 0; op->new_i_size = U64_MAX; op->i_sectors_delta = 0; } diff --git a/fs/bcachefs/io_types.h b/fs/bcachefs/io_types.h index 685fb1183399..b31f2a22f098 100644 --- a/fs/bcachefs/io_types.h +++ b/fs/bcachefs/io_types.h @@ -142,7 +142,6 @@ struct bch_write_op { struct open_buckets open_buckets; - u64 journal_seq; u64 new_i_size; s64 i_sectors_delta; diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c index d5c14bb2992d..0d4c004d7f9d 100644 --- a/fs/bcachefs/reflink.c +++ b/fs/bcachefs/reflink.c @@ -378,7 +378,7 @@ s64 bch2_remap_range(struct bch_fs *c, dst_end.offset - dst_iter.pos.offset)); ret = bch2_extent_update(&trans, dst_inum, &dst_iter, - new_dst.k, &disk_res, NULL, + new_dst.k, &disk_res, new_i_size, i_sectors_delta, true); bch2_disk_reservation_put(c, &disk_res); |