btrfs: clean up cow_file_range_inline()
authorOmar Sandoval <osandov@fb.com>
Tue, 16 Nov 2021 22:03:45 +0000 (14:03 -0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2022 12:13:51 +0000 (13:13 +0100)
The start parameter to cow_file_range_inline() (and
insert_inline_extent()) is always 0, so get rid of it and simplify the
logic in those two functions. Pass btrfs_inode to insert_inline_extent()
and remove the redundant root parameter. Also document the requirements
for creating an inline extent. No functional change.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index 38ea51d..c0b2421 100644 (file)
@@ -239,12 +239,13 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
  * no overlapping inline items exist in the btree
  */
 static int insert_inline_extent(struct btrfs_trans_handle *trans,
-                               struct btrfs_path *path, bool extent_inserted,
-                               struct btrfs_root *root, struct inode *inode,
-                               u64 start, size_t size, size_t compressed_size,
+                               struct btrfs_path *path,
+                               struct btrfs_inode *inode, bool extent_inserted,
+                               size_t size, size_t compressed_size,
                                int compress_type,
                                struct page **compressed_pages)
 {
+       struct btrfs_root *root = inode->root;
        struct extent_buffer *leaf;
        struct page *page = NULL;
        char *kaddr;
@@ -252,7 +253,6 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
        struct btrfs_file_extent_item *ei;
        int ret;
        size_t cur_size = size;
-       unsigned long offset;
 
        ASSERT((compressed_size > 0 && compressed_pages) ||
               (compressed_size == 0 && !compressed_pages));
@@ -264,8 +264,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
                struct btrfs_key key;
                size_t datasize;
 
-               key.objectid = btrfs_ino(BTRFS_I(inode));
-               key.offset = start;
+               key.objectid = btrfs_ino(inode);
+               key.offset = 0;
                key.type = BTRFS_EXTENT_DATA_KEY;
 
                datasize = btrfs_file_extent_calc_inline_size(cur_size);
@@ -303,12 +303,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
                btrfs_set_file_extent_compression(leaf, ei,
                                                  compress_type);
        } else {
-               page = find_get_page(inode->i_mapping,
-                                    start >> PAGE_SHIFT);
+               page = find_get_page(inode->vfs_inode.i_mapping, 0);
                btrfs_set_file_extent_compression(leaf, ei, 0);
                kaddr = kmap_atomic(page);
-               offset = offset_in_page(start);
-               write_extent_buffer(leaf, kaddr + offset, ptr, size);
+               write_extent_buffer(leaf, kaddr, ptr, size);
                kunmap_atomic(kaddr);
                put_page(page);
        }
@@ -319,8 +317,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
         * We align size to sectorsize for inline extents just for simplicity
         * sake.
         */
-       size = ALIGN(size, root->fs_info->sectorsize);
-       ret = btrfs_inode_set_file_extent_range(BTRFS_I(inode), start, size);
+       ret = btrfs_inode_set_file_extent_range(inode, 0,
+                                       ALIGN(size, root->fs_info->sectorsize));
        if (ret)
                goto fail;
 
@@ -333,7 +331,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
         * before we unlock the pages.  Otherwise we
         * could end up racing with unlink.
         */
-       BTRFS_I(inode)->disk_i_size = inode->i_size;
+       inode->disk_i_size = i_size_read(&inode->vfs_inode);
+
 fail:
        return ret;
 }
@@ -344,8 +343,8 @@ fail:
  * does the checks required to make sure the data is small enough
  * to fit as an inline extent.
  */
-static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
-                                         u64 end, size_t compressed_size,
+static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
+                                         size_t compressed_size,
                                          int compress_type,
                                          struct page **compressed_pages)
 {
@@ -353,26 +352,21 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
        struct btrfs_root *root = inode->root;
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_trans_handle *trans;
-       u64 isize = i_size_read(&inode->vfs_inode);
-       u64 actual_end = min(end + 1, isize);
-       u64 inline_len = actual_end - start;
-       u64 aligned_end = ALIGN(end, fs_info->sectorsize);
-       u64 data_len = inline_len;
+       u64 data_len = (compressed_size ?: size);
        int ret;
        struct btrfs_path *path;
 
-       if (compressed_size)
-               data_len = compressed_size;
-
-       if (start > 0 ||
-           actual_end > fs_info->sectorsize ||
+       /*
+        * We can create an inline extent if it ends at or beyond the current
+        * i_size, is no larger than a sector (decompressed), and the (possibly
+        * compressed) data fits in a leaf and the configured maximum inline
+        * size.
+        */
+       if (size < i_size_read(&inode->vfs_inode) ||
+           size > fs_info->sectorsize ||
            data_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info) ||
-           (!compressed_size &&
-           (actual_end & (fs_info->sectorsize - 1)) == 0) ||
-           end + 1 < isize ||
-           data_len > fs_info->max_inline) {
+           data_len > fs_info->max_inline)
                return 1;
-       }
 
        path = btrfs_alloc_path();
        if (!path)
@@ -386,30 +380,20 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
        trans->block_rsv = &inode->block_rsv;
 
        drop_args.path = path;
-       drop_args.start = start;
-       drop_args.end = aligned_end;
+       drop_args.start = 0;
+       drop_args.end = fs_info->sectorsize;
        drop_args.drop_cache = true;
        drop_args.replace_extent = true;
-
-       if (compressed_size && compressed_pages)
-               drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(
-                  compressed_size);
-       else
-               drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(
-                   inline_len);
-
+       drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(data_len);
        ret = btrfs_drop_extents(trans, root, inode, &drop_args);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
-       if (isize > actual_end)
-               inline_len = min_t(u64, isize, actual_end);
-       ret = insert_inline_extent(trans, path, drop_args.extent_inserted,
-                                  root, &inode->vfs_inode, start,
-                                  inline_len, compressed_size,
-                                  compress_type, compressed_pages);
+       ret = insert_inline_extent(trans, path, inode, drop_args.extent_inserted,
+                                  size, compressed_size, compress_type,
+                                  compressed_pages);
        if (ret && ret != -ENOSPC) {
                btrfs_abort_transaction(trans, ret);
                goto out;
@@ -418,7 +402,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
                goto out;
        }
 
-       btrfs_update_inode_bytes(inode, inline_len, drop_args.bytes_found);
+       btrfs_update_inode_bytes(inode, size, drop_args.bytes_found);
        ret = btrfs_update_inode(trans, root, inode);
        if (ret && ret != -ENOSPC) {
                btrfs_abort_transaction(trans, ret);
@@ -739,12 +723,12 @@ cont:
                        /* we didn't compress the entire range, try
                         * to make an uncompressed inline extent.
                         */
-                       ret = cow_file_range_inline(BTRFS_I(inode), start, end,
+                       ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
                                                    0, BTRFS_COMPRESS_NONE,
                                                    NULL);
                } else {
                        /* try making a compressed inline extent */
-                       ret = cow_file_range_inline(BTRFS_I(inode), start, end,
+                       ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
                                                    total_compressed,
                                                    compress_type, pages);
                }
@@ -1159,8 +1143,11 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
         * So here we skip inline extent creation completely.
         */
        if (start == 0 && fs_info->sectorsize == PAGE_SIZE) {
+               u64 actual_end = min_t(u64, i_size_read(&inode->vfs_inode),
+                                      end + 1);
+
                /* lets try to make an inline extent */
-               ret = cow_file_range_inline(inode, start, end, 0,
+               ret = cow_file_range_inline(inode, actual_end, 0,
                                            BTRFS_COMPRESS_NONE, NULL);
                if (ret == 0) {
                        /*