Skip to content

Commit 336e69f

Browse files
adam900710kdave
authored andcommitted
btrfs: unify to use writer locks for subpage locking
Since commit d7172f5 ("btrfs: use per-buffer locking for extent_buffer reading"), metadata read no longer relies on the subpage reader locking. This means we do not need to maintain a different metadata/data split for locking, so we can convert the existing reader lock users by: - add_ra_bio_pages() Convert to btrfs_folio_set_writer_lock() - end_folio_read() Convert to btrfs_folio_end_writer_lock() - begin_folio_read() Convert to btrfs_folio_set_writer_lock() - folio_range_has_eb() Remove the subpage->readers checks, since it is always 0. - Remove btrfs_subpage_start_reader() and btrfs_subpage_end_reader() Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 8511074 commit 336e69f

File tree

4 files changed

+5
-83
lines changed

4 files changed

+5
-83
lines changed

fs/btrfs/compression.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
545545
* subpage::readers and to unlock the page.
546546
*/
547547
if (fs_info->sectorsize < PAGE_SIZE)
548-
btrfs_subpage_start_reader(fs_info, folio, cur,
549-
add_size);
548+
btrfs_folio_set_writer_lock(fs_info, folio, cur, add_size);
550549
folio_put(folio);
551550
cur += add_size;
552551
}

fs/btrfs/extent_io.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le
438438
if (!btrfs_is_subpage(fs_info, folio->mapping))
439439
folio_unlock(folio);
440440
else
441-
btrfs_subpage_end_reader(fs_info, folio, start, len);
441+
btrfs_folio_end_writer_lock(fs_info, folio, start, len);
442442
}
443443

444444
/*
@@ -495,7 +495,7 @@ static void begin_folio_read(struct btrfs_fs_info *fs_info, struct folio *folio)
495495
return;
496496

497497
ASSERT(folio_test_private(folio));
498-
btrfs_subpage_start_reader(fs_info, folio, folio_pos(folio), PAGE_SIZE);
498+
btrfs_folio_set_writer_lock(fs_info, folio, folio_pos(folio), PAGE_SIZE);
499499
}
500500

501501
/*
@@ -2517,12 +2517,6 @@ static bool folio_range_has_eb(struct folio *folio)
25172517
subpage = folio_get_private(folio);
25182518
if (atomic_read(&subpage->eb_refs))
25192519
return true;
2520-
/*
2521-
* Even there is no eb refs here, we may still have
2522-
* end_folio_read() call relying on page::private.
2523-
*/
2524-
if (atomic_read(&subpage->readers))
2525-
return true;
25262520
}
25272521
return false;
25282522
}

fs/btrfs/subpage.c

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,10 @@ struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info,
140140
return ERR_PTR(-ENOMEM);
141141

142142
spin_lock_init(&ret->lock);
143-
if (type == BTRFS_SUBPAGE_METADATA) {
143+
if (type == BTRFS_SUBPAGE_METADATA)
144144
atomic_set(&ret->eb_refs, 0);
145-
} else {
146-
atomic_set(&ret->readers, 0);
145+
else
147146
atomic_set(&ret->writers, 0);
148-
}
149147
return ret;
150148
}
151149

@@ -221,62 +219,6 @@ static void btrfs_subpage_assert(const struct btrfs_fs_info *fs_info,
221219
__start_bit; \
222220
})
223221

224-
void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info,
225-
struct folio *folio, u64 start, u32 len)
226-
{
227-
struct btrfs_subpage *subpage = folio_get_private(folio);
228-
const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
229-
const int nbits = len >> fs_info->sectorsize_bits;
230-
unsigned long flags;
231-
232-
233-
btrfs_subpage_assert(fs_info, folio, start, len);
234-
235-
spin_lock_irqsave(&subpage->lock, flags);
236-
/*
237-
* Even though it's just for reading the page, no one should have
238-
* locked the subpage range.
239-
*/
240-
ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits));
241-
bitmap_set(subpage->bitmaps, start_bit, nbits);
242-
atomic_add(nbits, &subpage->readers);
243-
spin_unlock_irqrestore(&subpage->lock, flags);
244-
}
245-
246-
void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info,
247-
struct folio *folio, u64 start, u32 len)
248-
{
249-
struct btrfs_subpage *subpage = folio_get_private(folio);
250-
const int start_bit = subpage_calc_start_bit(fs_info, folio, locked, start, len);
251-
const int nbits = len >> fs_info->sectorsize_bits;
252-
unsigned long flags;
253-
bool is_data;
254-
bool last;
255-
256-
btrfs_subpage_assert(fs_info, folio, start, len);
257-
is_data = is_data_inode(BTRFS_I(folio->mapping->host));
258-
259-
spin_lock_irqsave(&subpage->lock, flags);
260-
261-
/* The range should have already been locked. */
262-
ASSERT(bitmap_test_range_all_set(subpage->bitmaps, start_bit, nbits));
263-
ASSERT(atomic_read(&subpage->readers) >= nbits);
264-
265-
bitmap_clear(subpage->bitmaps, start_bit, nbits);
266-
last = atomic_sub_and_test(nbits, &subpage->readers);
267-
268-
/*
269-
* For data we need to unlock the page if the last read has finished.
270-
*
271-
* And please don't replace @last with atomic_sub_and_test() call
272-
* inside if () condition.
273-
* As we want the atomic_sub_and_test() to be always executed.
274-
*/
275-
if (is_data && last)
276-
folio_unlock(folio);
277-
spin_unlock_irqrestore(&subpage->lock, flags);
278-
}
279-
280222
static void btrfs_subpage_clamp_range(struct folio *folio, u64 *start, u32 *len)
281223
{
282224
u64 orig_start = *start;

fs/btrfs/subpage.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,6 @@ enum {
4545
struct btrfs_subpage {
4646
/* Common members for both data and metadata pages */
4747
spinlock_t lock;
48-
/*
49-
* Both data and metadata needs to track how many readers are for the
50-
* page.
51-
* Data relies on @readers to unlock the page when last reader finished.
52-
* While metadata doesn't need page unlock, it needs to prevent
53-
* page::private get cleared before the last end_page_read().
54-
*/
55-
atomic_t readers;
5648
union {
5749
/*
5850
* Structures only used by metadata
@@ -95,11 +87,6 @@ void btrfs_free_subpage(struct btrfs_subpage *subpage);
9587
void btrfs_folio_inc_eb_refs(const struct btrfs_fs_info *fs_info, struct folio *folio);
9688
void btrfs_folio_dec_eb_refs(const struct btrfs_fs_info *fs_info, struct folio *folio);
9789

98-
void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info,
99-
struct folio *folio, u64 start, u32 len);
100-
void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info,
101-
struct folio *folio, u64 start, u32 len);
102-
10390
void btrfs_folio_end_writer_lock(const struct btrfs_fs_info *fs_info,
10491
struct folio *folio, u64 start, u32 len);
10592
void btrfs_folio_set_writer_lock(const struct btrfs_fs_info *fs_info,

0 commit comments

Comments
 (0)