summaryrefslogtreecommitdiffstats
path: root/mount
diff options
context:
space:
mode:
authorKarel Zak2011-09-30 01:28:02 +0200
committerKarel Zak2011-09-30 01:28:02 +0200
commit8fbbe528a7912dea26fd5e1669e960f49e18acfe (patch)
tree4723e3b51cecb97b7950594f3922226f5095750a /mount
parentinclude,xalloc: fix whitespace to be consistent (diff)
downloadkernel-qcow2-util-linux-8fbbe528a7912dea26fd5e1669e960f49e18acfe.tar.gz
kernel-qcow2-util-linux-8fbbe528a7912dea26fd5e1669e960f49e18acfe.tar.xz
kernel-qcow2-util-linux-8fbbe528a7912dea26fd5e1669e960f49e18acfe.zip
mount: use new lib/loopdev.c code
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount')
-rw-r--r--mount/Makefile.am18
-rw-r--r--mount/mount.c112
2 files changed, 85 insertions, 45 deletions
diff --git a/mount/Makefile.am b/mount/Makefile.am
index e9237b75a..8f4a4870f 100644
--- a/mount/Makefile.am
+++ b/mount/Makefile.am
@@ -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)
diff --git a/mount/mount.c b/mount/mount.c
index d74da2c74..4f6a1637a 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -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);