[PATCH] erofs-utils: mkfs,fsck,dump: support `--offset` option
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Nov 7 17:21:17 AEDT 2023
Add `--offset` option to allows users to specify an offset in the file
where the filesystem will begin.
Suggested-by: Pavel Otchertsov <pavel.otchertsov at gmail.com>
Closes: https://lore.kernel.org/r/CAAxnTOGTD2NkKnBphZ+vEr7NVnWvT0u02E+c8pN8ZVFcXp5uhg@mail.gmail.com
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
Hi Pavel,
Could you check if the following patch resolves your requirement?
dump/main.c | 11 +++++++++++
fsck/main.c | 11 +++++++++++
fuse/main.c | 5 ++---
include/erofs/config.h | 3 ---
include/erofs/internal.h | 2 ++
lib/blobchunk.c | 1 +
lib/io.c | 12 +++++++-----
mkfs/main.c | 10 ++++++++++
8 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/dump/main.c b/dump/main.c
index 293093d..8da9cbc 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -80,6 +80,7 @@ static struct option long_options[] = {
{"device", required_argument, NULL, 3},
{"path", required_argument, NULL, 4},
{"ls", no_argument, NULL, 5},
+ {"offset", required_argument, NULL, 6},
{0, 0, 0, 0},
};
@@ -124,6 +125,7 @@ static void usage(int argc, char **argv)
" --device=X specify an extra device to be used together\n"
" --ls show directory contents (INODE required)\n"
" --nid=# show the target inode info of nid #\n"
+ " --offset=# skip # bytes at the beginning of IMAGE\n"
" --path=X show the target inode info of path X\n",
argv[0]);
}
@@ -136,6 +138,7 @@ static void erofsdump_print_version(void)
static int erofsdump_parse_options_cfg(int argc, char **argv)
{
int opt, err;
+ char *endptr;
while ((opt = getopt_long(argc, argv, "SVesh",
long_options, NULL)) != -1) {
@@ -177,6 +180,14 @@ static int erofsdump_parse_options_cfg(int argc, char **argv)
case 5:
dumpcfg.show_subdirectories = true;
break;
+ case 6:
+ err = strtoull(optarg, &endptr, 0);
+ if (*endptr != '\0') {
+ erofs_err("invalid disk offset %s", optarg);
+ return -EINVAL;
+ }
+ sbi.diskoffset = err;
+ break;
default:
return -EINVAL;
}
diff --git a/fsck/main.c b/fsck/main.c
index 26cd131..1e45b61 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -48,6 +48,7 @@ static struct option long_options[] = {
{"no-preserve", no_argument, 0, 9},
{"no-preserve-owner", no_argument, 0, 10},
{"no-preserve-perms", no_argument, 0, 11},
+ {"offset", required_argument, 0, 12},
{0, 0, 0, 0},
};
@@ -97,6 +98,7 @@ static void usage(int argc, char **argv)
" --device=X specify an extra device to be used together\n"
" --extract[=X] check if all files are well encoded, optionally\n"
" extract to X\n"
+ " --offset=# skip # bytes at the beginning of IMAGE\n"
"\n"
" -a, -A, -y no-op, for compatibility with fsck of other filesystems\n"
"\n"
@@ -123,6 +125,7 @@ static void erofsfsck_print_version(void)
static int erofsfsck_parse_options_cfg(int argc, char **argv)
{
+ char *endptr;
int opt, ret;
bool has_opt_preserve = false;
@@ -216,6 +219,14 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
fsckcfg.preserve_perms = false;
has_opt_preserve = true;
break;
+ case 12:
+ ret = strtoull(optarg, &endptr, 0);
+ if (*endptr != '\0') {
+ erofs_err("invalid disk offset %s", optarg);
+ return -EINVAL;
+ }
+ sbi.diskoffset = ret;
+ break;
default:
return -EINVAL;
}
diff --git a/fuse/main.c b/fuse/main.c
index 5b2c64d..f07165c 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -547,7 +547,7 @@ static void usage(void)
#endif
fputs("usage: [options] IMAGE MOUNTPOINT\n\n"
"Options:\n"
- " --offset=# skip # bytes when reading IMAGE\n"
+ " --offset=# skip # bytes at the beginning of IMAGE\n"
" --dbglevel=# set output message level to # (maximum 9)\n"
" --device=# specify an extra device to be used together\n"
#if FUSE_MAJOR_VERSION < 3
@@ -676,8 +676,7 @@ int main(int argc, char *argv[])
if (fusecfg.odebug && cfg.c_dbg_lvl < EROFS_DBG)
cfg.c_dbg_lvl = EROFS_DBG;
- cfg.c_offset = fusecfg.offset;
-
+ sbi.diskoffset = fusecfg.offset;
ret = dev_open_ro(&sbi, fusecfg.disk);
if (ret) {
fprintf(stderr, "failed to open: %s\n", fusecfg.disk);
diff --git a/include/erofs/config.h b/include/erofs/config.h
index e342722..89fe522 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -83,9 +83,6 @@ struct erofs_configure {
char *fs_config_file;
char *block_list_file;
#endif
-
- /* offset when reading multi partition images */
- u64 c_offset;
};
extern struct erofs_configure cfg;
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 4d794ae..78b9f32 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -110,6 +110,8 @@ struct erofs_sb_info {
struct erofs_xattr_prefix_item *xattr_prefixes;
int devfd, devblksz;
+ /* offset when reading multi-part images */
+ u64 diskoffset;
u64 devsz;
dev_t dev;
unsigned int nblobs;
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index e4d0bad..6d2501e 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -448,6 +448,7 @@ int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
pos_out = erofs_btell(bh, false);
remapped_base = erofs_blknr(sbi, pos_out);
+ pos_out += sbi->diskoffset;
if (blobfile) {
pos_in = 0;
ret = erofs_copy_file_range(fileno(blobfile), &pos_in,
diff --git a/lib/io.c b/lib/io.c
index c92f16c..85d5156 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -194,6 +194,7 @@ int dev_write(struct erofs_sb_info *sbi, const void *buf, u64 offset, size_t len
return -EINVAL;
}
+ offset += sbi->diskoffset;
if (offset >= sbi->devsz || len > sbi->devsz ||
offset > sbi->devsz - len) {
erofs_err("Write posion[%" PRIu64 ", %zd] is too large beyond the end of device(%" PRIu64 ").",
@@ -230,7 +231,7 @@ int dev_fillzero(struct erofs_sb_info *sbi, u64 offset, size_t len, bool padding
#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
if (!padding && fallocate(sbi->devfd, FALLOC_FL_PUNCH_HOLE |
- FALLOC_FL_KEEP_SIZE, offset, len) >= 0)
+ FALLOC_FL_KEEP_SIZE, offset + sbi->diskoffset, len) >= 0)
return 0;
#endif
while (len > erofs_blksiz(sbi)) {
@@ -255,7 +256,7 @@ int dev_fsync(struct erofs_sb_info *sbi)
return 0;
}
-int dev_resize(struct erofs_sb_info *sbi, unsigned int blocks)
+int dev_resize(struct erofs_sb_info *sbi, erofs_blk_t blocks)
{
int ret;
struct stat st;
@@ -271,6 +272,7 @@ int dev_resize(struct erofs_sb_info *sbi, unsigned int blocks)
}
length = (u64)blocks * erofs_blksiz(sbi);
+ length += sbi->diskoffset;
if (st.st_size == length)
return 0;
if (st.st_size > length)
@@ -281,7 +283,8 @@ int dev_resize(struct erofs_sb_info *sbi, unsigned int blocks)
if (fallocate(sbi->devfd, 0, st.st_size, length) >= 0)
return 0;
#endif
- return dev_fillzero(sbi, st.st_size, length, true);
+ return dev_fillzero(sbi, st.st_size - sbi->diskoffset,
+ length, true);
}
int dev_read(struct erofs_sb_info *sbi, int device_id,
@@ -292,8 +295,7 @@ int dev_read(struct erofs_sb_info *sbi, int device_id,
if (cfg.c_dry_run)
return 0;
- offset += cfg.c_offset;
-
+ offset += sbi->diskoffset;
if (!buf) {
erofs_err("buf is NULL");
return -EINVAL;
diff --git a/mkfs/main.c b/mkfs/main.c
index f024026..ea871b2 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -71,6 +71,7 @@ static struct option long_options[] = {
#ifdef HAVE_ZLIB
{"gzip", no_argument, NULL, 517},
#endif
+ {"offset", required_argument, NULL, 518},
{0, 0, 0, 0},
};
@@ -151,6 +152,7 @@ static void usage(int argc, char **argv)
" --ignore-mtime use build time instead of strict per-file modification time\n"
" --max-extent-bytes=# set maximum decompressed extent size # in bytes\n"
" --preserve-mtime keep per-file modification time strictly\n"
+ " --offset=# skip # bytes at the beginning of IMAGE.\n"
" --aufs replace aufs special files with overlayfs metadata\n"
" --tar=[fi] generate an image from tarball(s)\n"
" --ovlfs-strip=<0,1> strip overlayfs metadata in the target image (e.g. whiteouts)\n"
@@ -571,6 +573,14 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
case 517:
gzip_supported = true;
break;
+ case 518:
+ i = strtoull(optarg, &endptr, 0);
+ if (*endptr != '\0') {
+ erofs_err("invalid disk offset %s", optarg);
+ return -EINVAL;
+ }
+ sbi.diskoffset = i;
+ break;
case 'V':
version();
exit(0);
--
2.39.3
More information about the Linux-erofs
mailing list