On 2022/11/19 2:22, Kang-Che Sung wrote:
On Friday, November 18, 2022, Xiaoming Ni <[email protected]
<mailto:[email protected]>> wrote:
> LOOP_CONFIGURE is added to Linux 5.8
>
> This allows userspace to completely setup a loop device with a single
> ioctl, removing the in-between state where the device can be partially
> configured - eg the loop device has a backing file associated with it,
> but is reading from the wrong offset.
>
> https://lwn.net/Articles/820408/ <https://lwn.net/Articles/820408/>
>
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5>
>
> kernel version >= 5.8, choice CONFIG_LOOP_CONFIGURE
> function old
new delta
> set_loop 716
832 +116
>
------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 1/0 up/down: 116/0)
Total: 116 bytes
> kernel version < 5.8, choice CONFIG_NO_LOOP_CONFIGURE
> function old
new delta
> set_loop 760
716 -44
>
------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-44)
Total: -44 bytes
> kernel version is unknown, choice CONFIG_TRY_LOOP_CONFIGURE
> function old
new delta
>
------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0)
Total: 0 bytes
>
> Signed-off-by: Xiaoming Ni <[email protected]
<mailto:[email protected]>>
> ---
> libbb/Config.src | 22 ++++++++++++++++++++++
> libbb/loop.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/libbb/Config.src b/libbb/Config.src
> index 66a3ffa23..b7f9ddab4 100644
> --- a/libbb/Config.src
> +++ b/libbb/Config.src
> @@ -369,3 +369,25 @@ config UNICODE_PRESERVE_BROKEN
> For example, this means that entering 'l', 's', ' ', 0xff,
[Enter]
> at shell prompt will list file named 0xff (single char name
> with char value 255), not file named '?'.
> +
> +choice
> + prompt "LOOP_CONFIGURE or LOOP_SET_FD + LOOP_SET_STATUS"
> + default TRY_LOOP_CONFIGURE
> + help
> + LOOP_CONFIGURE is added to Linux 5.8
> + https://lwn.net/Articles/820408/ <https://lwn.net/Articles/820408/>
> + This allows userspace to completely setup a loop device with
a single
> + ioctl, removing the in-between state where the device can be
partially
> + configured - eg the loop device has a backing file associated
with it,
> + but is reading from the wrong offset.
> +
> +config LOOP_CONFIGURE
> + bool "always uses LOOP_CONFIGURE, kernel version >= 5.8"
> +
> +config NO_LOOP_CONFIGURE
> + bool "never uses LOOP_CONFIGURE, kernel version < 5.8"
> +
> +config TRY_LOOP_CONFIGURE
> + bool "try LOOP_CONFIGURE, kernel version is unknown"
> +
> +endchoice
> diff --git a/libbb/loop.c b/libbb/loop.c
> index ddb92fce3..be592bc4b 100644
> --- a/libbb/loop.c
> +++ b/libbb/loop.c
> @@ -126,7 +126,8 @@ static int open_file(const char *file, unsigned
flags, int *mode)
> return ffd;
> }
>
> -static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
> +#ifndef CONFIG_LOOP_CONFIGURE
> +static int set_loop_configure_old(int ffd, int lfd, bb_loop_info
*loopinfo)
> {
> int rc;
> bb_loop_info loopinfo2;
> @@ -149,6 +150,46 @@ static int set_loop_configure(int ffd, int lfd,
bb_loop_info *loopinfo)
> ioctl(lfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
> return -1;
> }
> +#endif
> +
> +#ifndef CONFIG_NO_LOOP_CONFIGURE
> +
> +#ifndef LOOP_CONFIGURE
> +#define LOOP_CONFIGURE 0x4C0A
> +struct loop_config {
> + uint32_t fd;
> + uint32_t block_size;
> + struct loop_info64 info;
> + uint64_t __reserved[8];
> +};
> +#endif
> +
> +/*
> + * linux v5.8.0
> + * loop: Add LOOP_CONFIGURE ioctl
> + * https://lwn.net/Articles/820408/ <https://lwn.net/Articles/820408/>
> + *
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5>
> + */
> +static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
> +{
> + int rc;
> + struct loop_config config;
> +
> + memset(&config, 0, sizeof(config));
> + config.fd = ffd;
> + memcpy(&config.info <http://config.info>, loopinfo,
sizeof(config.info <http://config.info>));
> +
> + rc = ioctl(lfd, LOOP_CONFIGURE, &config);
> + if (rc == 0) {
> + return lfd;
> + }
> +#ifdef CONFIG_TRY_LOOP_CONFIGURE
> + if (rc == -1 && errno == EINVAL) /* The system may not
support LOOP_CONFIGURE. */
> + return set_loop_configure_old(ffd, lfd, loopinfo);
> +#endif
How about putting the new code into a function named
try_loop_configure_ioctl(), and let the original set_loop_configure()
call it?
This way you won't rename the function to set_loop_configure_old, the
name I personally think is ugly.
new name: set_loop_fd_and_status
#ifdef CONFIG_TRY_LOOP_CONFIGURE
if (rc == -1 && errno == EINVAL) /* The system may not support
LOOP_CONFIGURE. */
return set_loop_fd_and_status(ffd, lfd, loopinfo);
#endif
return -1;
}
#endif
static int set_loop_info(int ffd, int lfd, bb_loop_info *loopinfo)
{
int rc;
bb_loop_info tmp;
rc = ioctl(lfd, BB_LOOP_GET_STATUS, &tmp);
/* If device is free, try to claim it */
if (rc && errno == ENXIO) {
#ifdef CONFIG_NO_LOOP_CONFIGURE
return set_loop_fd_and_status(ffd, lfd, loopinfo);
#else
return set_loop_configure(ffd, lfd, loopinfo);
#endif
}
Thanks
Xiaoming Ni
> + return -1;
> +}
> +#endif
>
> static int set_loop_info(int ffd, int lfd, bb_loop_info *loopinfo)
> {
> @@ -159,7 +200,11 @@ static int set_loop_info(int ffd, int lfd,
bb_loop_info *loopinfo)
>
> /* If device is free, try to claim it */
> if (rc && errno == ENXIO) {
> +#ifdef CONFIG_NO_LOOP_CONFIGURE
> + return set_loop_configure_old(ffd, lfd, loopinfo);
> +#else
> return set_loop_configure(ffd, lfd, loopinfo);
> +#endif
> }
> return -1;
> }
> --
> 2.27.0
>
>
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox