summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mount/lomount.c27
-rw-r--r--mount/lomount.h7
-rw-r--r--mount/mount.c30
3 files changed, 61 insertions, 3 deletions
diff --git a/mount/lomount.c b/mount/lomount.c
index 90149536a..4d99d9f6f 100644
--- a/mount/lomount.c
+++ b/mount/lomount.c
@@ -109,6 +109,33 @@ static char *loopfile_from_sysfs(const char *device)
return res;
}
+char *loopdev_get_loopfile(const char *device)
+{
+ char *res = loopfile_from_sysfs(device);
+
+ if (!res) {
+ struct loop_info lo;
+ struct loop_info64 lo64;
+ int fd;
+
+ if ((fd = open(device, O_RDONLY)) < 0)
+ return NULL;
+
+ if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0) {
+ lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
+ lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
+ res = xstrdup((char *) lo64.lo_file_name);
+
+ } else if (ioctl(fd, LOOP_GET_STATUS, &lo) == 0) {
+ lo.lo_name[LO_NAME_SIZE-2] = '*';
+ lo.lo_name[LO_NAME_SIZE-1] = 0;
+ res = xstrdup((char *) lo.lo_name);
+ }
+ close(fd);
+ }
+ return res;
+}
+
int
is_loop_device (const char *device) {
struct stat st;
diff --git a/mount/lomount.h b/mount/lomount.h
index 59108d408..de8b76bf4 100644
--- a/mount/lomount.h
+++ b/mount/lomount.h
@@ -1,3 +1,6 @@
+#ifndef UTIL_LINUX_LOMOUNT_H
+#define UTIL_LINUX_LOMOUNT_H
+
extern int set_loop(const char *, const char *, unsigned long long, unsigned long long,
const char *, int, int *);
extern int del_loop(const char *);
@@ -7,6 +10,10 @@ extern char * find_unused_loop_device(void);
extern int loopfile_used_with(char *devname, const char *filename, unsigned long long offset);
extern char *loopfile_used (const char *filename, unsigned long long offset);
+extern char *loopdev_get_loopfile(const char *device);
+
#define SETLOOP_RDONLY (1<<0) /* Open loop read-only */
#define SETLOOP_AUTOCLEAR (1<<1) /* Automatically detach loop on close (2.6.25?) */
+
+#endif /* !UTIL_LINUX_LOMOUNT_H */
diff --git a/mount/mount.c b/mount/mount.c
index 9faa6a5b6..8c30263cb 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -249,9 +249,23 @@ parse_string_opt(char *s) {
/* Report on a single mount. */
static void
print_one (const struct my_mntent *me) {
+
+ char *fsname = NULL;
+
if (mount_quiet)
return;
- printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
+
+ /* users assume backing file name rather than /dev/loopN in
+ * 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);
+
+ if (!fsname)
+ fsname = (char *) me->mnt_fsname;
+
+ printf ("%s on %s", fsname, me->mnt_dir);
if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
printf (" type %s", me->mnt_type);
if (me->mnt_opts != NULL)
@@ -1206,10 +1220,20 @@ loop_check(const char **spec, const char **type, int *flags,
if (verbose)
printf(_("mount: skipping the setup of a loop device\n"));
} else {
- /* use autoclear loopdev on system without regular mtab only */
- int loop_opts = mtab_is_writable() ? 0 : SETLOOP_AUTOCLEAR;
+ int loop_opts;
int res;
+ /* since 2.6.37 we don't have to store backing filename to mtab
+ * because kernel provides the name in /sys
+ */
+ if (get_linux_version() >= KERNEL_VERSION(2, 6, 37) ||
+ mtab_is_writable() == 0) {
+
+ if (verbose)
+ printf(_("mount: enabling autoclear loopdev flag\n"));
+ loop_opts = SETLOOP_AUTOCLEAR;
+ }
+
if (*flags & MS_RDONLY)
loop_opts |= SETLOOP_RDONLY;