NSH no long calls losetup() and loteardown() directly. Now it uses /dev/loop and performs these operations using ioctl() calls

This commit is contained in:
Gregory Nutt 2015-11-25 17:55:16 -06:00
parent 882ae41aee
commit a62bf6727f
4 changed files with 53 additions and 25 deletions

View File

@ -1461,3 +1461,7 @@
leading or trailing whitespace (2015-11-23).
* apps/nshlib: The mount commands now accepts mount options (currently
needed only for the hostfs file system). From Ken Petit (2015-11-25).
* apps/nshlib: NSH no longer calls losetup() and loteardown directly.
Now it opens /dev/loop and accomplishes these things using ioctl()
calls (2015-11-25).

View File

@ -594,7 +594,7 @@
* entries the provide the necessary interfaces.
* - Other interfaces are more standard and for these there probably should
* be new system calls to support the OS interface. Such interfaces
* include things like losetup, loteardown, and mkrd.
* include things like ps, mkfatfs, and mkrd.
* - Other interfaces simply need to be moved out of the OS and into the C
* library where they will become accessible to application code. Such
* interfaces include mkfatfs.
@ -605,8 +605,6 @@
# define CONFIG_NSH_DISABLE_PS 1
# undef CONFIG_NSH_DISABLE_DF /* 'df' depends on foreach_mountpoint */
# define CONFIG_NSH_DISABLE_DF 1
# undef CONFIG_NSH_DISABLE_LOSETUP /* 'losetup' depends on losetup/loteardown */
# define CONFIG_NSH_DISABLE_LOSETUP 1
# undef CONFIG_NSH_DISABLE_MKFATFS /* 'mkfatfs' depends on mkfatfs interface */
# define CONFIG_NSH_DISABLE_MKFATFS 1
# undef CONFIG_NSH_DISABLE_MKRD /* 'mkrd' depends on ramdisk_register */
@ -908,7 +906,7 @@ void nsh_usbtrace(void);
# endif /* CONFIG_NFILE_STREAMS && NSH_HAVE_DIROPTS */
# ifndef CONFIG_DISABLE_MOUNTPOINT
# ifndef CONFIG_NSH_DISABLE_LOSETUP
# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP)
int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_NSH_DISABLE_MKFIFO

View File

@ -243,7 +243,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)
# ifndef CONFIG_NSH_DISABLE_LOSETUP
# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP)
{ "losetup", cmd_losetup, 3, 6, "[-d <dev-path>] | [[-o <offset>] [-r] <dev-path> <file-path>]" },
# endif
#endif

View File

@ -51,6 +51,10 @@
# include <sys/mount.h>
# include <nuttx/fs/ramdisk.h>
# endif
# ifdef CONFIG_DEV_LOOP
# include <sys/ioctl.h>
# include <nuttx/fs/loop.h>
# endif
# ifdef CONFIG_FS_FAT
# include <nuttx/fs/mkfatfs.h>
# endif
@ -838,17 +842,19 @@ errout:
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)
#ifndef CONFIG_NSH_DISABLE_LOSETUP
# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP)
int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *loopdev = NULL;
char *filepath = NULL;
bool teardown = false;
bool readonly = false;
off_t offset = 0;
bool badarg = false;
int ret = ERROR;
int option;
FAR char *loopdev = NULL;
FAR char *filepath = NULL;
struct losetup_s setup;
bool teardown = false;
bool readonly = false;
off_t offset = 0;
bool badarg = false;
int ret = ERROR;
int option;
int fd;
/* Get the losetup options: Two forms are supported:
*
@ -917,10 +923,19 @@ int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* There should be nothing else on the command line */
if (optind < argc)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
goto errout_with_paths;
}
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
goto errout_with_paths;
}
/* Open the loop device */
fd = open("/dev/loop", O_RDONLY);
if (fd < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
goto errout_with_paths;
}
/* Perform the teardown operation */
@ -928,26 +943,37 @@ int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
/* Tear down the loop device. */
ret = loteardown(loopdev);
ret = ioctl(fd, LOOPIOC_TEARDOWN, (unsigned long)((uintptr_t)loopdev));
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "loteardown", NSH_ERRNO_OF(-ret));
goto errout_with_paths;
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO);
goto errout_with_fd;
}
}
else
{
/* Set up the loop device */
ret = losetup(loopdev, filepath, 512, offset, readonly);
setup.devname = loopdev; /* The loop block device to be created */
setup.filename = filepath; /* The file or character device to use */
setup.sectsize = 512; /* The sector size to use with the block device */
setup.offset = offset; /* An offset that may be applied to the device */
setup.readonly = readonly; /* True: Read access will be supported only */
ret = ioctl(fd, LOOPIOC_SETUP, (unsigned long)((uintptr_t)&setup));
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "losetup", NSH_ERRNO_OF(-ret));
goto errout_with_paths;
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO);
goto errout_with_fd;
}
}
/* Free memory */
ret = OK;
/* Free resources */
errout_with_fd:
(void)close(fd);
errout_with_paths:
if (loopdev)