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

Reply via email to