[PATCH v8] erofs-utils: add support for fuse 2/3 lowlevel API
Gao Xiang
hsiangkao at linux.alibaba.com
Sat Sep 2 02:39:18 AEST 2023
On 2023/9/2 00:09, Li Yiyan wrote:
> Add support for the fuse low-level API in erofsfuse, proven correct in> 22 test cases. Lowlevel API offers improved performance compared to the
> high-level API, while maintaining compatibility with fuse version
> 2(>=2.6) and 3 (>=3.0).
Support FUSE low-level APIs for erofsfuse. Lowlevel APIs offer
improved performance compared to the previous high-level APIs,
while maintaining compatibility with libfuse version 2(>=2.6)
and 3 (>=3.0).
>
> Dataset: linux 5.15
> Compression algorithm: -z4hc,12
Compression algorithm: lz4hc, 12
> Additional options: -T0 -C16384
> Test options: --warmup 3 -p "echo 3 > /proc/sys/vm/drop_caches; sleep 1"
>
> Evaluation result (highlevel->lowlevel avg time):
> - Sequence metadata: 777.3 ms->180.9 ms
> - Sequence data: 3.282 s->818.1 ms
> - Random metadata: 1.571 s->928.3 ms
> - Random data: 2.461 s->597.8 ms
>
> Signed-off-by: Li Yiyan <lyy0627 at sjtu.edu.cn>
> ---
...
> +
> +static int erofsfuse_add_dentry(struct erofs_dir_context *ctx)
> {
> - struct erofsfuse_dir_context *fusectx = (void *)ctx;
> - struct stat st = {0};
> + size_t size = 0;
> char dname[EROFS_NAME_LEN + 1];
> + struct erofsfuse_readdir_context *readdir_ctx = (void *)ctx;
> +
> + if (readdir_ctx->offset < readdir_ctx->start_off) {
> + readdir_ctx->offset +=
> + ctx->de_namelen + sizeof(struct erofs_dirent);
> + return 0;
> + }
>
> strncpy(dname, ctx->dname, ctx->de_namelen);
> dname[ctx->de_namelen] = '\0';
> - st.st_mode = erofs_ftype_to_dtype(ctx->de_ftype) << 12;
here << 12 means S_SHIFT.
> - fusectx->filler(fusectx->buf, dname, &st, 0);
> + readdir_ctx->offset += ctx->de_namelen + sizeof(struct erofs_dirent);
> +
> + if (!readdir_ctx->is_plus) { /* fuse 3 still use non-plus readdir */
> + struct stat st = { 0 };
> +
> + st.st_mode = erofs_ftype_to_dtype(ctx->de_ftype);
I'm afriad that is incorrect. Maybe we need a erofs_ftype_to_umode()
helper then.
> + st.st_ino = ctx->de_nid;
> + size = fuse_add_direntry(readdir_ctx->req, readdir_ctx->buf,
> + readdir_ctx->buf_size, dname, &st,
> + readdir_ctx->offset);
> + } else {
> +#if FUSE_MAJOR_VERSION >= 3
> + struct fuse_entry_param param;
I think here you could define as
struct fuse_entry_param param = {
.ino = erofsfuse_to_ino(ctx->de_nid),
.attr.st_ino = ctx->de_nid,
.attr.st_mode = erofs_ftype_to_umode(ctx->de_ftype),
};
to avoid uninitialized fields.
> +
> + param.ino = erofsfuse_to_ino(ctx->de_nid);
> + param.generation = 0;
> + param.attr.st_ino = ctx->de_nid;
> + param.attr.st_mode = erofs_ftype_to_dtype(ctx->de_ftype);
ditto.
Otherwise it looks good to me generally.
Thanks,
Gao Xiang
More information about the Linux-erofs
mailing list