]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
btrfs: extent-tree: Switch to new check_data_free_space and free_reserved_data_space
authorQu Wenruo <quwenruo@cn.fujitsu.com>
Tue, 8 Sep 2015 09:22:43 +0000 (17:22 +0800)
committerChris Mason <clm@fb.com>
Thu, 22 Oct 2015 01:41:04 +0000 (18:41 -0700)
Use new reserve/free for buffered write and inode cache.

For buffered write case, as nodatacow write won't increase quota account,
so unlike old behavior which does reserve before check nocow, now we
check nocow first and then only reserve data if we can't do nocow write.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/relocation.c

index 71c172e12b190d57cbc2a634caaa98838a792b28..3c58fc34aa107660e04d634d935a4dbb0b7f540d 100644 (file)
@@ -3356,7 +3356,7 @@ again:
        num_pages *= 16;
        num_pages *= PAGE_CACHE_SIZE;
 
-       ret = btrfs_check_data_free_space(inode, num_pages, num_pages);
+       ret = __btrfs_check_data_free_space(inode, 0, num_pages);
        if (ret)
                goto out_put;
 
@@ -3365,7 +3365,7 @@ again:
                                              &alloc_hint);
        if (!ret)
                dcs = BTRFS_DC_SETUP;
-       btrfs_free_reserved_data_space(inode, num_pages);
+       __btrfs_free_reserved_data_space(inode, 0, num_pages);
 
 out_put:
        iput(inode);
index 7031e9631519523d3c933c2190e724e85723c8b7..61fb78f1ea5c88c2acc1881b24c90e80a7425b1b 100644 (file)
@@ -1507,12 +1507,17 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
                }
 
                reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
-               ret = btrfs_check_data_free_space(inode, reserve_bytes, write_bytes);
-               if (ret == -ENOSPC &&
-                   (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
-                                             BTRFS_INODE_PREALLOC))) {
+
+               if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
+                                            BTRFS_INODE_PREALLOC)) {
                        ret = check_can_nocow(inode, pos, &write_bytes);
+                       if (ret < 0)
+                               break;
                        if (ret > 0) {
+                               /*
+                                * For nodata cow case, no need to reserve
+                                * data space.
+                                */
                                only_release_metadata = true;
                                /*
                                 * our prealloc extent may be smaller than
@@ -1521,20 +1526,19 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
                                num_pages = DIV_ROUND_UP(write_bytes + offset,
                                                         PAGE_CACHE_SIZE);
                                reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
-                               ret = 0;
-                       } else {
-                               ret = -ENOSPC;
+                               goto reserve_metadata;
                        }
                }
-
-               if (ret)
+               ret = __btrfs_check_data_free_space(inode, pos, write_bytes);
+               if (ret < 0)
                        break;
 
+reserve_metadata:
                ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
                if (ret) {
                        if (!only_release_metadata)
-                               btrfs_free_reserved_data_space(inode,
-                                                              reserve_bytes);
+                               __btrfs_free_reserved_data_space(inode, pos,
+                                                                write_bytes);
                        else
                                btrfs_end_write_no_snapshoting(root);
                        break;
@@ -2566,8 +2570,11 @@ static long btrfs_fallocate(struct file *file, int mode,
        /*
         * Make sure we have enough space before we do the
         * allocation.
+        * XXX: The behavior must be changed to do accurate check first
+        * and then check data reserved space.
         */
-       ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start, alloc_end - alloc_start);
+       ret = btrfs_check_data_free_space(inode, alloc_start,
+                                         alloc_end - alloc_start);
        if (ret)
                return ret;
 
@@ -2700,7 +2707,8 @@ static long btrfs_fallocate(struct file *file, int mode,
 out:
        mutex_unlock(&inode->i_mutex);
        /* Let go of our reservation. */
-       btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
+       __btrfs_free_reserved_data_space(inode, alloc_start,
+                                        alloc_end - alloc_start);
        return ret;
 }
 
index 58ede0a564569ed082f09f4015229ab2cfd89f85..490c9e298c5804cd44cc3a372e470e67b2691dfa 100644 (file)
@@ -3034,8 +3034,8 @@ int prealloc_file_extent_cluster(struct inode *inode,
        BUG_ON(cluster->start != cluster->boundary[0]);
        mutex_lock(&inode->i_mutex);
 
-       ret = btrfs_check_data_free_space(inode, cluster->end +
-                                         1 - cluster->start, 0);
+       ret = __btrfs_check_data_free_space(inode, cluster->start,
+                                           cluster->end + 1 - cluster->start);
        if (ret)
                goto out;
 
@@ -3056,8 +3056,8 @@ int prealloc_file_extent_cluster(struct inode *inode,
                        break;
                nr++;
        }
-       btrfs_free_reserved_data_space(inode, cluster->end +
-                                      1 - cluster->start);
+       __btrfs_free_reserved_data_space(inode, cluster->start,
+                                        cluster->end + 1 - cluster->start);
 out:
        mutex_unlock(&inode->i_mutex);
        return ret;