]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
erofs: do sanity check on m->type in z_erofs_load_compact_lcluster()
authorChao Yu <chao@kernel.org>
Tue, 8 Jul 2025 11:09:28 +0000 (19:09 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Thu, 24 Jul 2025 11:42:05 +0000 (19:42 +0800)
All below functions will do sanity check on m->type, let's move sanity
check to z_erofs_load_compact_lcluster() for cleanup.
- z_erofs_map_blocks_fo
- z_erofs_get_extent_compressedlen
- z_erofs_get_extent_decompressedlen
- z_erofs_extent_lookback

Reviewed-by: Hongbo Li <lihongbo22@huawei.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20250708110928.3110375-1-chao@kernel.org
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
fs/erofs/zmap.c

index f1a15ff22147ba1bfff0ac4203d17d8c93a57136..312ec54668aac9a7f4d2fcf7dc84e36d49f514b3 100644 (file)
@@ -240,6 +240,13 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
 static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m,
                                           unsigned int lcn, bool lookahead)
 {
+       if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
+               erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu",
+                               m->type, lcn, EROFS_I(m->inode)->nid);
+               DBG_BUGON(1);
+               return -EOPNOTSUPP;
+       }
+
        switch (EROFS_I(m->inode)->datalayout) {
        case EROFS_INODE_COMPRESSED_FULL:
                return z_erofs_load_full_lcluster(m, lcn);
@@ -265,12 +272,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
                if (err)
                        return err;
 
-               if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
-                       erofs_err(sb, "unknown type %u @ lcn %lu of nid %llu",
-                                 m->type, lcn, vi->nid);
-                       DBG_BUGON(1);
-                       return -EOPNOTSUPP;
-               } else if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
+               if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
                        lookback_distance = m->delta[0];
                        if (!lookback_distance)
                                break;
@@ -325,25 +327,18 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
        DBG_BUGON(lcn == initial_lcn &&
                  m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
 
-       if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
-               if (m->delta[0] != 1) {
-                       erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
-                       DBG_BUGON(1);
-                       return -EFSCORRUPTED;
-               }
-               if (m->compressedblks)
-                       goto out;
-       } else if (m->type < Z_EROFS_LCLUSTER_TYPE_MAX) {
-               /*
-                * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
-                * rather than CBLKCNT, it's a 1 block-sized pcluster.
-                */
-               m->compressedblks = 1;
-               goto out;
+       if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD && m->delta[0] != 1) {
+               erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
+               DBG_BUGON(1);
+               return -EFSCORRUPTED;
        }
-       erofs_err(sb, "cannot found CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
-       DBG_BUGON(1);
-       return -EFSCORRUPTED;
+
+       /*
+        * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type rather
+        * than CBLKCNT, it's a 1 block-sized pcluster.
+        */
+       if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD || !m->compressedblks)
+               m->compressedblks = 1;
 out:
        m->map->m_plen = erofs_pos(sb, m->compressedblks);
        return 0;
@@ -379,11 +374,6 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
                        if (lcn != headlcn)
                                break;  /* ends at the next HEAD lcluster */
                        m->delta[1] = 1;
-               } else {
-                       erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu",
-                                 m->type, lcn, vi->nid);
-                       DBG_BUGON(1);
-                       return -EOPNOTSUPP;
                }
                lcn += m->delta[1];
        }
@@ -428,44 +418,33 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
        map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
        end = (m.lcn + 1ULL) << lclusterbits;
 
-       switch (m.type) {
-       case Z_EROFS_LCLUSTER_TYPE_PLAIN:
-       case Z_EROFS_LCLUSTER_TYPE_HEAD1:
-       case Z_EROFS_LCLUSTER_TYPE_HEAD2:
-               if (endoff >= m.clusterofs) {
-                       m.headtype = m.type;
-                       map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
-                       /*
-                        * For ztailpacking files, in order to inline data more
-                        * effectively, special EOF lclusters are now supported
-                        * which can have three parts at most.
-                        */
-                       if (ztailpacking && end > inode->i_size)
-                               end = inode->i_size;
-                       break;
-               }
-               /* m.lcn should be >= 1 if endoff < m.clusterofs */
-               if (!m.lcn) {
-                       erofs_err(sb, "invalid logical cluster 0 at nid %llu",
-                                 vi->nid);
-                       err = -EFSCORRUPTED;
-                       goto unmap_out;
+       if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && endoff >= m.clusterofs) {
+               m.headtype = m.type;
+               map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
+               /*
+                * For ztailpacking files, in order to inline data more
+                * effectively, special EOF lclusters are now supported
+                * which can have three parts at most.
+                */
+               if (ztailpacking && end > inode->i_size)
+                       end = inode->i_size;
+       } else {
+               if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
+                       /* m.lcn should be >= 1 if endoff < m.clusterofs */
+                       if (!m.lcn) {
+                               erofs_err(sb, "invalid logical cluster 0 at nid %llu",
+                                         vi->nid);
+                               err = -EFSCORRUPTED;
+                               goto unmap_out;
+                       }
+                       end = (m.lcn << lclusterbits) | m.clusterofs;
+                       map->m_flags |= EROFS_MAP_FULL_MAPPED;
+                       m.delta[0] = 1;
                }
-               end = (m.lcn << lclusterbits) | m.clusterofs;
-               map->m_flags |= EROFS_MAP_FULL_MAPPED;
-               m.delta[0] = 1;
-               fallthrough;
-       case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
                /* get the corresponding first chunk */
                err = z_erofs_extent_lookback(&m, m.delta[0]);
                if (err)
                        goto unmap_out;
-               break;
-       default:
-               erofs_err(sb, "unknown type %u @ offset %llu of nid %llu",
-                         m.type, ofs, vi->nid);
-               err = -EOPNOTSUPP;
-               goto unmap_out;
        }
        if (m.partialref)
                map->m_flags |= EROFS_MAP_PARTIAL_REF;