Skip to content

Commit f2e74ec

Browse files
committed
Merge tag 'vfs-6.19-rc1.folio' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull folio updates from Christian Brauner: "Add a new folio_next_pos() helper function that returns the file position of the first byte after the current folio. This is a common operation in filesystems when needing to know the end of the current folio. The helper is lifted from btrfs which already had its own version, and is now used across multiple filesystems and subsystems: - btrfs - buffer - ext4 - f2fs - gfs2 - iomap - netfs - xfs - mm This fixes a long-standing bug in ocfs2 on 32-bit systems with files larger than 2GiB. Presumably this is not a common configuration, but the fix is backported anyway. The other filesystems did not have bugs, they were just mildly inefficient. This also introduce uoff_t as the unsigned version of loff_t. A recent commit inadvertently changed a comparison from being unsigned (on 64-bit systems) to being signed (which it had always been on 32-bit systems), leading to sporadic fstests failures. Generally file sizes are restricted to being a signed integer, but in places where -1 is passed to indicate "up to the end of the file", it is convenient to have an unsigned type to ensure comparisons are always unsigned regardless of architecture" * tag 'vfs-6.19-rc1.folio' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: Add uoff_t mm: Use folio_next_pos() xfs: Use folio_next_pos() netfs: Use folio_next_pos() iomap: Use folio_next_pos() gfs2: Use folio_next_pos() f2fs: Use folio_next_pos() ext4: Use folio_next_pos() buffer: Use folio_next_pos() btrfs: Use folio_next_pos() filemap: Add folio_next_pos()
2 parents 212c405 + 37d369f commit f2e74ec

25 files changed

Lines changed: 70 additions & 61 deletions

File tree

fs/btrfs/compression.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ static inline u32 btrfs_calc_input_length(struct folio *folio, u64 range_end, u6
8585
{
8686
/* @cur must be inside the folio. */
8787
ASSERT(folio_pos(folio) <= cur);
88-
ASSERT(cur < folio_end(folio));
89-
return min(range_end, folio_end(folio)) - cur;
88+
ASSERT(cur < folio_next_pos(folio));
89+
return umin(range_end, folio_next_pos(folio)) - cur;
9090
}
9191

9292
int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info);

fs/btrfs/defrag.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ static struct folio *defrag_prepare_one_folio(struct btrfs_inode *inode, pgoff_t
886886
}
887887

888888
lock_start = folio_pos(folio);
889-
lock_end = folio_end(folio) - 1;
889+
lock_end = folio_next_pos(folio) - 1;
890890
/* Wait for any existing ordered extent in the range */
891891
while (1) {
892892
struct btrfs_ordered_extent *ordered;
@@ -1178,7 +1178,8 @@ static int defrag_one_locked_target(struct btrfs_inode *inode,
11781178

11791179
if (!folio)
11801180
break;
1181-
if (start >= folio_end(folio) || start + len <= folio_pos(folio))
1181+
if (start >= folio_next_pos(folio) ||
1182+
start + len <= folio_pos(folio))
11821183
continue;
11831184
btrfs_folio_clamp_clear_checked(fs_info, folio, start, len);
11841185
btrfs_folio_clamp_set_dirty(fs_info, folio, start, len);
@@ -1219,7 +1220,7 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len,
12191220
folios[i] = NULL;
12201221
goto free_folios;
12211222
}
1222-
cur = folio_end(folios[i]);
1223+
cur = folio_next_pos(folios[i]);
12231224
}
12241225
for (int i = 0; i < nr_pages; i++) {
12251226
if (!folios[i])

fs/btrfs/extent_io.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ static noinline int lock_delalloc_folios(struct inode *inode,
333333
goto out;
334334
}
335335
range_start = max_t(u64, folio_pos(folio), start);
336-
range_len = min_t(u64, folio_end(folio), end + 1) - range_start;
336+
range_len = min_t(u64, folio_next_pos(folio), end + 1) - range_start;
337337
btrfs_folio_set_lock(fs_info, folio, range_start, range_len);
338338

339339
processed_end = range_start + range_len - 1;
@@ -387,7 +387,7 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
387387
ASSERT(orig_end > orig_start);
388388

389389
/* The range should at least cover part of the folio */
390-
ASSERT(!(orig_start >= folio_end(locked_folio) ||
390+
ASSERT(!(orig_start >= folio_next_pos(locked_folio) ||
391391
orig_end <= folio_pos(locked_folio)));
392392
again:
393393
/* step one, find a bunch of delalloc bytes starting at start */
@@ -493,7 +493,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le
493493
struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
494494

495495
ASSERT(folio_pos(folio) <= start &&
496-
start + len <= folio_end(folio));
496+
start + len <= folio_next_pos(folio));
497497

498498
if (uptodate && btrfs_verify_folio(folio, start, len))
499499
btrfs_folio_set_uptodate(fs_info, folio, start, len);
@@ -1201,7 +1201,7 @@ static bool can_skip_one_ordered_range(struct btrfs_inode *inode,
12011201
* finished our folio read and unlocked the folio.
12021202
*/
12031203
if (btrfs_folio_test_dirty(fs_info, folio, cur, blocksize)) {
1204-
u64 range_len = min(folio_end(folio),
1204+
u64 range_len = umin(folio_next_pos(folio),
12051205
ordered->file_offset + ordered->num_bytes) - cur;
12061206

12071207
ret = true;
@@ -1223,7 +1223,7 @@ static bool can_skip_one_ordered_range(struct btrfs_inode *inode,
12231223
* So we return true and update @next_ret to the OE/folio boundary.
12241224
*/
12251225
if (btrfs_folio_test_uptodate(fs_info, folio, cur, blocksize)) {
1226-
u64 range_len = min(folio_end(folio),
1226+
u64 range_len = umin(folio_next_pos(folio),
12271227
ordered->file_offset + ordered->num_bytes) - cur;
12281228

12291229
/*
@@ -2215,7 +2215,7 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb,
22152215
for (int i = 0; i < num_extent_folios(eb); i++) {
22162216
struct folio *folio = eb->folios[i];
22172217
u64 range_start = max_t(u64, eb->start, folio_pos(folio));
2218-
u32 range_len = min_t(u64, folio_end(folio),
2218+
u32 range_len = min_t(u64, folio_next_pos(folio),
22192219
eb->start + eb->len) - range_start;
22202220

22212221
folio_lock(folio);
@@ -2624,7 +2624,7 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
26242624
continue;
26252625
}
26262626

2627-
cur_end = min_t(u64, folio_end(folio) - 1, end);
2627+
cur_end = min_t(u64, folio_next_pos(folio) - 1, end);
26282628
cur_len = cur_end + 1 - cur;
26292629

26302630
ASSERT(folio_test_locked(folio));
@@ -3865,7 +3865,7 @@ int read_extent_buffer_pages_nowait(struct extent_buffer *eb, int mirror_num,
38653865
for (int i = 0; i < num_extent_folios(eb); i++) {
38663866
struct folio *folio = eb->folios[i];
38673867
u64 range_start = max_t(u64, eb->start, folio_pos(folio));
3868-
u32 range_len = min_t(u64, folio_end(folio),
3868+
u32 range_len = min_t(u64, folio_next_pos(folio),
38693869
eb->start + eb->len) - range_start;
38703870

38713871
bio_add_folio_nofail(&bbio->bio, folio, range_len,

fs/btrfs/file.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ int btrfs_dirty_folio(struct btrfs_inode *inode, struct folio *folio, loff_t pos
8989
num_bytes = round_up(write_bytes + pos - start_pos,
9090
fs_info->sectorsize);
9191
ASSERT(num_bytes <= U32_MAX);
92-
ASSERT(folio_pos(folio) <= pos && folio_end(folio) >= pos + write_bytes);
92+
ASSERT(folio_pos(folio) <= pos &&
93+
folio_next_pos(folio) >= pos + write_bytes);
9394

9495
end_of_last_block = start_pos + num_bytes - 1;
9596

@@ -799,7 +800,7 @@ static int prepare_uptodate_folio(struct inode *inode, struct folio *folio, u64
799800
u64 len)
800801
{
801802
u64 clamp_start = max_t(u64, pos, folio_pos(folio));
802-
u64 clamp_end = min_t(u64, pos + len, folio_end(folio));
803+
u64 clamp_end = min_t(u64, pos + len, folio_next_pos(folio));
803804
const u32 blocksize = inode_to_fs_info(inode)->sectorsize;
804805
int ret = 0;
805806

@@ -1254,8 +1255,8 @@ static int copy_one_range(struct btrfs_inode *inode, struct iov_iter *iter,
12541255
* The reserved range goes beyond the current folio, shrink the reserved
12551256
* space to the folio boundary.
12561257
*/
1257-
if (reserved_start + reserved_len > folio_end(folio)) {
1258-
const u64 last_block = folio_end(folio);
1258+
if (reserved_start + reserved_len > folio_next_pos(folio)) {
1259+
const u64 last_block = folio_next_pos(folio);
12591260

12601261
shrink_reserved_space(inode, *data_reserved, reserved_start,
12611262
reserved_len, last_block - reserved_start,

fs/btrfs/inode.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,
411411
continue;
412412
}
413413

414-
index = folio_end(folio) >> PAGE_SHIFT;
414+
index = folio_next_index(folio);
415415
/*
416416
* Here we just clear all Ordered bits for every page in the
417417
* range, then btrfs_mark_ordered_io_finished() will handle
@@ -2338,7 +2338,8 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct folio *locked_fol
23382338
* The range must cover part of the @locked_folio, or a return of 1
23392339
* can confuse the caller.
23402340
*/
2341-
ASSERT(!(end <= folio_pos(locked_folio) || start >= folio_end(locked_folio)));
2341+
ASSERT(!(end <= folio_pos(locked_folio) ||
2342+
start >= folio_next_pos(locked_folio)));
23422343

23432344
if (should_nocow(inode, start, end)) {
23442345
ret = run_delalloc_nocow(inode, locked_folio, start, end);
@@ -2745,7 +2746,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
27452746
struct btrfs_inode *inode = fixup->inode;
27462747
struct btrfs_fs_info *fs_info = inode->root->fs_info;
27472748
u64 page_start = folio_pos(folio);
2748-
u64 page_end = folio_end(folio) - 1;
2749+
u64 page_end = folio_next_pos(folio) - 1;
27492750
int ret = 0;
27502751
bool free_delalloc_space = true;
27512752

@@ -4857,7 +4858,7 @@ static int truncate_block_zero_beyond_eof(struct btrfs_inode *inode, u64 start)
48574858
*/
48584859

48594860
zero_start = max_t(u64, folio_pos(folio), start);
4860-
zero_end = folio_end(folio);
4861+
zero_end = folio_next_pos(folio);
48614862
folio_zero_range(folio, zero_start - folio_pos(folio),
48624863
zero_end - zero_start);
48634864

@@ -5040,7 +5041,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, u64 offset, u64 start, u64 e
50405041
* not reach disk, it still affects our page caches.
50415042
*/
50425043
zero_start = max_t(u64, folio_pos(folio), start);
5043-
zero_end = min_t(u64, folio_end(folio) - 1, end);
5044+
zero_end = min_t(u64, folio_next_pos(folio) - 1, end);
50445045
} else {
50455046
zero_start = max_t(u64, block_start, start);
50465047
zero_end = min_t(u64, block_end, end);

fs/btrfs/misc.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,4 @@ static inline bool bitmap_test_range_all_zero(const unsigned long *addr,
209209
return (found_set == start + nbits);
210210
}
211211

212-
static inline u64 folio_end(struct folio *folio)
213-
{
214-
return folio_pos(folio) + folio_size(folio);
215-
}
216-
217212
#endif

fs/btrfs/ordered-data.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ static bool can_finish_ordered_extent(struct btrfs_ordered_extent *ordered,
359359
if (folio) {
360360
ASSERT(folio->mapping);
361361
ASSERT(folio_pos(folio) <= file_offset);
362-
ASSERT(file_offset + len <= folio_end(folio));
362+
ASSERT(file_offset + len <= folio_next_pos(folio));
363363

364364
/*
365365
* Ordered flag indicates whether we still have

fs/btrfs/subpage.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ static void btrfs_subpage_assert(const struct btrfs_fs_info *fs_info,
186186
* unmapped page like dummy extent buffer pages.
187187
*/
188188
if (folio->mapping)
189-
ASSERT(folio_pos(folio) <= start && start + len <= folio_end(folio),
189+
ASSERT(folio_pos(folio) <= start &&
190+
start + len <= folio_next_pos(folio),
190191
"start=%llu len=%u folio_pos=%llu folio_size=%zu",
191192
start, len, folio_pos(folio), folio_size(folio));
192193
}
@@ -217,7 +218,7 @@ static void btrfs_subpage_clamp_range(struct folio *folio, u64 *start, u32 *len)
217218
if (folio_pos(folio) >= orig_start + orig_len)
218219
*len = 0;
219220
else
220-
*len = min_t(u64, folio_end(folio), orig_start + orig_len) - *start;
221+
*len = min_t(u64, folio_next_pos(folio), orig_start + orig_len) - *start;
221222
}
222223

223224
static bool btrfs_subpage_end_and_test_lock(const struct btrfs_fs_info *fs_info,

fs/buffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2732,7 +2732,7 @@ int block_write_full_folio(struct folio *folio, struct writeback_control *wbc,
27322732
loff_t i_size = i_size_read(inode);
27332733

27342734
/* Is the folio fully inside i_size? */
2735-
if (folio_pos(folio) + folio_size(folio) <= i_size)
2735+
if (folio_next_pos(folio) <= i_size)
27362736
return __block_write_full_folio(inode, folio, get_block, wbc);
27372737

27382738
/* Is the folio fully outside i_size? (truncate in progress) */

fs/ext4/inode.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,8 +1318,8 @@ static int ext4_write_begin(const struct kiocb *iocb,
13181318
if (IS_ERR(folio))
13191319
return PTR_ERR(folio);
13201320

1321-
if (pos + len > folio_pos(folio) + folio_size(folio))
1322-
len = folio_pos(folio) + folio_size(folio) - pos;
1321+
if (len > folio_next_pos(folio) - pos)
1322+
len = folio_next_pos(folio) - pos;
13231323

13241324
from = offset_in_folio(folio, pos);
13251325
to = from + len;
@@ -2700,7 +2700,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
27002700

27012701
if (mpd->map.m_len == 0)
27022702
mpd->start_pos = folio_pos(folio);
2703-
mpd->next_pos = folio_pos(folio) + folio_size(folio);
2703+
mpd->next_pos = folio_next_pos(folio);
27042704
/*
27052705
* Writeout when we cannot modify metadata is simple.
27062706
* Just submit the page. For data=journal mode we
@@ -3142,8 +3142,8 @@ static int ext4_da_write_begin(const struct kiocb *iocb,
31423142
if (IS_ERR(folio))
31433143
return PTR_ERR(folio);
31443144

3145-
if (pos + len > folio_pos(folio) + folio_size(folio))
3146-
len = folio_pos(folio) + folio_size(folio) - pos;
3145+
if (len > folio_next_pos(folio) - pos)
3146+
len = folio_next_pos(folio) - pos;
31473147

31483148
ret = ext4_block_write_begin(NULL, folio, pos, len,
31493149
ext4_da_get_block_prep);

0 commit comments

Comments
 (0)