summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-02-20 02:17:49 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:35:39 -0800
commita708990596a176bb21424005e3e935b9822050c7 (patch)
tree1a498f6215c439d92c4db57440107db8d5af339c
parent891038a270f84280debeb8183fcdab01e5d8ad7f (diff)
bcachefs: don't use BCH_WRITE_CHECK_ENOSPC in dio write path
-rw-r--r--drivers/md/bcache/fs-io.c23
-rw-r--r--drivers/md/bcache/fs-io.h1
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c
index 8cd99b972012..95403ffd6312 100644
--- a/drivers/md/bcache/fs-io.c
+++ b/drivers/md/bcache/fs-io.c
@@ -1330,7 +1330,11 @@ out:
static void __bch_dio_write_complete(struct dio_write *dio)
{
- struct bch_inode_info *ei = to_bch_ei(dio->req->ki_filp->f_inode);
+ struct inode *inode = dio->req->ki_filp->f_inode;
+ struct bch_inode_info *ei = to_bch_ei(inode);
+ struct cache_set *c = inode->i_sb->s_fs_info;
+
+ atomic64_sub_bug(dio->nr_sectors, &c->sectors_reserved);
i_sectors_dirty_put(ei, &dio->i_sectors_hook);
@@ -1376,7 +1380,7 @@ static void bch_do_direct_IO_write(struct dio_write *dio, bool sync)
struct bch_inode_info *ei = to_bch_ei(inode);
struct cache_set *c = inode->i_sb->s_fs_info;
struct bio *bio = &dio->bio.bio.bio;
- unsigned flags = BCH_WRITE_CHECK_ENOSPC;
+ unsigned flags = 0;
int ret;
if (file->f_flags & O_DSYNC || IS_SYNC(file->f_mapping->host))
@@ -1455,6 +1459,7 @@ static int bch_direct_IO_write(struct cache_set *c, struct kiocb *req,
dio->written = 0;
dio->error = 0;
dio->offset = offset;
+ dio->nr_sectors = iter->count >> 9;
dio->append = false;
dio->iovec = NULL;
dio->iter = *iter;
@@ -1478,6 +1483,18 @@ static int bch_direct_IO_write(struct cache_set *c, struct kiocb *req,
if (ret)
goto err;
+ /*
+ * XXX: we shouldn't return -ENOSPC if we're overwriting existing data -
+ * if getting a reservation fails we should check if we are doing an
+ * overwrite.
+ *
+ * Have to then guard against racing with truncate (deleting data that
+ * we would have been overwriting)
+ */
+ ret = reserve_sectors(c, dio->nr_sectors);
+ if (ret)
+ goto err_put_sectors_dirty;
+
closure_init(&dio->cl, NULL);
inode_dio_begin(inode);
@@ -1548,6 +1565,8 @@ static int bch_direct_IO_write(struct cache_set *c, struct kiocb *req,
dio->iter.count ? system_wq : NULL);
return -EIOCBQUEUED;
}
+err_put_sectors_dirty:
+ i_sectors_dirty_put(ei, &dio->i_sectors_hook);
err:
if (dio->append)
i_size_dirty_put(ei);
diff --git a/drivers/md/bcache/fs-io.h b/drivers/md/bcache/fs-io.h
index 310508d35a89..f701058434de 100644
--- a/drivers/md/bcache/fs-io.h
+++ b/drivers/md/bcache/fs-io.h
@@ -64,6 +64,7 @@ struct dio_write {
long written;
long error;
loff_t offset;
+ unsigned nr_sectors;
bool append;
struct iovec *iovec;