Whamcloud - gitweb
EX-9878 csdc: is_chunk_start should return header copy
authorArtem Blagodarenko <ablagodarenko@ddn.com>
Mon, 3 Jun 2024 10:57:33 +0000 (06:57 -0400)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 6 Jun 2024 08:20:04 +0000 (08:20 +0000)
In is_chunk_start()

*ret_header = header;
...
kunmap_atomic(header);

ret_header is used after is_chunk_start(). The header
copy should be returned from is_chunk_start() for safe work.

Test-Parameters: testlist=sanity-compr
Signed-off-by: Artem Blagodarenko <ablagodarenko@ddn.com>
Change-Id: Ib5e828d6b61e90dcd70c28589931a4490cf19c22
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/55292
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/include/lustre_compr.h
lustre/obdclass/lustre_compr.c
lustre/ofd/ofd_compress.c
lustre/osc/osc_compress.c

index c5b6452..35d24f2 100644 (file)
@@ -47,7 +47,7 @@ static inline struct page *mem_to_page(void *addr)
        return vmalloc_to_page(addr);
 }
 
-int is_chunk_start(struct page *page, struct ll_compr_hdr **ret_header, int *rc);
+int is_chunk_start(struct page *page, struct ll_compr_hdr *ret_header, int *rc);
 
 int decompress_chunk(const char *obd_name, struct crypto_comp *cc,
                     unsigned char *in, unsigned int in_len,
index c3cdb26..7ff0b22 100644 (file)
@@ -382,7 +382,7 @@ static int chunk_header_csum_valid(struct ll_compr_hdr *header)
        return 1;
 }
 
-int is_chunk_start(struct page *page, struct ll_compr_hdr **ret_header, int *rc)
+int is_chunk_start(struct page *page, struct ll_compr_hdr *ret_header, int *rc)
 {
        struct ll_compr_hdr *header;
        int retval = 1;
@@ -424,7 +424,7 @@ int is_chunk_start(struct page *page, struct ll_compr_hdr **ret_header, int *rc)
                }
        }
 
-       *ret_header = header;
+       *ret_header = *header;
 
        kunmap_atomic(header);
 
index 0e8bd5f..24bd8bf 100644 (file)
@@ -39,7 +39,7 @@ static int decompress_chunk_in_lnb(const char *obd_name, struct lu_fid *fid,
                                   enum ll_compr_type type, int lvl,
                                   int chunk_size, bool write)
 {
-       struct ll_compr_hdr *llch = NULL;
+       struct ll_compr_hdr llch;
        struct crypto_comp *cc = NULL;
        int pages_in_chunk = chunk_size / PAGE_SIZE;
        /* dst_size must be initialized for kernel compression code */
@@ -71,24 +71,24 @@ static int decompress_chunk_in_lnb(const char *obd_name, struct lu_fid *fid,
         */
        CDEBUG(D_SEC,
               "chunk_size %d, layout: type %d, lvl %d, disk: type %d, lvl %d\n",
-              chunk_size, type, lvl, llch->llch_compr_type,
-              llch->llch_compr_level);
+              chunk_size, type, lvl, llch.llch_compr_type,
+              llch.llch_compr_level);
        if (chunk_size !=
-           COMPR_GET_CHUNK_SIZE(llch->llch_chunk_log_bits)) {
+           COMPR_GET_CHUNK_SIZE(llch.llch_chunk_log_bits)) {
                CERROR("%s: chunk size disagreement: "DFID" at %llu: layout %d, from disk %d\n",
                       obd_name, PFID(fid), lnbs[lnb_start].lnb_file_offset,
                       chunk_size,
-                      COMPR_GET_CHUNK_SIZE(llch->llch_chunk_log_bits));
+                      COMPR_GET_CHUNK_SIZE(llch.llch_chunk_log_bits));
                /* compression type and level can disagree with layout, we just
                 * dump them for debugging
                 */
                CERROR("layout: type %d, lvl %d, disk: type %d, lvl %d\n",
-                      type, lvl, llch->llch_compr_type, llch->llch_compr_level);
+                      type, lvl, llch.llch_compr_type, llch.llch_compr_level);
                GOTO(out, rc = -EINVAL);
        }
-       type = llch->llch_compr_type;
-       lvl = llch->llch_compr_level;
-       hdr_size = llch->llch_header_size;
+       type = llch.llch_compr_type;
+       lvl = llch.llch_compr_level;
+       hdr_size = llch.llch_header_size;
        rc = alloc_decompr(obd_name, &type, &lvl, &cc);
        if (rc) {
                 CERROR("%s: Setup for decompression failed: "DFID" at %llu: type %i, lvl %d: rc = %d\n",
@@ -115,21 +115,21 @@ static int decompress_chunk_in_lnb(const char *obd_name, struct lu_fid *fid,
 
        rc = decompress_chunk(obd_name, cc,
                              ((char *) bounce_src) + hdr_size,
-                              llch->llch_compr_size,
+                              llch.llch_compr_size,
                               (char *) bounce_dst, &dst_size, type,
                               lvl);
        if (rc != 0) {
                CERROR("%s: Failed to decompress: "DFID", %d byte chunk at %llu: rc = %d\n",
-                      obd_name, PFID(fid), llch->llch_compr_size,
+                      obd_name, PFID(fid), llch.llch_compr_size,
                       lnbs[lnb_start].lnb_file_offset, rc);
                GOTO(out, rc);
        }
        /* uncompressed size is not set by older clients, but older clients
         * reliably zero unused parts of the header, so we skip if it's zero
         */
-       if (llch->llch_uncompr_size != 0 && dst_size != llch->llch_uncompr_size) {
+       if (llch.llch_uncompr_size != 0 && dst_size != llch.llch_uncompr_size) {
                CERROR("%s: object invalid, size %d != %d: "DFID" at %llu:  rc = %d\n",
-                      obd_name, llch->llch_uncompr_size, dst_size, PFID(fid),
+                      obd_name, llch.llch_uncompr_size, dst_size, PFID(fid),
                       lnbs[lnb_start].lnb_file_offset, rc);
                GOTO(out, rc = -EUCLEAN);
        }
index 5d8033b..2fa6aa3 100644 (file)
@@ -346,7 +346,7 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count)
 {
        struct brw_page **pga = aa->aa_ppga;
        struct osc_async_page *oap = NULL;
-       struct ll_compr_hdr *llch = NULL;
+       struct ll_compr_hdr llch;
        struct client_obd *cli = aa->aa_cli;
        char *obd_name = cli->cl_import->imp_obd->obd_name;
        enum ll_compr_type type = LL_COMPR_TYPE_NONE;
@@ -427,13 +427,13 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count)
                 * In the future it may be that the type is also changing in
                 * a single component, so handle this properly if that happens.
                 */
-               if (unlikely(cc && type != llch->llch_compr_type)) {
+               if (unlikely(cc && type != llch.llch_compr_type)) {
                        crypto_free_comp(cc);
                        cc = NULL;
                }
                if (!cc) {
-                       type = llch->llch_compr_type;
-                       lvl = llch->llch_compr_level;
+                       type = llch.llch_compr_type;
+                       lvl = llch.llch_compr_level;
                        rc = alloc_decompr(obd_name, &type, &lvl, &cc);
                        if (rc)
                                GOTO(out, rc);
@@ -442,7 +442,7 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count)
                if (!src) { /* get chunk size once */
                        int rpc_chunk_bits;
 
-                       rpc_chunk_bits = llch->llch_chunk_log_bits +
+                       rpc_chunk_bits = llch.llch_chunk_log_bits +
                                COMPR_CHUNK_MIN_BITS;
                        /* the chunk bits from storage must be the same as from
                         * the layout (but don't assert on it, since it comes
@@ -469,7 +469,7 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count)
                                GOTO(out, rc = -ENOMEM);
                }
 
-               compressed_bytes = llch->llch_compr_size + sizeof(*llch);
+               compressed_bytes = llch.llch_compr_size + sizeof(llch);
                compressed_pages = ((compressed_bytes - 1) >> PAGE_SHIFT) + 1;
                CDEBUG(D_SEC, "compressed bytes %d compressed pages %d\n",
                       compressed_bytes, compressed_pages);
@@ -502,11 +502,11 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count)
                }
                dst_size = 2 * chunk_size;
                CDEBUG(D_SEC, "Compressed size %lu, type %i\n",
-                      llch->llch_compr_size + sizeof(*llch), type);
+                      llch.llch_compr_size + sizeof(llch), type);
 
                rc = decompress_chunk(obd_name, cc,
-                                     src + llch->llch_header_size,
-                                     llch->llch_compr_size, dst, &dst_size,
+                                     src + llch.llch_header_size,
+                                     llch.llch_compr_size, dst, &dst_size,
                                      type, lvl);
                if (rc)
                        GOTO(out, rc);