Skip to content

Commit 7ae4609

Browse files
committed
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()
2 parents bb1a114 + ce4b815 commit 7ae4609

File tree

4 files changed

+23
-25
lines changed

4 files changed

+23
-25
lines changed

fs/erofs/fscache.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,14 +590,17 @@ struct erofs_fscache *erofs_domain_register_cookie(struct super_block *sb,
590590
struct super_block *psb = erofs_pseudo_mnt->mnt_sb;
591591

592592
mutex_lock(&erofs_domain_cookies_lock);
593+
spin_lock(&psb->s_inode_list_lock);
593594
list_for_each_entry(inode, &psb->s_inodes, i_sb_list) {
594595
ctx = inode->i_private;
595596
if (!ctx || ctx->domain != domain || strcmp(ctx->name, name))
596597
continue;
597598
igrab(inode);
599+
spin_unlock(&psb->s_inode_list_lock);
598600
mutex_unlock(&erofs_domain_cookies_lock);
599601
return ctx;
600602
}
603+
spin_unlock(&psb->s_inode_list_lock);
601604
ctx = erofs_fscache_domain_init_cookie(sb, name, need_inode);
602605
mutex_unlock(&erofs_domain_cookies_lock);
603606
return ctx;

fs/erofs/zdata.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -813,15 +813,14 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
813813
++spiltted;
814814
if (fe->pcl->pageofs_out != (map->m_la & ~PAGE_MASK))
815815
fe->pcl->multibases = true;
816-
817-
if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
818-
!(map->m_flags & EROFS_MAP_PARTIAL_REF) &&
819-
fe->pcl->length == map->m_llen)
820-
fe->pcl->partial = false;
821816
if (fe->pcl->length < offset + end - map->m_la) {
822817
fe->pcl->length = offset + end - map->m_la;
823818
fe->pcl->pageofs_out = map->m_la & ~PAGE_MASK;
824819
}
820+
if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
821+
!(map->m_flags & EROFS_MAP_PARTIAL_REF) &&
822+
fe->pcl->length == map->m_llen)
823+
fe->pcl->partial = false;
825824
next_part:
826825
/* shorten the remaining extent to update progress */
827826
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,
888887

889888
if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK)) {
890889
unsigned int pgnr;
891-
struct page *oldpage;
892890

893891
pgnr = (bvec->offset + be->pcl->pageofs_out) >> PAGE_SHIFT;
894892
DBG_BUGON(pgnr >= be->nr_pages);
895-
oldpage = be->decompressed_pages[pgnr];
896-
be->decompressed_pages[pgnr] = bvec->page;
897-
898-
if (!oldpage)
893+
if (!be->decompressed_pages[pgnr]) {
894+
be->decompressed_pages[pgnr] = bvec->page;
899895
return;
896+
}
900897
}
901898

902899
/* (cold path) one pcluster is requested multiple times */

fs/erofs/zdata.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl)
126126
}
127127

128128
/*
129-
* bit 31: I/O error occurred on this page
130-
* bit 0 - 30: remaining parts to complete this page
129+
* bit 30: I/O error occurred on this page
130+
* bit 0 - 29: remaining parts to complete this page
131131
*/
132-
#define Z_EROFS_PAGE_EIO (1 << 31)
132+
#define Z_EROFS_PAGE_EIO (1 << 30)
133133

134134
static inline void z_erofs_onlinepage_init(struct page *page)
135135
{

fs/erofs/zmap.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
5757

5858
pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
5959
vi->xattr_isize, 8);
60-
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos),
61-
EROFS_KMAP_ATOMIC);
60+
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
6261
if (IS_ERR(kaddr)) {
6362
err = PTR_ERR(kaddr);
6463
goto out_unlock;
@@ -73,7 +72,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
7372
vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER;
7473
vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63);
7574
vi->z_tailextent_headlcn = 0;
76-
goto unmap_done;
75+
goto done;
7776
}
7877
vi->z_advise = le16_to_cpu(h->h_advise);
7978
vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
@@ -85,7 +84,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
8584
erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
8685
headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
8786
err = -EOPNOTSUPP;
88-
goto unmap_done;
87+
goto out_put_metabuf;
8988
}
9089

9190
vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
@@ -95,20 +94,16 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
9594
erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
9695
vi->nid);
9796
err = -EFSCORRUPTED;
98-
goto unmap_done;
97+
goto out_put_metabuf;
9998
}
10099
if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
101100
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
102101
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
103102
erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
104103
vi->nid);
105104
err = -EFSCORRUPTED;
106-
goto unmap_done;
105+
goto out_put_metabuf;
107106
}
108-
unmap_done:
109-
erofs_put_metabuf(&buf);
110-
if (err)
111-
goto out_unlock;
112107

113108
if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
114109
struct erofs_map_blocks map = {
@@ -127,7 +122,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
127122
err = -EFSCORRUPTED;
128123
}
129124
if (err < 0)
130-
goto out_unlock;
125+
goto out_put_metabuf;
131126
}
132127

133128
if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER &&
@@ -141,11 +136,14 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
141136
EROFS_GET_BLOCKS_FINDTAIL);
142137
erofs_put_metabuf(&map.buf);
143138
if (err < 0)
144-
goto out_unlock;
139+
goto out_put_metabuf;
145140
}
141+
done:
146142
/* paired with smp_mb() at the beginning of the function */
147143
smp_mb();
148144
set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
145+
out_put_metabuf:
146+
erofs_put_metabuf(&buf);
149147
out_unlock:
150148
clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
151149
return err;

0 commit comments

Comments
 (0)