mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Changes since last update:
- Fix illegal unmapped accesses when initializing compressed inodes; - Fix up very rare hung on page lock after enabling compressed data deduplication; - Fix up inplace decompression success rate; - Take s_inode_list_lock to protect sb->s_inodes for fscache shared domain. -----BEGIN PGP SIGNATURE----- iIcEABYIAC8WIQThPAmQN9sSA0DVxtI5NzHcH7XmBAUCY05u9xEceGlhbmdAa2Vy bmVsLm9yZwAKCRA5NzHcH7XmBHp1AQCXNLts5Af2PdRZUcG8RP0IAM0cZbXM9oZE e520B85VRQD8CuHE4xemQ6pN7iTcBRS/i60p5UF3pCr5PJ0WGcf5gwU= =/mdV -----END PGP SIGNATURE----- Merge tag 'erofs-for-6.1-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs fixes from Gao Xiang: - Fix invalid unmapped accesses when initializing compressed inodes - Fix up very rare hung on page lock after enabling compressed data deduplication - Fix up inplace decompression success rate - Take s_inode_list_lock to protect sb->s_inodes for fscache shared domain * tag 'erofs-for-6.1-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: protect s_inodes with s_inode_list_lock for fscache erofs: fix up inplace decompression success rate erofs: shouldn't churn the mapping page for duplicated copies erofs: fix illegal unmapped accesses in z_erofs_fill_inode_lazy()
This commit is contained in:
commit
7ae460973d
@ -590,14 +590,17 @@ struct erofs_fscache *erofs_domain_register_cookie(struct super_block *sb,
|
||||
struct super_block *psb = erofs_pseudo_mnt->mnt_sb;
|
||||
|
||||
mutex_lock(&erofs_domain_cookies_lock);
|
||||
spin_lock(&psb->s_inode_list_lock);
|
||||
list_for_each_entry(inode, &psb->s_inodes, i_sb_list) {
|
||||
ctx = inode->i_private;
|
||||
if (!ctx || ctx->domain != domain || strcmp(ctx->name, name))
|
||||
continue;
|
||||
igrab(inode);
|
||||
spin_unlock(&psb->s_inode_list_lock);
|
||||
mutex_unlock(&erofs_domain_cookies_lock);
|
||||
return ctx;
|
||||
}
|
||||
spin_unlock(&psb->s_inode_list_lock);
|
||||
ctx = erofs_fscache_domain_init_cookie(sb, name, need_inode);
|
||||
mutex_unlock(&erofs_domain_cookies_lock);
|
||||
return ctx;
|
||||
|
@ -813,15 +813,14 @@ retry:
|
||||
++spiltted;
|
||||
if (fe->pcl->pageofs_out != (map->m_la & ~PAGE_MASK))
|
||||
fe->pcl->multibases = true;
|
||||
|
||||
if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
|
||||
!(map->m_flags & EROFS_MAP_PARTIAL_REF) &&
|
||||
fe->pcl->length == map->m_llen)
|
||||
fe->pcl->partial = false;
|
||||
if (fe->pcl->length < offset + end - map->m_la) {
|
||||
fe->pcl->length = offset + end - map->m_la;
|
||||
fe->pcl->pageofs_out = map->m_la & ~PAGE_MASK;
|
||||
}
|
||||
if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
|
||||
!(map->m_flags & EROFS_MAP_PARTIAL_REF) &&
|
||||
fe->pcl->length == map->m_llen)
|
||||
fe->pcl->partial = false;
|
||||
next_part:
|
||||
/* shorten the remaining extent to update progress */
|
||||
map->m_llen = offset + cur - map->m_la;
|
||||
@ -888,15 +887,13 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be,
|
||||
|
||||
if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK)) {
|
||||
unsigned int pgnr;
|
||||
struct page *oldpage;
|
||||
|
||||
pgnr = (bvec->offset + be->pcl->pageofs_out) >> PAGE_SHIFT;
|
||||
DBG_BUGON(pgnr >= be->nr_pages);
|
||||
oldpage = be->decompressed_pages[pgnr];
|
||||
be->decompressed_pages[pgnr] = bvec->page;
|
||||
|
||||
if (!oldpage)
|
||||
if (!be->decompressed_pages[pgnr]) {
|
||||
be->decompressed_pages[pgnr] = bvec->page;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* (cold path) one pcluster is requested multiple times */
|
||||
|
@ -126,10 +126,10 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl)
|
||||
}
|
||||
|
||||
/*
|
||||
* bit 31: I/O error occurred on this page
|
||||
* bit 0 - 30: remaining parts to complete this page
|
||||
* bit 30: I/O error occurred on this page
|
||||
* bit 0 - 29: remaining parts to complete this page
|
||||
*/
|
||||
#define Z_EROFS_PAGE_EIO (1 << 31)
|
||||
#define Z_EROFS_PAGE_EIO (1 << 30)
|
||||
|
||||
static inline void z_erofs_onlinepage_init(struct page *page)
|
||||
{
|
||||
|
@ -57,8 +57,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
|
||||
|
||||
pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
|
||||
vi->xattr_isize, 8);
|
||||
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos),
|
||||
EROFS_KMAP_ATOMIC);
|
||||
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
|
||||
if (IS_ERR(kaddr)) {
|
||||
err = PTR_ERR(kaddr);
|
||||
goto out_unlock;
|
||||
@ -73,7 +72,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
|
||||
vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER;
|
||||
vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63);
|
||||
vi->z_tailextent_headlcn = 0;
|
||||
goto unmap_done;
|
||||
goto done;
|
||||
}
|
||||
vi->z_advise = le16_to_cpu(h->h_advise);
|
||||
vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
|
||||
@ -85,7 +84,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
|
||||
erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
|
||||
headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
|
||||
err = -EOPNOTSUPP;
|
||||
goto unmap_done;
|
||||
goto out_put_metabuf;
|
||||
}
|
||||
|
||||
vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
|
||||
@ -95,7 +94,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
|
||||
erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
|
||||
vi->nid);
|
||||
err = -EFSCORRUPTED;
|
||||
goto unmap_done;
|
||||
goto out_put_metabuf;
|
||||
}
|
||||
if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
|
||||
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
|
||||
@ -103,12 +102,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
|
||||
erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
|
||||
vi->nid);
|
||||
err = -EFSCORRUPTED;
|
||||
goto unmap_done;
|
||||
goto out_put_metabuf;
|
||||
}
|
||||
unmap_done:
|
||||
erofs_put_metabuf(&buf);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
|
||||
struct erofs_map_blocks map = {
|
||||
@ -127,7 +122,7 @@ unmap_done:
|
||||
err = -EFSCORRUPTED;
|
||||
}
|
||||
if (err < 0)
|
||||
goto out_unlock;
|
||||
goto out_put_metabuf;
|
||||
}
|
||||
|
||||
if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER &&
|
||||
@ -141,11 +136,14 @@ unmap_done:
|
||||
EROFS_GET_BLOCKS_FINDTAIL);
|
||||
erofs_put_metabuf(&map.buf);
|
||||
if (err < 0)
|
||||
goto out_unlock;
|
||||
goto out_put_metabuf;
|
||||
}
|
||||
done:
|
||||
/* paired with smp_mb() at the beginning of the function */
|
||||
smp_mb();
|
||||
set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
|
||||
out_put_metabuf:
|
||||
erofs_put_metabuf(&buf);
|
||||
out_unlock:
|
||||
clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
|
||||
return err;
|
||||
|
Loading…
Reference in New Issue
Block a user