summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason2010-05-26 16:59:53 +0200
committerChris Mason2010-05-26 16:59:53 +0200
commit3f7c579c41a3d20af76fd6ff1f6b949edf105fd1 (patch)
tree374d50346763fb37299f5de93f48901596f21e59 /fs/btrfs/inode.c
parentBtrfs: rework O_DIRECT enospc handling (diff)
downloadkernel-qcow2-linux-3f7c579c41a3d20af76fd6ff1f6b949edf105fd1.tar.gz
kernel-qcow2-linux-3f7c579c41a3d20af76fd6ff1f6b949edf105fd1.tar.xz
kernel-qcow2-linux-3f7c579c41a3d20af76fd6ff1f6b949edf105fd1.zip
Btrfs: move O_DIRECT space reservation to btrfs_direct_IO
This moves the delalloc space reservation done for O_DIRECT into btrfs_direct_IO. This way we don't leak reserved space if the generic O_DIRECT write code errors out before it calls into btrfs_direct_IO. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 00aefbdcc2df..ca9d5501d340 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5602,9 +5602,16 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
ssize_t ret;
int writing = rw & WRITE;
int write_bits = 0;
+ size_t count = iov_length(iov, nr_segs);
lockstart = offset;
- lockend = offset + iov_length(iov, nr_segs) - 1;
+ lockend = offset + count - 1;
+
+ if (writing) {
+ ret = btrfs_delalloc_reserve_space(inode, count);
+ if (ret)
+ goto out;
+ }
while (1) {
lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend,