Btrfs: move O_DIRECT space reservation to btrfs_direct_IO
authorChris Mason <chris.mason@oracle.com>
Wed, 26 May 2010 14:59:53 +0000 (10:59 -0400)
committerChris Mason <chris.mason@oracle.com>
Wed, 26 May 2010 14:59:53 +0000 (10:59 -0400)
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>
fs/btrfs/file.c
fs/btrfs/inode.c

index 54556cae449755ffa4c57d53ec9704a14c280f8e..79437c5eeb1efcfd0ca484799d0f79fa525709d9 100644 (file)
@@ -888,14 +888,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        BTRFS_I(inode)->sequence++;
 
        if (unlikely(file->f_flags & O_DIRECT)) {
-               ret = btrfs_delalloc_reserve_space(inode, count);
-               if (ret)
-                       goto out;
-
                num_written = generic_file_direct_write(iocb, iov, &nr_segs,
                                                        pos, ppos, count,
                                                        ocount);
-
                /*
                 * the generic O_DIRECT will update in-memory i_size after the
                 * DIOs are done.  But our endio handlers that update the on
index 00aefbdcc2dfabca958a56a34a3b80ae432e7499..ca9d5501d3400efe9716d6722d9260e0be8ba441 100644 (file)
@@ -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,