btrfs: add the ability to use NO_FLUSH for data reservations
authorJosef Bacik <josef@toxicpanda.com>
Mon, 12 Sep 2022 19:27:44 +0000 (12:27 -0700)
committerDavid Sterba <dsterba@suse.com>
Thu, 29 Sep 2022 15:08:28 +0000 (17:08 +0200)
In order to accommodate NOWAIT IOCB's we need to be able to do NO_FLUSH
data reservations, so plumb this through the delalloc reservation
system.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Stefan Roesch <shr@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c
fs/btrfs/delalloc-space.c
fs/btrfs/delalloc-space.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/space-info.c

index d83bafc..32c415c 100644 (file)
@@ -2850,7 +2850,7 @@ again:
        cache_size *= fs_info->sectorsize;
 
        ret = btrfs_check_data_free_space(BTRFS_I(inode), &data_reserved, 0,
-                                         cache_size);
+                                         cache_size, false);
        if (ret)
                goto out_put;
 
index 1e8f17f..118b2e2 100644 (file)
@@ -127,9 +127,11 @@ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes)
 }
 
 int btrfs_check_data_free_space(struct btrfs_inode *inode,
-                       struct extent_changeset **reserved, u64 start, u64 len)
+                               struct extent_changeset **reserved, u64 start,
+                               u64 len, bool noflush)
 {
        struct btrfs_fs_info *fs_info = inode->root->fs_info;
+       enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_DATA;
        int ret;
 
        /* align the range */
@@ -137,7 +139,12 @@ int btrfs_check_data_free_space(struct btrfs_inode *inode,
              round_down(start, fs_info->sectorsize);
        start = round_down(start, fs_info->sectorsize);
 
-       ret = btrfs_alloc_data_chunk_ondemand(inode, len);
+       if (noflush)
+               flush = BTRFS_RESERVE_NO_FLUSH;
+       else if (btrfs_is_free_space_inode(inode))
+               flush = BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE;
+
+       ret = btrfs_reserve_data_bytes(fs_info, len, flush);
        if (ret < 0)
                return ret;
 
@@ -454,7 +461,7 @@ int btrfs_delalloc_reserve_space(struct btrfs_inode *inode,
 {
        int ret;
 
-       ret = btrfs_check_data_free_space(inode, reserved, start, len);
+       ret = btrfs_check_data_free_space(inode, reserved, start, len, false);
        if (ret < 0)
                return ret;
        ret = btrfs_delalloc_reserve_metadata(inode, len, len, false);
index 28bf5c3..e07d460 100644 (file)
@@ -7,7 +7,8 @@ struct extent_changeset;
 
 int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes);
 int btrfs_check_data_free_space(struct btrfs_inode *inode,
-                       struct extent_changeset **reserved, u64 start, u64 len);
+                       struct extent_changeset **reserved, u64 start, u64 len,
+                       bool noflush);
 void btrfs_free_reserved_data_space(struct btrfs_inode *inode,
                        struct extent_changeset *reserved, u64 start, u64 len);
 void btrfs_delalloc_release_space(struct btrfs_inode *inode,
index 22471f6..94a9b47 100644 (file)
@@ -1663,7 +1663,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
                extent_changeset_release(data_reserved);
                ret = btrfs_check_data_free_space(BTRFS_I(inode),
                                                  &data_reserved, pos,
-                                                 write_bytes);
+                                                 write_bytes, false);
                if (ret < 0) {
                        /*
                         * If we don't have to COW at the offset, reserve
index 92ea0f9..0c92b22 100644 (file)
@@ -4885,7 +4885,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
        block_end = block_start + blocksize - 1;
 
        ret = btrfs_check_data_free_space(inode, &data_reserved, block_start,
-                                         blocksize);
+                                         blocksize, false);
        if (ret < 0) {
                if (btrfs_check_nocow_lock(inode, block_start, &write_bytes) > 0) {
                        /* For nocow case, no need to reserve data space */
@@ -7641,7 +7641,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
        if (write && !(flags & IOMAP_NOWAIT)) {
                ret = btrfs_check_data_free_space(BTRFS_I(inode),
                                                  &dio_data->data_reserved,
-                                                 start, data_alloc_len);
+                                                 start, data_alloc_len, false);
                if (!ret)
                        dio_data->data_space_reserved = true;
                else if (ret && !(BTRFS_I(inode)->flags &
index 226727b..f171bf8 100644 (file)
@@ -1760,7 +1760,8 @@ int btrfs_reserve_data_bytes(struct btrfs_fs_info *fs_info, u64 bytes,
        int ret;
 
        ASSERT(flush == BTRFS_RESERVE_FLUSH_DATA ||
-              flush == BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE);
+              flush == BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE ||
+              flush == BTRFS_RESERVE_NO_FLUSH);
        ASSERT(!current->journal_info || flush != BTRFS_RESERVE_FLUSH_DATA);
 
        ret = __reserve_bytes(fs_info, data_sinfo, bytes, flush);