[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