erofs-utils: mkfs: fragment: gracefully exit if temporary storage is low
authorGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 12 Feb 2025 12:36:33 +0000 (20:36 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 12 Feb 2025 12:50:54 +0000 (20:50 +0800)
Currently, EROFS keeps all fragments into a temporary file for later
packed inode compression.  However, this could trigger an unexpected
segfault if temporary storage runs low.

Print a proper error message and gracefully exit.

Closes: https://github.com/erofs/erofs-utils/issues/13
Link: https://lore.kernel.org/r/20250212123633.40004-1-hsiangkao@linux.alibaba.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
include/erofs/internal.h
lib/fragments.c
lib/inode.c

index 5f5bc10d31636c94f9cc683e2f8e2b2dfad49664..2f715572b6e77d008c0193d6ca98666a9928343e 100644 (file)
@@ -256,7 +256,6 @@ struct erofs_inode {
        unsigned int eof_tailrawsize;
 
        union {
-               void *compressmeta;
                void *chunkindexes;
                struct {
                        uint16_t z_advise;
@@ -274,6 +273,8 @@ struct erofs_inode {
 #define z_idata_size   idata_size
                };
        };
+       void *compressmeta;
+
 #ifdef WITH_ANDROID
        uint64_t capabilities;
 #endif
index 32ac6f5a8252638d8cb21e38d5484ce41d2aaac1..9633a2bebb9b594509060c0506cfdfeb8b8f934c 100644 (file)
@@ -266,6 +266,10 @@ int z_erofs_pack_file_from_fd(struct erofs_inode *inode, int fd, u32 tofcrc)
        else
                rc = 0;
 out:
+       if (rc)
+               erofs_err("Failed to record %llu-byte fragment data @ %llu for nid %llu: %d",
+                         inode->fragment_size | 0ULL,
+                         inode->fragmentoff | 0ULL, inode->nid | 0ULL, rc);
        if (memblock)
                munmap(memblock, inode->i_size);
        return rc;
index 7f970300583ab79edba75fde5882c4f0a20e1878..743e9154de0ecb07c7653a9c04114e2938f4cfd2 100644 (file)
@@ -141,16 +141,14 @@ unsigned int erofs_iput(struct erofs_inode *inode)
                free(d);
 
        free(inode->compressmeta);
-       if (inode->eof_tailraw)
-               free(inode->eof_tailraw);
+       free(inode->eof_tailraw);
        list_del(&inode->i_hash);
-       if (inode->i_srcpath)
-               free(inode->i_srcpath);
+       free(inode->i_srcpath);
 
        if (inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF) {
                erofs_diskbuf_close(inode->i_diskbuf);
                free(inode->i_diskbuf);
-       } else if (inode->i_link) {
+       } else {
                free(inode->i_link);
        }
        free(inode);