btrfs: replace delete argument with EXTENT_CLEAR_ALL_BITS
authorJosef Bacik <josef@toxicpanda.com>
Fri, 9 Sep 2022 21:53:47 +0000 (17:53 -0400)
committerDavid Sterba <dsterba@suse.com>
Mon, 26 Sep 2022 10:28:05 +0000 (12:28 +0200)
Instead of taking up a whole argument to indicate we're clearing
everything in a range, simply add another EXTENT bit to control this,
and then update all the callers to drop this argument from the
clear_extent_bit variants.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
12 files changed:
fs/btrfs/extent-io-tree.c
fs/btrfs/extent-io-tree.h
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/reflink.c
fs/btrfs/tests/inode-tests.c
fs/btrfs/transaction.c

index c14e133881507fc7904052e81c9abdd086ed16bf..da6eb2dd7377fde3e4f7cf4431fbcb897fd968c4 100644 (file)
@@ -547,8 +547,7 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree,
  * This takes the tree lock, and returns 0 on success and < 0 on error.
  */
 int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
-                      u32 bits, int delete,
-                      struct extent_state **cached_state,
+                      u32 bits, struct extent_state **cached_state,
                       gfp_t mask, struct extent_changeset *changeset)
 {
        struct extent_state *state;
@@ -557,17 +556,19 @@ int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
        u64 last_end;
        int err;
        int clear = 0;
-       int wake = (bits & EXTENT_LOCKED) ? 1 : 0;
+       int wake;
+       int delete = (bits & EXTENT_CLEAR_ALL_BITS);
 
        btrfs_debug_check_extent_io_range(tree, start, end);
        trace_btrfs_clear_extent_bit(tree, start, end - start + 1, bits);
 
-       if (bits & EXTENT_DELALLOC)
-               bits |= EXTENT_NORESERVE;
-
        if (delete)
                bits |= ~EXTENT_CTLBITS;
 
+       if (bits & EXTENT_DELALLOC)
+               bits |= EXTENT_NORESERVE;
+
+       wake = (bits & EXTENT_LOCKED) ? 1 : 0;
        if (bits & (EXTENT_LOCKED | EXTENT_BOUNDARY))
                clear = 1;
 again:
@@ -1610,7 +1611,7 @@ int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
         */
        ASSERT(!(bits & EXTENT_LOCKED));
 
-       return __clear_extent_bit(tree, start, end, bits, 0, NULL, GFP_NOFS,
+       return __clear_extent_bit(tree, start, end, bits, NULL, GFP_NOFS,
                                  changeset);
 }
 
@@ -1624,7 +1625,7 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
        if (err == -EEXIST) {
                if (failed_start > start)
                        clear_extent_bit(tree, start, failed_start - 1,
-                                        EXTENT_LOCKED, 0, NULL);
+                                        EXTENT_LOCKED, NULL);
                return 0;
        }
        return 1;
index 913d83a2eee783270eeaef5d8f2bb840ff25a736..bcc8f6b05c03a80316031e5b39dc69c70a00133a 100644 (file)
@@ -35,10 +35,18 @@ struct io_failure_record;
  * delalloc bytes decremented, in an atomic way to prevent races with stat(2).
  */
 #define EXTENT_ADD_INODE_BYTES  (1U << 15)
+
+/*
+ * Set during truncate when we're clearing an entire range and we just want the
+ * extent states to go away.
+ */
+#define EXTENT_CLEAR_ALL_BITS  (1U << 16)
+
 #define EXTENT_DO_ACCOUNTING    (EXTENT_CLEAR_META_RESV | \
                                 EXTENT_CLEAR_DATA_RESV)
 #define EXTENT_CTLBITS         (EXTENT_DO_ACCOUNTING | \
-                                EXTENT_ADD_INODE_BYTES)
+                                EXTENT_ADD_INODE_BYTES | \
+                                EXTENT_CLEAR_ALL_BITS)
 
 /*
  * Redefined bits above which are used only in the device allocation tree,
@@ -114,35 +122,35 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,
 int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                             u32 bits, struct extent_changeset *changeset);
 int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
-                      u32 bits, int delete, struct extent_state **cached,
-                      gfp_t mask, struct extent_changeset *changeset);
+                      u32 bits, struct extent_state **cached, gfp_t mask,
+                      struct extent_changeset *changeset);
 
 static inline int clear_extent_bit(struct extent_io_tree *tree, u64 start,
-                                  u64 end, u32 bits, int delete,
+                                  u64 end, u32 bits,
                                   struct extent_state **cached)
 {
-       return __clear_extent_bit(tree, start, end, bits, delete, cached,
+       return __clear_extent_bit(tree, start, end, bits, cached,
                                  GFP_NOFS, NULL);
 }
 
 static inline int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end,
                                struct extent_state **cached)
 {
-       return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, 0, cached,
+       return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, cached,
                                  GFP_NOFS, NULL);
 }
 
 static inline int unlock_extent_atomic(struct extent_io_tree *tree, u64 start,
                                       u64 end, struct extent_state **cached)
 {
-       return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, 0, cached,
+       return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, cached,
                                  GFP_ATOMIC, NULL);
 }
 
 static inline int clear_extent_bits(struct extent_io_tree *tree, u64 start,
                                    u64 end, u32 bits)
 {
-       return clear_extent_bit(tree, start, end, bits, 0, NULL);
+       return clear_extent_bit(tree, start, end, bits, NULL);
 }
 
 int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
@@ -165,7 +173,7 @@ static inline int set_extent_bits(struct extent_io_tree *tree, u64 start,
 static inline int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
                u64 end, struct extent_state **cached_state)
 {
-       return __clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0,
+       return __clear_extent_bit(tree, start, end, EXTENT_UPTODATE,
                                  cached_state, GFP_NOFS, NULL);
 }
 
@@ -180,7 +188,7 @@ static inline int clear_extent_dirty(struct extent_io_tree *tree, u64 start,
 {
        return clear_extent_bit(tree, start, end,
                                EXTENT_DIRTY | EXTENT_DELALLOC |
-                               EXTENT_DO_ACCOUNTING, 0, cached);
+                               EXTENT_DO_ACCOUNTING, cached);
 }
 
 int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
index 42a8d4a3d99013defc25ae16e45ea4155272116e..b503635e1e825a331b29eb9747689afa236e8bba 100644 (file)
@@ -487,7 +487,7 @@ void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
                                  struct page *locked_page,
                                  u32 clear_bits, unsigned long page_ops)
 {
-       clear_extent_bit(&inode->io_tree, start, end, clear_bits, 0, NULL);
+       clear_extent_bit(&inode->io_tree, start, end, clear_bits, NULL);
 
        __process_pages_contig(inode->vfs_inode.i_mapping, locked_page,
                               start, end, page_ops, NULL);
@@ -3397,7 +3397,7 @@ static int try_release_extent_state(struct extent_io_tree *tree,
                 * The delalloc new bit will be cleared by ordered extent
                 * completion.
                 */
-               ret = __clear_extent_bit(tree, start, end, clear_bits, 0, NULL,
+               ret = __clear_extent_bit(tree, start, end, clear_bits, NULL,
                                         mask, NULL);
 
                /* if clear_extent_bit failed for enomem reasons,
index fae627c28d7c7c6cecfad036ca90f4c7ab771d87..d5640e695e6b993935e6b4f52c8cecf15f2e0814 100644 (file)
@@ -382,7 +382,7 @@ static void extent_map_device_clear_bits(struct extent_map *em, unsigned bits)
 
                __clear_extent_bit(&device->alloc_state, stripe->physical,
                                   stripe->physical + stripe_size - 1, bits,
-                                  0, NULL, GFP_NOWAIT, NULL);
+                                  NULL, GFP_NOWAIT, NULL);
        }
 }
 
index d44e0d3c84cdd238430f2d5636653fcc48eb0adf..45949261c699c482a2b04a6efb6e8d6cffc8b27e 100644 (file)
@@ -118,7 +118,7 @@ int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
        if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
                return 0;
        return clear_extent_bit(&inode->file_extent_tree, start,
-                               start + len - 1, EXTENT_DIRTY, 0, NULL);
+                               start + len - 1, EXTENT_DIRTY, NULL);
 }
 
 static inline u32 max_ordered_sum_bytes(struct btrfs_fs_info *fs_info,
index eb5579d9a3e01a02978d1cebbb22db707caa651f..fea508a359001d623c64b0d66fdb8c27cb023d5d 100644 (file)
@@ -473,7 +473,7 @@ int btrfs_dirty_pages(struct btrfs_inode *inode, struct page **pages,
         */
        clear_extent_bit(&inode->io_tree, start_pos, end_of_last_block,
                         EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
-                        0, cached);
+                        cached);
 
        err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
                                        extra_bits, cached);
index ecef1ba816c3bc9337e92883b670cb126d3049fb..7859eeca484c1df7e36fd6ffe9c8a9e25e067d84 100644 (file)
@@ -1163,7 +1163,7 @@ update_cache_item(struct btrfs_trans_handle *trans,
        ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
        if (ret < 0) {
                clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
-                                EXTENT_DELALLOC, 0, NULL);
+                                EXTENT_DELALLOC, NULL);
                goto fail;
        }
        leaf = path->nodes[0];
@@ -1175,7 +1175,7 @@ update_cache_item(struct btrfs_trans_handle *trans,
                if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID ||
                    found_key.offset != offset) {
                        clear_extent_bit(&BTRFS_I(inode)->io_tree, 0,
-                                        inode->i_size - 1, EXTENT_DELALLOC, 0,
+                                        inode->i_size - 1, EXTENT_DELALLOC,
                                         NULL);
                        btrfs_release_path(path);
                        goto fail;
@@ -1272,7 +1272,7 @@ static int flush_dirty_cache(struct inode *inode)
        ret = btrfs_wait_ordered_range(inode, 0, (u64)-1);
        if (ret)
                clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
-                                EXTENT_DELALLOC, 0, NULL);
+                                EXTENT_DELALLOC, NULL);
 
        return ret;
 }
index c417bbc299865a74b217a45fbb3e261c402ee98a..39f00b68b3a849a50f363fbcf1230d41679c9e15 100644 (file)
@@ -1747,7 +1747,7 @@ static int fallback_to_cow(struct btrfs_inode *inode, struct page *locked_page,
 
                if (count > 0)
                        clear_extent_bit(io_tree, start, end, EXTENT_NORESERVE,
-                                        0, NULL);
+                                        NULL);
        }
 
        return cow_file_range(inode, locked_page, start, end, page_started,
@@ -3323,7 +3323,7 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
            !test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags))
                clear_extent_bit(&inode->io_tree, start, end,
                                 EXTENT_DELALLOC_NEW | EXTENT_ADD_INODE_BYTES,
-                                0, &cached_state);
+                                &cached_state);
 
        btrfs_inode_safe_disk_i_size_write(inode, 0);
        ret = btrfs_update_inode_fallback(trans, root, inode);
@@ -3333,7 +3333,7 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
        }
        ret = 0;
 out:
-       clear_extent_bit(&inode->io_tree, start, end, clear_bits, 0,
+       clear_extent_bit(&inode->io_tree, start, end, clear_bits,
                         &cached_state);
 
        if (trans)
@@ -4933,7 +4933,7 @@ again:
 
        clear_extent_bit(&inode->io_tree, block_start, block_end,
                         EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
-                        0, &cached_state);
+                        &cached_state);
 
        ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0,
                                        &cached_state);
@@ -5347,8 +5347,7 @@ static void evict_inode_truncate_pages(struct inode *inode)
                                               end - start + 1);
 
                clear_extent_bit(io_tree, start, end,
-                                EXTENT_LOCKED | EXTENT_DELALLOC |
-                                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1,
+                                EXTENT_CLEAR_ALL_BITS | EXTENT_DO_ACCOUNTING,
                                 &cached_state);
 
                cond_resched();
@@ -8275,9 +8274,9 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
        cur = page_start;
        while (cur < page_end) {
                struct btrfs_ordered_extent *ordered;
-               bool delete_states;
                u64 range_end;
                u32 range_len;
+               u32 extra_flags = 0;
 
                ordered = btrfs_lookup_first_ordered_range(inode, cur,
                                                           page_end + 1 - cur);
@@ -8287,7 +8286,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                         * No ordered extent covering this range, we are safe
                         * to delete all extent states in the range.
                         */
-                       delete_states = true;
+                       extra_flags = EXTENT_CLEAR_ALL_BITS;
                        goto next;
                }
                if (ordered->file_offset > cur) {
@@ -8298,7 +8297,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                         * the ordered extent in the next iteration.
                         */
                        range_end = ordered->file_offset - 1;
-                       delete_states = true;
+                       extra_flags = EXTENT_CLEAR_ALL_BITS;
                        goto next;
                }
 
@@ -8313,7 +8312,6 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                         * We can't delete the extent states as
                         * btrfs_finish_ordered_io() may still use some of them.
                         */
-                       delete_states = false;
                        goto next;
                }
                btrfs_page_clear_ordered(fs_info, &folio->page, cur, range_len);
@@ -8330,7 +8328,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                        clear_extent_bit(tree, cur, range_end,
                                         EXTENT_DELALLOC |
                                         EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
-                                        EXTENT_DEFRAG, 0, &cached_state);
+                                        EXTENT_DEFRAG, &cached_state);
 
                spin_lock_irq(&inode->ordered_tree.lock);
                set_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags);
@@ -8338,6 +8336,12 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                                             cur - ordered->file_offset);
                spin_unlock_irq(&inode->ordered_tree.lock);
 
+               /*
+                * If the ordered extent has finished, we're safe to delete all
+                * the extent states of the range, otherwise
+                * btrfs_finish_ordered_io() will get executed by endio for
+                * other pages, so we can't delete extent states.
+                */
                if (btrfs_dec_test_ordered_pending(inode, &ordered,
                                                   cur, range_end + 1 - cur)) {
                        btrfs_finish_ordered_io(ordered);
@@ -8345,14 +8349,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
                         * The ordered extent has finished, now we're again
                         * safe to delete all extent states of the range.
                         */
-                       delete_states = true;
-               } else {
-                       /*
-                        * btrfs_finish_ordered_io() will get executed by endio
-                        * of other pages, thus we can't delete extent states
-                        * anymore
-                        */
-                       delete_states = false;
+                       extra_flags = EXTENT_CLEAR_ALL_BITS;
                }
 next:
                if (ordered)
@@ -8376,8 +8373,8 @@ next:
                if (!inode_evicting) {
                        clear_extent_bit(tree, cur, range_end, EXTENT_LOCKED |
                                 EXTENT_DELALLOC | EXTENT_UPTODATE |
-                                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
-                                delete_states, &cached_state);
+                                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG |
+                                extra_flags, &cached_state);
                }
                cur = range_end + 1;
        }
@@ -8511,7 +8508,7 @@ again:
         */
        clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, end,
                          EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
-                         EXTENT_DEFRAG, 0, &cached_state);
+                         EXTENT_DEFRAG, &cached_state);
 
        ret2 = btrfs_set_extent_delalloc(BTRFS_I(inode), page_start, end, 0,
                                        &cached_state);
index d59e1f1b762e751e7d8f09cd4f031673fd0885d8..d5dd8bed1488a807d9ec4e5bb0834b8b6c0b4f1e 100644 (file)
@@ -1616,7 +1616,7 @@ static int defrag_one_locked_target(struct btrfs_inode *inode,
                return ret;
        clear_extent_bit(&inode->io_tree, start, start + len - 1,
                         EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
-                        EXTENT_DEFRAG, 0, cached_state);
+                        EXTENT_DEFRAG, cached_state);
        set_extent_defrag(&inode->io_tree, start, start + len - 1, cached_state);
 
        /* Update the page status */
index 7a0db71d683b4f639cb0877d73e994be03a70d58..f50586ff85c84258c74d31aabc73fe24270854b9 100644 (file)
@@ -92,7 +92,7 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
 
        clear_extent_bit(&inode->io_tree, file_offset, range_end,
                         EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
-                        0, NULL);
+                        NULL);
        ret = btrfs_set_extent_delalloc(inode, file_offset, range_end, 0, NULL);
        if (ret)
                goto out_unlock;
index eeba3deb771466a23e9f7daf96c2473b4d75715a..b1c88dd187cb7aa5a6bccade7018fe2092cfd9a3 100644 (file)
@@ -975,7 +975,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
                               BTRFS_MAX_EXTENT_SIZE >> 1,
                               (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1,
                               EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
-                              EXTENT_UPTODATE, 0, NULL);
+                              EXTENT_UPTODATE, NULL);
        if (ret) {
                test_err("clear_extent_bit returned %d", ret);
                goto out;
@@ -1043,7 +1043,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
                               BTRFS_MAX_EXTENT_SIZE + sectorsize,
                               BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1,
                               EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
-                              EXTENT_UPTODATE, 0, NULL);
+                              EXTENT_UPTODATE, NULL);
        if (ret) {
                test_err("clear_extent_bit returned %d", ret);
                goto out;
@@ -1076,7 +1076,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
        /* Empty */
        ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
                               EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
-                              EXTENT_UPTODATE, 0, NULL);
+                              EXTENT_UPTODATE, NULL);
        if (ret) {
                test_err("clear_extent_bit returned %d", ret);
                goto out;
@@ -1092,7 +1092,7 @@ out:
        if (ret)
                clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
                                 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
-                                EXTENT_UPTODATE, 0, NULL);
+                                EXTENT_UPTODATE, NULL);
        iput(inode);
        btrfs_free_dummy_root(root);
        btrfs_free_dummy_fs_info(fs_info);
index 83f3d4b89faa68c2eb0f2a1f2853c4b9269390ed..d9d770a9b1a382fd5276779b55de7a8e9f526234 100644 (file)
@@ -1116,7 +1116,7 @@ static int __btrfs_wait_marked_extents(struct btrfs_fs_info *fs_info,
                 * it's safe to do it (through extent_io_tree_release()).
                 */
                err = clear_extent_bit(dirty_pages, start, end,
-                                      EXTENT_NEED_WAIT, 0, &cached_state);
+                                      EXTENT_NEED_WAIT, &cached_state);
                if (err == -ENOMEM)
                        err = 0;
                if (!err)