summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/data_update.c3
-rw-r--r--fs/bcachefs/fs-io.c59
-rw-r--r--fs/bcachefs/io.c44
-rw-r--r--fs/bcachefs/io.h5
-rw-r--r--fs/bcachefs/io_types.h1
-rw-r--r--fs/bcachefs/reflink.c2
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);