Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 baa2c7c97153 ("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

+11 -17
+11 -17
fs/erofs/data.c
··· 129 129 struct page *page, 130 130 erofs_off_t *last_block, 131 131 unsigned int nblocks, 132 + unsigned int *eblks, 132 133 bool ra) 133 134 { 134 135 struct inode *const inode = mapping->host; ··· 146 145 147 146 /* note that for readpage case, bio also equals to NULL */ 148 147 if (bio && 149 - /* not continuous */ 150 - *last_block + 1 != current_block) { 148 + (*last_block + 1 != current_block || !*eblks)) { 151 149 submit_bio_retry: 152 150 submit_bio(bio); 153 151 bio = NULL; ··· 216 216 if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) 217 217 nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); 218 218 219 - bio = bio_alloc(GFP_NOIO, bio_max_segs(nblocks)); 219 + *eblks = bio_max_segs(nblocks); 220 + bio = bio_alloc(GFP_NOIO, *eblks); 220 221 221 222 bio->bi_end_io = erofs_readendio; 222 223 bio_set_dev(bio, sb->s_bdev); ··· 230 229 /* out of the extent or bio is full */ 231 230 if (err < PAGE_SIZE) 232 231 goto submit_bio_retry; 233 - 232 + --*eblks; 234 233 *last_block = current_block; 235 - 236 - /* shift in advance in case of it followed by too many gaps */ 237 - if (bio->bi_iter.bi_size >= bio->bi_max_vecs * PAGE_SIZE) { 238 - /* err should reassign to 0 after submitting */ 239 - err = 0; 240 - goto submit_bio_out; 241 - } 242 - 243 234 return bio; 244 235 245 236 err_out: ··· 245 252 246 253 /* if updated manually, continuous pages has a gap */ 247 254 if (bio) 248 - submit_bio_out: 249 255 submit_bio(bio); 250 256 return err ? ERR_PTR(err) : NULL; 251 257 } ··· 256 264 static int erofs_raw_access_readpage(struct file *file, struct page *page) 257 265 { 258 266 erofs_off_t last_block; 267 + unsigned int eblks; 259 268 struct bio *bio; 260 269 261 270 trace_erofs_readpage(page, true); 262 271 263 272 bio = erofs_read_raw_page(NULL, page->mapping, 264 - page, &last_block, 1, false); 273 + page, &last_block, 1, &eblks, false); 265 274 266 275 if (IS_ERR(bio)) 267 276 return PTR_ERR(bio); 268 277 269 - DBG_BUGON(bio); /* since we have only one bio -- must be NULL */ 278 + if (bio) 279 + submit_bio(bio); 270 280 return 0; 271 281 } 272 282 273 283 static void erofs_raw_access_readahead(struct readahead_control *rac) 274 284 { 275 285 erofs_off_t last_block; 286 + unsigned int eblks; 276 287 struct bio *bio = NULL; 277 288 struct page *page; 278 289 ··· 286 291 prefetchw(&page->flags); 287 292 288 293 bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block, 289 - readahead_count(rac), true); 294 + readahead_count(rac), &eblks, true); 290 295 291 296 /* all the page errors are ignored when readahead */ 292 297 if (IS_ERR(bio)) { ··· 300 305 put_page(page); 301 306 } 302 307 303 - /* the rare case (end in gaps) */ 304 308 if (bio) 305 309 submit_bio(bio); 306 310 }