Skip to content

Commit 4206234

Browse files
committed
Merge tag 'erofs-for-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs fix from Gao Xiang: "Fix an urgent regression introduced by commit baa2c7c ("block: set .bi_max_vecs as actual allocated vector number"), which could cause unexpected hung since linux 5.12-rc1. Resolve it by avoiding using bio->bi_max_vecs completely" * tag 'erofs-for-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: fix bio->bi_max_vecs behavior change
2 parents e83bad7 + 9f37762 commit 4206234

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

fs/erofs/data.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
129129
struct page *page,
130130
erofs_off_t *last_block,
131131
unsigned int nblocks,
132+
unsigned int *eblks,
132133
bool ra)
133134
{
134135
struct inode *const inode = mapping->host;
@@ -145,8 +146,7 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
145146

146147
/* note that for readpage case, bio also equals to NULL */
147148
if (bio &&
148-
/* not continuous */
149-
*last_block + 1 != current_block) {
149+
(*last_block + 1 != current_block || !*eblks)) {
150150
submit_bio_retry:
151151
submit_bio(bio);
152152
bio = NULL;
@@ -216,7 +216,8 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
216216
if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE))
217217
nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE);
218218

219-
bio = bio_alloc(GFP_NOIO, bio_max_segs(nblocks));
219+
*eblks = bio_max_segs(nblocks);
220+
bio = bio_alloc(GFP_NOIO, *eblks);
220221

221222
bio->bi_end_io = erofs_readendio;
222223
bio_set_dev(bio, sb->s_bdev);
@@ -229,16 +230,8 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
229230
/* out of the extent or bio is full */
230231
if (err < PAGE_SIZE)
231232
goto submit_bio_retry;
232-
233+
--*eblks;
233234
*last_block = current_block;
234-
235-
/* shift in advance in case of it followed by too many gaps */
236-
if (bio->bi_iter.bi_size >= bio->bi_max_vecs * PAGE_SIZE) {
237-
/* err should reassign to 0 after submitting */
238-
err = 0;
239-
goto submit_bio_out;
240-
}
241-
242235
return bio;
243236

244237
err_out:
@@ -252,7 +245,6 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
252245

253246
/* if updated manually, continuous pages has a gap */
254247
if (bio)
255-
submit_bio_out:
256248
submit_bio(bio);
257249
return err ? ERR_PTR(err) : NULL;
258250
}
@@ -264,23 +256,26 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
264256
static int erofs_raw_access_readpage(struct file *file, struct page *page)
265257
{
266258
erofs_off_t last_block;
259+
unsigned int eblks;
267260
struct bio *bio;
268261

269262
trace_erofs_readpage(page, true);
270263

271264
bio = erofs_read_raw_page(NULL, page->mapping,
272-
page, &last_block, 1, false);
265+
page, &last_block, 1, &eblks, false);
273266

274267
if (IS_ERR(bio))
275268
return PTR_ERR(bio);
276269

277-
DBG_BUGON(bio); /* since we have only one bio -- must be NULL */
270+
if (bio)
271+
submit_bio(bio);
278272
return 0;
279273
}
280274

281275
static void erofs_raw_access_readahead(struct readahead_control *rac)
282276
{
283277
erofs_off_t last_block;
278+
unsigned int eblks;
284279
struct bio *bio = NULL;
285280
struct page *page;
286281

@@ -291,7 +286,7 @@ static void erofs_raw_access_readahead(struct readahead_control *rac)
291286
prefetchw(&page->flags);
292287

293288
bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block,
294-
readahead_count(rac), true);
289+
readahead_count(rac), &eblks, true);
295290

296291
/* all the page errors are ignored when readahead */
297292
if (IS_ERR(bio)) {
@@ -305,7 +300,6 @@ static void erofs_raw_access_readahead(struct readahead_control *rac)
305300
put_page(page);
306301
}
307302

308-
/* the rare case (end in gaps) */
309303
if (bio)
310304
submit_bio(bio);
311305
}

0 commit comments

Comments
 (0)