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-6.16-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull erofs fixes from Gao Xiang:
"Fix for a cache aliasing issue by adding missing flush_dcache_folio(),
which causes execution failures on some arm32 setups.

Fix for large compressed fragments, which could be generated by
-Eall-fragments option (but should be rare) and was rejected by
mistake due to an on-disk hardening commit.

The remaining ones are small fixes. Summary:

- Address cache aliasing for mappable page cache folios

- Allow readdir() to be interrupted

- Fix large fragment handling which was errored out by mistake

- Add missing tracepoints

- Use memcpy_to_folio() to replace copy_to_iter() for inline data"

* tag 'erofs-for-6.16-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
erofs: fix large fragment handling
erofs: allow readdir() to be interrupted
erofs: address D-cache aliasing
erofs: use memcpy_to_folio() to replace copy_to_iter()
erofs: fix to add missing tracepoint in erofs_read_folio()
erofs: fix to add missing tracepoint in erofs_readahead()

+41 -35
+16 -5
fs/erofs/data.c
··· 214 214 215 215 /* 216 216 * bit 30: I/O error occurred on this folio 217 + * bit 29: CPU has dirty data in D-cache (needs aliasing handling); 217 218 * bit 0 - 29: remaining parts to complete this folio 218 219 */ 219 - #define EROFS_ONLINEFOLIO_EIO (1 << 30) 220 + #define EROFS_ONLINEFOLIO_EIO 30 221 + #define EROFS_ONLINEFOLIO_DIRTY 29 220 222 221 223 void erofs_onlinefolio_init(struct folio *folio) 222 224 { ··· 235 233 atomic_inc((atomic_t *)&folio->private); 236 234 } 237 235 238 - void erofs_onlinefolio_end(struct folio *folio, int err) 236 + void erofs_onlinefolio_end(struct folio *folio, int err, bool dirty) 239 237 { 240 238 int orig, v; 241 239 242 240 do { 243 241 orig = atomic_read((atomic_t *)&folio->private); 244 - v = (orig - 1) | (err ? EROFS_ONLINEFOLIO_EIO : 0); 242 + DBG_BUGON(orig <= 0); 243 + v = dirty << EROFS_ONLINEFOLIO_DIRTY; 244 + v |= (orig - 1) | (!!err << EROFS_ONLINEFOLIO_EIO); 245 245 } while (atomic_cmpxchg((atomic_t *)&folio->private, orig, v) != orig); 246 246 247 - if (v & ~EROFS_ONLINEFOLIO_EIO) 247 + if (v & (BIT(EROFS_ONLINEFOLIO_DIRTY) - 1)) 248 248 return; 249 249 folio->private = 0; 250 - folio_end_read(folio, !(v & EROFS_ONLINEFOLIO_EIO)); 250 + if (v & BIT(EROFS_ONLINEFOLIO_DIRTY)) 251 + flush_dcache_folio(folio); 252 + folio_end_read(folio, !(v & BIT(EROFS_ONLINEFOLIO_EIO))); 251 253 } 252 254 253 255 static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, ··· 357 351 */ 358 352 static int erofs_read_folio(struct file *file, struct folio *folio) 359 353 { 354 + trace_erofs_read_folio(folio, true); 355 + 360 356 return iomap_read_folio(folio, &erofs_iomap_ops); 361 357 } 362 358 363 359 static void erofs_readahead(struct readahead_control *rac) 364 360 { 361 + trace_erofs_readahead(rac->mapping->host, readahead_index(rac), 362 + readahead_count(rac), true); 363 + 365 364 return iomap_readahead(rac, &erofs_iomap_ops); 366 365 } 367 366
+4 -8
fs/erofs/decompressor.c
··· 301 301 cur = min(cur, rq->outputsize); 302 302 if (cur && rq->out[0]) { 303 303 kin = kmap_local_page(rq->in[nrpages_in - 1]); 304 - if (rq->out[0] == rq->in[nrpages_in - 1]) { 304 + if (rq->out[0] == rq->in[nrpages_in - 1]) 305 305 memmove(kin + rq->pageofs_out, kin + pi, cur); 306 - flush_dcache_page(rq->out[0]); 307 - } else { 306 + else 308 307 memcpy_to_page(rq->out[0], rq->pageofs_out, 309 308 kin + pi, cur); 310 - } 311 309 kunmap_local(kin); 312 310 } 313 311 rq->outputsize -= cur; ··· 323 325 po = (rq->pageofs_out + cur + pi) & ~PAGE_MASK; 324 326 DBG_BUGON(no >= nrpages_out); 325 327 cnt = min(insz - pi, PAGE_SIZE - po); 326 - if (rq->out[no] == rq->in[ni]) { 328 + if (rq->out[no] == rq->in[ni]) 327 329 memmove(kin + po, 328 330 kin + rq->pageofs_in + pi, cnt); 329 - flush_dcache_page(rq->out[no]); 330 - } else if (rq->out[no]) { 331 + else if (rq->out[no]) 331 332 memcpy_to_page(rq->out[no], po, 332 333 kin + rq->pageofs_in + pi, cnt); 333 - } 334 334 pi += cnt; 335 335 } while (pi < insz); 336 336 kunmap_local(kin);
+6
fs/erofs/dir.c
··· 58 58 struct erofs_dirent *de; 59 59 unsigned int nameoff, maxsize; 60 60 61 + if (fatal_signal_pending(current)) { 62 + err = -ERESTARTSYS; 63 + break; 64 + } 65 + 61 66 de = erofs_bread(&buf, dbstart, true); 62 67 if (IS_ERR(de)) { 63 68 erofs_err(sb, "failed to readdir of logical block %llu of nid %llu", ··· 93 88 break; 94 89 ctx->pos = dbstart + maxsize; 95 90 ofs = 0; 91 + cond_resched(); 96 92 } 97 93 erofs_put_metabuf(&buf); 98 94 if (EROFS_I(dir)->dot_omitted && ctx->pos == dir->i_size) {
+3 -11
fs/erofs/fileio.c
··· 38 38 } else { 39 39 bio_for_each_folio_all(fi, &rq->bio) { 40 40 DBG_BUGON(folio_test_uptodate(fi.folio)); 41 - erofs_onlinefolio_end(fi.folio, ret); 41 + erofs_onlinefolio_end(fi.folio, ret, false); 42 42 } 43 43 } 44 44 bio_uninit(&rq->bio); ··· 96 96 struct erofs_map_blocks *map = &io->map; 97 97 unsigned int cur = 0, end = folio_size(folio), len, attached = 0; 98 98 loff_t pos = folio_pos(folio), ofs; 99 - struct iov_iter iter; 100 - struct bio_vec bv; 101 99 int err = 0; 102 100 103 101 erofs_onlinefolio_init(folio); ··· 120 122 err = PTR_ERR(src); 121 123 break; 122 124 } 123 - bvec_set_folio(&bv, folio, len, cur); 124 - iov_iter_bvec(&iter, ITER_DEST, &bv, 1, len); 125 - if (copy_to_iter(src, len, &iter) != len) { 126 - erofs_put_metabuf(&buf); 127 - err = -EIO; 128 - break; 129 - } 125 + memcpy_to_folio(folio, cur, src, len); 130 126 erofs_put_metabuf(&buf); 131 127 } else if (!(map->m_flags & EROFS_MAP_MAPPED)) { 132 128 folio_zero_segment(folio, cur, cur + len); ··· 154 162 } 155 163 cur += len; 156 164 } 157 - erofs_onlinefolio_end(folio, err); 165 + erofs_onlinefolio_end(folio, err, false); 158 166 return err; 159 167 } 160 168
+4 -2
fs/erofs/internal.h
··· 315 315 /* The length of extent is full */ 316 316 #define EROFS_MAP_FULL_MAPPED 0x0008 317 317 /* Located in the special packed inode */ 318 - #define EROFS_MAP_FRAGMENT 0x0010 318 + #define __EROFS_MAP_FRAGMENT 0x0010 319 319 /* The extent refers to partial decompressed data */ 320 320 #define EROFS_MAP_PARTIAL_REF 0x0020 321 + 322 + #define EROFS_MAP_FRAGMENT (EROFS_MAP_MAPPED | __EROFS_MAP_FRAGMENT) 321 323 322 324 struct erofs_map_blocks { 323 325 struct erofs_buf buf; ··· 392 390 int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map); 393 391 void erofs_onlinefolio_init(struct folio *folio); 394 392 void erofs_onlinefolio_split(struct folio *folio); 395 - void erofs_onlinefolio_end(struct folio *folio, int err); 393 + void erofs_onlinefolio_end(struct folio *folio, int err, bool dirty); 396 394 struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid); 397 395 int erofs_getattr(struct mnt_idmap *idmap, const struct path *path, 398 396 struct kstat *stat, u32 request_mask,
+4 -4
fs/erofs/zdata.c
··· 1034 1034 if (!(map->m_flags & EROFS_MAP_MAPPED)) { 1035 1035 folio_zero_segment(folio, cur, end); 1036 1036 tight = false; 1037 - } else if (map->m_flags & EROFS_MAP_FRAGMENT) { 1037 + } else if (map->m_flags & __EROFS_MAP_FRAGMENT) { 1038 1038 erofs_off_t fpos = offset + cur - map->m_la; 1039 1039 1040 1040 err = z_erofs_read_fragment(inode->i_sb, folio, cur, ··· 1091 1091 tight = (bs == PAGE_SIZE); 1092 1092 } 1093 1093 } while ((end = cur) > 0); 1094 - erofs_onlinefolio_end(folio, err); 1094 + erofs_onlinefolio_end(folio, err, false); 1095 1095 return err; 1096 1096 } 1097 1097 ··· 1196 1196 cur += len; 1197 1197 } 1198 1198 kunmap_local(dst); 1199 - erofs_onlinefolio_end(page_folio(bvi->bvec.page), err); 1199 + erofs_onlinefolio_end(page_folio(bvi->bvec.page), err, true); 1200 1200 list_del(p); 1201 1201 kfree(bvi); 1202 1202 } ··· 1355 1355 1356 1356 DBG_BUGON(z_erofs_page_is_invalidated(page)); 1357 1357 if (!z_erofs_is_shortlived_page(page)) { 1358 - erofs_onlinefolio_end(page_folio(page), err); 1358 + erofs_onlinefolio_end(page_folio(page), err, true); 1359 1359 continue; 1360 1360 } 1361 1361 if (pcl->algorithmformat != Z_EROFS_COMPRESSION_LZ4) {
+4 -5
fs/erofs/zmap.c
··· 413 413 !vi->z_tailextent_headlcn) { 414 414 map->m_la = 0; 415 415 map->m_llen = inode->i_size; 416 - map->m_flags = EROFS_MAP_MAPPED | 417 - EROFS_MAP_FULL_MAPPED | EROFS_MAP_FRAGMENT; 416 + map->m_flags = EROFS_MAP_FRAGMENT; 418 417 return 0; 419 418 } 420 419 initial_lcn = ofs >> lclusterbits; ··· 488 489 goto unmap_out; 489 490 } 490 491 } else if (fragment && m.lcn == vi->z_tailextent_headlcn) { 491 - map->m_flags |= EROFS_MAP_FRAGMENT; 492 + map->m_flags = EROFS_MAP_FRAGMENT; 492 493 } else { 493 494 map->m_pa = erofs_pos(sb, m.pblk); 494 495 err = z_erofs_get_extent_compressedlen(&m, initial_lcn); ··· 616 617 if (lstart < lend) { 617 618 map->m_la = lstart; 618 619 if (last && (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER)) { 619 - map->m_flags |= EROFS_MAP_MAPPED | EROFS_MAP_FRAGMENT; 620 + map->m_flags = EROFS_MAP_FRAGMENT; 620 621 vi->z_fragmentoff = map->m_plen; 621 622 if (recsz > offsetof(struct z_erofs_extent, pstart_lo)) 622 623 vi->z_fragmentoff |= map->m_pa << 32; ··· 796 797 iomap->length = map.m_llen; 797 798 if (map.m_flags & EROFS_MAP_MAPPED) { 798 799 iomap->type = IOMAP_MAPPED; 799 - iomap->addr = map.m_flags & EROFS_MAP_FRAGMENT ? 800 + iomap->addr = map.m_flags & __EROFS_MAP_FRAGMENT ? 800 801 IOMAP_NULL_ADDR : map.m_pa; 801 802 } else { 802 803 iomap->type = IOMAP_HOLE;