Skip to content

Commit b086c5b

Browse files
adam900710kdave
authored andcommitted
btrfs: subpage: make writer lock utilize bitmap
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 <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 8e7e9c6 commit b086c5b

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

fs/btrfs/subpage.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,36 +328,53 @@ static void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info,
328328
struct folio *folio, u64 start, u32 len)
329329
{
330330
struct btrfs_subpage *subpage = folio_get_private(folio);
331+
const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
331332
const int nbits = (len >> fs_info->sectorsize_bits);
333+
unsigned long flags;
332334
int ret;
333335

334336
btrfs_subpage_assert(fs_info, folio, start, len);
335337

338+
spin_lock_irqsave(&subpage->lock, flags);
336339
ASSERT(atomic_read(&subpage->readers) == 0);
340+
ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits));
341+
bitmap_set(subpage->bitmaps, start_bit, nbits);
337342
ret = atomic_add_return(nbits, &subpage->writers);
338343
ASSERT(ret == nbits);
344+
spin_unlock_irqrestore(&subpage->lock, flags);
339345
}
340346

341347
static bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
342348
struct folio *folio, u64 start, u32 len)
343349
{
344350
struct btrfs_subpage *subpage = folio_get_private(folio);
351+
const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
345352
const int nbits = (len >> fs_info->sectorsize_bits);
353+
unsigned long flags;
354+
bool last;
346355

347356
btrfs_subpage_assert(fs_info, folio, start, len);
348357

358+
spin_lock_irqsave(&subpage->lock, flags);
349359
/*
350360
* We have call sites passing @lock_page into
351361
* extent_clear_unlock_delalloc() for compression path.
352362
*
353363
* This @locked_page is locked by plain lock_page(), thus its
354364
* subpage::writers is 0. Handle them in a special way.
355365
*/
356-
if (atomic_read(&subpage->writers) == 0)
366+
if (atomic_read(&subpage->writers) == 0) {
367+
spin_unlock_irqrestore(&subpage->lock, flags);
357368
return true;
369+
}
358370

359371
ASSERT(atomic_read(&subpage->writers) >= nbits);
360-
return atomic_sub_and_test(nbits, &subpage->writers);
372+
/* The target range should have been locked. */
373+
ASSERT(bitmap_test_range_all_set(subpage->bitmaps, start_bit, nbits));
374+
bitmap_clear(subpage->bitmaps, start_bit, nbits);
375+
last = atomic_sub_and_test(nbits, &subpage->writers);
376+
spin_unlock_irqrestore(&subpage->lock, flags);
377+
return last;
361378
}
362379

363380
/*

0 commit comments

Comments
 (0)