Skip to content

Commit 9e203c4

Browse files
author
Kent Overstreet
committed
bcachefs: Fix missing write refs in fs fio paths
bch2_journal_flush_seq requires us to have a write ref Signed-off-by: Kent Overstreet <[email protected]>
1 parent 82cf18f commit 9e203c4

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ struct btree_trans_buf {
709709
x(stripe_delete) \
710710
x(reflink) \
711711
x(fallocate) \
712+
x(fsync) \
713+
x(dio_write) \
712714
x(discard) \
713715
x(discard_fast) \
714716
x(invalidate) \

fs/bcachefs/fs-io-direct.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ static __always_inline long bch2_dio_write_done(struct dio_write *dio)
387387
ret = dio->op.error ?: ((long) dio->written << 9);
388388
bio_put(&dio->op.wbio.bio);
389389

390+
bch2_write_ref_put(dio->op.c, BCH_WRITE_REF_dio_write);
391+
390392
/* inode->i_dio_count is our ref on inode and thus bch_fs */
391393
inode_dio_end(&inode->v);
392394

@@ -590,22 +592,25 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
590592
prefetch(&inode->ei_inode);
591593
prefetch((void *) &inode->ei_inode + 64);
592594

595+
if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_dio_write))
596+
return -EROFS;
597+
593598
inode_lock(&inode->v);
594599

595600
ret = generic_write_checks(req, iter);
596601
if (unlikely(ret <= 0))
597-
goto err;
602+
goto err_put_write_ref;
598603

599604
ret = file_remove_privs(file);
600605
if (unlikely(ret))
601-
goto err;
606+
goto err_put_write_ref;
602607

603608
ret = file_update_time(file);
604609
if (unlikely(ret))
605-
goto err;
610+
goto err_put_write_ref;
606611

607612
if (unlikely((req->ki_pos|iter->count) & (block_bytes(c) - 1)))
608-
goto err;
613+
goto err_put_write_ref;
609614

610615
inode_dio_begin(&inode->v);
611616
bch2_pagecache_block_get(inode);
@@ -645,15 +650,17 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
645650
}
646651

647652
ret = bch2_dio_write_loop(dio);
648-
err:
653+
out:
649654
if (locked)
650655
inode_unlock(&inode->v);
651656
return ret;
652657
err_put_bio:
653658
bch2_pagecache_block_put(inode);
654659
bio_put(bio);
655660
inode_dio_end(&inode->v);
656-
goto err;
661+
err_put_write_ref:
662+
bch2_write_ref_put(c, BCH_WRITE_REF_dio_write);
663+
goto out;
657664
}
658665

659666
void bch2_fs_fs_io_direct_exit(struct bch_fs *c)

fs/bcachefs/fs-io.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,18 +174,18 @@ void __bch2_i_sectors_acct(struct bch_fs *c, struct bch_inode_info *inode,
174174
static int bch2_flush_inode(struct bch_fs *c,
175175
struct bch_inode_info *inode)
176176
{
177-
struct bch_inode_unpacked u;
178-
int ret;
179-
180177
if (c->opts.journal_flush_disabled)
181178
return 0;
182179

183-
ret = bch2_inode_find_by_inum(c, inode_inum(inode), &u);
184-
if (ret)
185-
return ret;
180+
if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_fsync))
181+
return -EROFS;
186182

187-
return bch2_journal_flush_seq(&c->journal, u.bi_journal_seq) ?:
188-
bch2_inode_flush_nocow_writes(c, inode);
183+
struct bch_inode_unpacked u;
184+
int ret = bch2_inode_find_by_inum(c, inode_inum(inode), &u) ?:
185+
bch2_journal_flush_seq(&c->journal, u.bi_journal_seq) ?:
186+
bch2_inode_flush_nocow_writes(c, inode);
187+
bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
188+
return ret;
189189
}
190190

191191
int bch2_fsync(struct file *file, loff_t start, loff_t end, int datasync)

0 commit comments

Comments
 (0)