]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mount: use new lib/loopdev.c code
authorKarel Zak <kzak@redhat.com>
Thu, 29 Sep 2011 23:28:02 +0000 (01:28 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 29 Sep 2011 23:28:02 +0000 (01:28 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
lib/loopdev.c
mount/Makefile.am
mount/mount.c

index ee7a242358530dd9e984f1c36e899945197b0e04..11555b0a84dfd9fa53e1c2ade300a5c62c71a7e1 100644 (file)
@@ -887,6 +887,7 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
        memset(&lc->info, 0, sizeof(lc->info));
        lc->has_info = 0;
 
+       DBG(lc, loopdev_debug("setup success [rc=0]"));
        return 0;
 err:
        if (file_fd >= 0)
@@ -894,7 +895,7 @@ err:
        if (dev_fd >= 0)
                ioctl(dev_fd, LOOP_CLR_FD, 0);
 
-       DBG(lc, loopdev_debug("setup done [rc=%d]", rc));
+       DBG(lc, loopdev_debug("setup failed [rc=%d]", rc));
        return rc;
 }
 
index e9237b75af667a81c285792cee8c28afd2646a3d..8f4a4870f10bf02b5e72ec1c1580ca626d84ead9 100644 (file)
@@ -8,11 +8,10 @@ dist_man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
 srcs_common = sundries.c $(top_srcdir)/lib/canonicalize.c sundries.h
 
 # generic header for mount and umount
-hdrs_mount = fstab.h mount_mntent.h mount_constants.h \
-       lomount.h getusername.h loop.h
+hdrs_mount = fstab.h mount_mntent.h mount_constants.h getusername.h
 
 # generic sources for mount and umount
-srcs_mount = fstab.c mount_mntent.c getusername.c lomount.c devname.c devname.h \
+srcs_mount = fstab.c mount_mntent.c getusername.c devname.c devname.h \
        $(srcs_common) $(hdrs_mount) $(top_srcdir)/lib/env.c \
        $(top_srcdir)/lib/linux_version.c $(top_srcdir)/lib/blkdev.c \
        $(top_srcdir)/lib/fsprobe.c $(top_srcdir)/lib/mangle.c
@@ -25,13 +24,20 @@ ldadd_static =
 cflags_common = $(AM_CFLAGS)
 ldflags_static = -all-static
 
-mount_SOURCES = mount.c $(srcs_mount) $(top_srcdir)/lib/setproctitle.c \
-               $(top_srcdir)/lib/strutils.c
+mount_SOURCES = mount.c \
+               $(srcs_mount) \
+               $(top_srcdir)/lib/setproctitle.c \
+               $(top_srcdir)/lib/strutils.c \
+               $(top_srcdir)/lib/at.c \
+               $(top_srcdir)/lib/sysfs.c \
+               $(top_srcdir)/lib/loopdev.c
+
 mount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
 mount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
 mount_LDADD = $(ldadd_common)
 
-umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strutils.c
+umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strutils.c \
+                lomount.c lomount.h loop.h
 umount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
 umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
 umount_LDADD = $(ldadd_common)
index d74da2c74ec01d59e3a02cfe7f48d0e9930a1e0c..4f6a1637a06b6819422b8f2a7b7b31772f6d4a2a 100644 (file)
@@ -34,8 +34,8 @@
 #include "sundries.h"
 #include "mount_mntent.h"
 #include "fstab.h"
-#include "lomount.h"
-#include "loop.h"
+#include "loopdev.h"
+#include "linux_version.h"
 #include "getusername.h"
 #include "env.h"
 #include "nls.h"
@@ -268,8 +268,8 @@ print_one (const struct my_mntent *me) {
         * mount(8) output if the device has been initialized by mount(8).
         */
        if (strncmp(me->mnt_fsname, "/dev/loop", 9) == 0 &&
-           is_loop_autoclear(me->mnt_fsname))
-               fsname = loopdev_get_loopfile(me->mnt_fsname);
+           loopdev_is_autoclear(me->mnt_fsname))
+               fsname = loopdev_get_backing_file(me->mnt_fsname);
 
        if (!fsname)
                fsname = (char *) me->mnt_fsname;
@@ -1160,8 +1160,8 @@ is_mounted_same_loopfile(const char *node0, const char *loopfile, unsigned long
                char *p;
 
                if (strncmp(mnt->m.mnt_fsname, "/dev/loop", 9) == 0)
-                       res = loopfile_used_with((char *) mnt->m.mnt_fsname,
-                                       loopfile, offset);
+                       res = loopdev_is_used((char *) mnt->m.mnt_fsname,
+                                       loopfile, offset, LOOPDEV_FL_OFFSET);
 
                else if (mnt->m.mnt_opts &&
                         (p = strstr(mnt->m.mnt_opts, "loop=")))
@@ -1169,7 +1169,8 @@ is_mounted_same_loopfile(const char *node0, const char *loopfile, unsigned long
                        char *dev = xstrdup(p+5);
                        if ((p = strchr(dev, ',')))
                                *p = '\0';
-                       res = loopfile_used_with(dev, loopfile, offset);
+                       res =  loopdev_is_used(dev,
+                                       loopfile, offset, LOOPDEV_FL_OFFSET);
                        free(dev);
                }
        }
@@ -1199,6 +1200,7 @@ loop_check(const char **spec, const char **type, int *flags,
           const char *node) {
   int looptype;
   uintmax_t offset = 0, sizelimit = 0;
+  struct loopdev_cxt lc;
 
   /*
    * In the case of a loop mount, either type is of the form lo@/dev/loop5
@@ -1249,7 +1251,6 @@ loop_check(const char **spec, const char **type, int *flags,
        printf(_("mount: skipping the setup of a loop device\n"));
     } else {
       int loop_opts = 0;
-      int res;
 
       /* since 2.6.37 we don't have to store backing filename to mtab
        * because kernel provides the name in /sys
@@ -1259,11 +1260,11 @@ loop_check(const char **spec, const char **type, int *flags,
 
        if (verbose)
          printf(_("mount: enabling autoclear loopdev flag\n"));
-       loop_opts = SETLOOP_AUTOCLEAR;
+       loop_opts = LO_FLAGS_AUTOCLEAR;
       }
 
       if (*flags & MS_RDONLY)
-        loop_opts |= SETLOOP_RDONLY;
+        loop_opts |= LO_FLAGS_READ_ONLY;
 
       if (opt_offset && parse_offset(&opt_offset, &offset)) {
         error(_("mount: invalid offset '%s' specified"), opt_offset);
@@ -1279,55 +1280,88 @@ loop_check(const char **spec, const char **type, int *flags,
         return EX_FAIL;
       }
 
+      loopcxt_init(&lc, 0);
+      /* loopcxt_enable_debug(&lc, 1); */
+
+      if (*loopdev && **loopdev)
+       loopcxt_set_device(&lc, *loopdev);      /* use loop=<devname> */
+
       do {
-        if (!*loopdev || !**loopdev)
-         *loopdev = find_unused_loop_device();
-       if (!*loopdev)
-         return EX_SYSERR;     /* no more loop devices */
+       int rc;
+
+        if ((!*loopdev || !**loopdev) && loopcxt_find_unused(&lc) == 0)
+           *loopdev = loopcxt_strdup_device(&lc);
+
+       if (!*loopdev) {
+         error(_("mount: failed to found free loop device"));
+         goto err;     /* no more loop devices */
+       }
        if (verbose)
          printf(_("mount: going to use the loop device %s\n"), *loopdev);
 
-       if ((res = set_loop(*loopdev, *loopfile, offset, sizelimit,
-                           opt_encryption, pfd, &loop_opts))) {
-         if (res == 2) {
-            /* loop dev has been grabbed by some other process,
-               try again, if not given explicitly */
-            if (!opt_loopdev) {
-              if (verbose)
-                printf(_("mount: stolen loop=%s ...trying again\n"), *loopdev);
-              my_free(*loopdev);
-              *loopdev = NULL;
-              continue;
-            }
-            error(_("mount: stolen loop=%s"), *loopdev);
-            return EX_FAIL;
+       rc = loopcxt_set_backing_file(&lc, *loopfile);
 
-         } else {
-            if (verbose)
-              printf(_("mount: failed setting up loop device\n"));
-            if (!opt_loopdev) {
-              my_free(*loopdev);
-              *loopdev = NULL;
-            }
-            return EX_FAIL;
+       if (!rc && offset)
+         rc = loopcxt_set_offset(&lc, offset);
+       if (!rc && sizelimit)
+         rc = loopcxt_set_sizelimit(&lc, sizelimit);
+       if (!rc)
+         loopcxt_set_flags(&lc, loop_opts);
+       if (rc) {
+          error(_("mount: %s: failed to set loopdev attributes"), *loopdev);
+          goto err;
+       }
+
+       /* setup the device */
+       rc = loopcxt_setup_device(&lc);
+       if (!rc)
+         break;        /* success */
+
+       if (rc != -EBUSY) {
+         if (verbose)
+           printf(_("mount: failed setting up loop device\n"));
+         if (!opt_loopdev) {
+           my_free(*loopdev);
+           *loopdev = NULL;
          }
+         goto err;
+       }
+
+       if (!opt_loopdev) {
+         if (verbose)
+           printf(_("mount: stolen loop=%s ...trying again\n"), *loopdev);
+           my_free(*loopdev);
+           *loopdev = NULL;
+           continue;
        }
+       error(_("mount: stolen loop=%s"), *loopdev);
+       goto err;
+
       } while (!*loopdev);
 
       if (verbose > 1)
        printf(_("mount: setup loop device successfully\n"));
       *spec = *loopdev;
 
-      if (loop_opts & SETLOOP_RDONLY)
+      if (loopcxt_is_readonly(&lc))
         *flags |= MS_RDONLY;
 
-      if (loop_opts & SETLOOP_AUTOCLEAR)
+      if (loopcxt_is_autoclear(&lc))
         /* Prevent recording loop dev in mtab for cleanup on umount */
         *loop = 0;
     }
   }
 
+  /* We have to keep the device open until mount(2), otherwise it will
+   * be auto-cleared by kernel (because LO_FLAGS_AUTOCLEAR) */
+  loopcxt_set_fd(&lc, -1, 0);
+
+  loopcxt_deinit(&lc);
   return 0;
+
+err:
+  loopcxt_deinit(&lc);
+  return EX_FAIL;
 }
 
 
@@ -1693,7 +1727,7 @@ try_mount_one (const char *spec0, const char *node0, const char *types0,
   mnt_err = errno;
 
   if (loop)
-       del_loop(spec);
+       loopdev_delete(spec);
 
   block_signals (SIG_UNBLOCK);