]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: subpage: make writer lock utilize bitmap
authorQu Wenruo <wqu@suse.com>
Sat, 17 Feb 2024 06:29:50 +0000 (16:59 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 5 Mar 2024 16:13:23 +0000 (17:13 +0100)
For the writer counter, it's pretty much the same as the reader counter,
and they are exclusive.  So move them to the new locked bitmap.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/subpage.c

index eae9e8a478f67a7e61b1e5cb220c57c02e10e0d7..54736f6238e659973c95b13b670a65e883b87087 100644 (file)
@@ -328,24 +328,34 @@ static void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info,
                                       struct folio *folio, u64 start, u32 len)
 {
        struct btrfs_subpage *subpage = folio_get_private(folio);
+       const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
        const int nbits = (len >> fs_info->sectorsize_bits);
+       unsigned long flags;
        int ret;
 
        btrfs_subpage_assert(fs_info, folio, start, len);
 
+       spin_lock_irqsave(&subpage->lock, flags);
        ASSERT(atomic_read(&subpage->readers) == 0);
+       ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits));
+       bitmap_set(subpage->bitmaps, start_bit, nbits);
        ret = atomic_add_return(nbits, &subpage->writers);
        ASSERT(ret == nbits);
+       spin_unlock_irqrestore(&subpage->lock, flags);
 }
 
 static bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
                                              struct folio *folio, u64 start, u32 len)
 {
        struct btrfs_subpage *subpage = folio_get_private(folio);
+       const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
        const int nbits = (len >> fs_info->sectorsize_bits);
+       unsigned long flags;
+       bool last;
 
        btrfs_subpage_assert(fs_info, folio, start, len);
 
+       spin_lock_irqsave(&subpage->lock, flags);
        /*
         * We have call sites passing @lock_page into
         * extent_clear_unlock_delalloc() for compression path.
@@ -353,11 +363,18 @@ static bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_inf
         * This @locked_page is locked by plain lock_page(), thus its
         * subpage::writers is 0.  Handle them in a special way.
         */
-       if (atomic_read(&subpage->writers) == 0)
+       if (atomic_read(&subpage->writers) == 0) {
+               spin_unlock_irqrestore(&subpage->lock, flags);
                return true;
+       }
 
        ASSERT(atomic_read(&subpage->writers) >= nbits);
-       return atomic_sub_and_test(nbits, &subpage->writers);
+       /* The target range should have been locked. */
+       ASSERT(bitmap_test_range_all_set(subpage->bitmaps, start_bit, nbits));
+       bitmap_clear(subpage->bitmaps, start_bit, nbits);
+       last = atomic_sub_and_test(nbits, &subpage->writers);
+       spin_unlock_irqrestore(&subpage->lock, flags);
+       return last;
 }
 
 /*