bcachefs: Kill BCH_WRITE_FLUSH
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 3 Nov 2022 04:29:43 +0000 (00:29 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:45 +0000 (17:09 -0400)
BCH_WRITE_FLUSH is a write flag that causes a journal flush.  It's only
used in the direct IO path, and this will allow for some consolidation
with the regular fsync path, which will help with the upcoming nocow
mode.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/data_update.c
fs/bcachefs/fs-io.c
fs/bcachefs/io.c
fs/bcachefs/io.h
fs/bcachefs/io_types.h
fs/bcachefs/reflink.c

index 658868048c22e5deb427ca95e25c61850ff477f2..9d1290ff179a934ef49bb652358b521e22f097c4 100644 (file)
@@ -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 =
index dff103a6678061e4acda4c67612af7b642ff1153..3c3fa95215ac533fab4c6624599cd77e632b14a3 100644 (file)
@@ -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;
index e754f57c134282601d465377f59d154261125ce8..701bfc8ce0e414dc99019a658318cdf3ee800590 100644 (file)
@@ -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);
 }
 
 /**
index 9322484135f928a1e455a2827c63c653c86a0fcf..faf2c2057828b9ba6212822f82d62629bd2b20a0 100644 (file)
@@ -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;
 }
index 685fb118339965d76177b36be625935a16b89b09..b31f2a22f098260612c69ba9802e0228120bd26b 100644 (file)
@@ -142,7 +142,6 @@ struct bch_write_op {
 
        struct open_buckets     open_buckets;
 
-       u64                     journal_seq;
        u64                     new_i_size;
        s64                     i_sectors_delta;
 
index d5c14bb2992d5d7fc4281a207140861a0cdefd1f..0d4c004d7f9dba82132403ff7f4e9ca0dfbb343e 100644 (file)
@@ -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);