Re: [PATCH 1/2] ublk: support ublk recovery

Gao Xiang <[email protected]>
Newsgroups org.ozlabs.lists.linux-erofs
Message-ID <[email protected]>
Hi Chengyu,

On 2026/6/19 12:19, Chengyu wrote:
> From: Chengyu Zhu <[email protected]>
> 
> Enable ublk user recovery so erofsmount can reattach a daemon to a
> recoverable ublk device after the previous userspace server exits.
> 
> Store the recovery source information in a ublk-specific runtime record,
> create ublk devices with user recovery enabled, and add the mount-side
> reattach path for existing recoverable ublk devices.
> 
> Also encode ublk IO uring command opcodes explicitly for non-legacy kernels,
> and initialize the control ring before querying whether a ublk device is
> recoverable.
> 
> Signed-off-by: Chengyu Zhu <[email protected]>
> ---
>   lib/backends/ublk.c |  23 ++++++---
>   mount/main.c        | 115 ++++++++++++++++++++++++++++++++++++++++----
>   2 files changed, 122 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/backends/ublk.c b/lib/backends/ublk.c
> index a8ecad9..49191de 100644
> --- a/lib/backends/ublk.c
> +++ b/lib/backends/ublk.c
> @@ -258,7 +258,16 @@ static unsigned int erofsublk_formalize_cmd_op(unsigned int op)
>   	DBG_BUGON(_IOC_DIR(op) != 0);
>   	DBG_BUGON(_IOC_SIZE(op) != 0);
>   
> -	if (op < ARRAY_SIZE(ctrl_cmd_op) && !erofs_ublk_use_legacy_cmds)
> +	if (erofs_ublk_use_legacy_cmds)
> +		return op;
> +
> +	/* IO opcodes live above the ctrl table and need explicit encoding */
> +	if (op == UBLK_IO_FETCH_REQ)
> +		return UBLK_U_IO_FETCH_REQ;
> +	if (op == UBLK_IO_COMMIT_AND_FETCH_REQ)
> +		return UBLK_U_IO_COMMIT_AND_FETCH_REQ;
> +
> +	if (op < ARRAY_SIZE(ctrl_cmd_op))
>   		return ctrl_cmd_op[op];
>   	return op;

	if (!erofs_ublk_use_legacy_cmds) {
		if (op == UBLK_IO_FETCH_REQ)
			return UBLK_U_IO_FETCH_REQ;
		if (op == UBLK_IO_COMMIT_AND_FETCH_REQ)
			return UBLK_U_IO_COMMIT_AND_FETCH_REQ;
		if (op < ARRAY_SIZE(ctrl_cmd_op))
			return ctrl_cmd_op[op];
	}
	return op;

?


>   }
> @@ -528,11 +537,6 @@ static inline unsigned int user_data_to_tag(u64 user_data)
>   	return user_data & 0xffff;
>   }

..

>   
> +static int ublk_dev_id_from_path(const char *path);

Can we avoid forward declaration?

> +
> +static int erofsmount_ublk_reattach(int dev_id)
> +{
> +	struct erofsmount_nbd_ctx ctx = { .vd = &ctx._vd };
> +	char *recp;
> +	FILE *f;
> +	int err;
> +
> +	if (!erofs_ublk_is_recoverable(dev_id))
> +		return -EINVAL;
> +
> +	if (asprintf(&recp, EROFSMOUNT_UBLK_REC_FMT, dev_id) <= 0)
> +		return -ENOMEM;
> +
> +	f = fopen(recp, "r");
> +	if (!f) {
> +		err = -errno;
> +		free(recp);
> +		return err;
> +	}
> +
> +	err = erofsmount_open_recovery_source(&ctx, f);
> +	if (err) {
> +		free(recp);
> +		return err;
> +	}
> +
> +	if (fork() == 0) {
> +		err = erofs_ublk_recover_dev(dev_id, erofsmount_ublk_handler,
> +					     ctx.vd);
> +		if (err) {
> +			erofs_err("ublk recover dev %d failed: %s",
> +				  dev_id, strerror(-err));
> +			erofs_io_close(ctx.vd);
> +			exit(EXIT_FAILURE);
> +		}
> +		err = erofs_ublk_start(dev_id, -1);
> +		erofs_ublk_destroy(dev_id);
> +		erofs_io_close(ctx.vd);
> +		(void)unlink(recp);
> +		exit(err ? EXIT_FAILURE : EXIT_SUCCESS);
> +	}
> +
> +	erofs_io_close(ctx.vd);
> +	free(recp);
> +	return 0;
> +}
> +
>   static int erofsmount_reattach(const char *target)
>   {
>   	struct erofsmount_nbd_ctx ctx = { .vd = &ctx._vd };
> @@ -1450,6 +1528,10 @@ static int erofsmount_reattach(const char *target)
>   	if (err < 0)
>   		return -errno;
>   
> +	nbdnum = ublk_dev_id_from_path(target);
> +	if (S_ISBLK(st.st_mode) && nbdnum >= 0)
> +		return erofsmount_ublk_reattach(nbdnum);
> +
>   	if (!S_ISBLK(st.st_mode) || major(st.st_rdev) != EROFS_NBD_MAJOR)
>   		return -ENOTBLK;

	if (!S_ISBLK(st.st_mode))
		return -ENOTBLK;

	nbdnum = ublk_dev_id_from_path(target);
	if (nbdnum >= 0)
		return erofsmount_ublk_reattach(nbdnum);

	if (major(st.st_rdev) != EROFS_NBD_MAJOR)
		return -ENOTBLK;

?


Thanks,
Gao Xiang
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.