diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2015-04-10 18:50:50 -0700 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-08-28 19:15:14 -0800 |
commit | 52e8659d75c93399ac99cf079ab602676824cf19 (patch) | |
tree | 9203ce889c1f1c574ea44f11d6c70470b7d9f2e3 | |
parent | 5db6cab6185caf43b4ba6ed4078a9db2ea38710a (diff) |
bcachefs: async fsync
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | drivers/md/bcache/fs-io.c | 52 | ||||
-rw-r--r-- | drivers/md/bcache/fs-io.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/fs.c | 1 |
3 files changed, 54 insertions, 0 deletions
diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c index 651f39dd9e96..b0079b2e6740 100644 --- a/drivers/md/bcache/fs-io.c +++ b/drivers/md/bcache/fs-io.c @@ -1626,6 +1626,58 @@ int bch_fsync(struct file *file, loff_t start, loff_t end, int datasync) return bch_journal_flush_seq(&c->journal, ei->journal_seq); } +struct bch_aio_fsync_op { + struct closure cl; + struct kiocb *req; +}; + +static void bch_aio_fsync_done(struct closure *cl) +{ + struct bch_aio_fsync_op *op = + container_of(cl, struct bch_aio_fsync_op, cl); + struct kiocb *req = op->req; + struct cache_set *c = req->ki_filp->f_inode->i_sb->s_fs_info; + + req->ki_complete(req, bch_journal_error(&c->journal), 0); + kfree(op); +} + +int bch_aio_fsync(struct kiocb *req, int datasync) +{ + struct file *file = req->ki_filp; + struct inode *inode = file->f_inode; + struct bch_inode_info *ei = to_bch_ei(inode); + struct cache_set *c = inode->i_sb->s_fs_info; + struct bch_aio_fsync_op *op; + int ret; + + ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX); + if (ret) + return ret; + + mutex_lock(&inode->i_mutex); + if (!(inode->i_state & I_DIRTY)) + goto out; + if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) + goto out; + + ret = sync_inode_metadata(inode, 1); +out: + mutex_unlock(&inode->i_mutex); + + op = kmalloc(sizeof(*op), GFP_NOIO); + if (!op) + return bch_fsync(file, 0, LLONG_MAX, datasync); + + closure_init(&op->cl, NULL); + op->req = req; + + bch_journal_flush_seq_async(&c->journal, ei->journal_seq, &op->cl); + closure_return_with_destructor_noreturn(&op->cl, bch_aio_fsync_done); + + return -EIOCBQUEUED; +} + static int __bch_truncate_page(struct address_space *mapping, pgoff_t index, loff_t start, loff_t end) { diff --git a/drivers/md/bcache/fs-io.h b/drivers/md/bcache/fs-io.h index d598bc8431be..3cf76b2f9d8f 100644 --- a/drivers/md/bcache/fs-io.h +++ b/drivers/md/bcache/fs-io.h @@ -23,6 +23,7 @@ ssize_t bch_direct_IO(struct kiocb *, struct iov_iter *); ssize_t bch_write_iter(struct kiocb *, struct iov_iter *); int bch_fsync(struct file *, loff_t, loff_t, int); +int bch_aio_fsync(struct kiocb *, int); int bch_truncate(struct inode *, struct iattr *); long bch_fallocate_dispatch(struct file *, int, loff_t, loff_t); diff --git a/drivers/md/bcache/fs.c b/drivers/md/bcache/fs.c index 3ce40da5e84e..2493f5ff9884 100644 --- a/drivers/md/bcache/fs.c +++ b/drivers/md/bcache/fs.c @@ -903,6 +903,7 @@ static const struct file_operations bch_file_operations = { .mmap = bch_mmap, .open = generic_file_open, .fsync = bch_fsync, + .aio_fsync = bch_aio_fsync, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, .fallocate = bch_fallocate_dispatch, |