aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/mount.c')
-rw-r--r--util-linux/mount.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c
index f0245f714..6bb18524d 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1887,6 +1887,7 @@ static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
1887// NB: mp->xxx fields may be trashed on exit 1887// NB: mp->xxx fields may be trashed on exit
1888static int singlemount(struct mntent *mp, int ignore_busy) 1888static int singlemount(struct mntent *mp, int ignore_busy)
1889{ 1889{
1890 int loopfd = -1;
1890 int rc = -1; 1891 int rc = -1;
1891 unsigned long vfsflags; 1892 unsigned long vfsflags;
1892 char *loopFile = NULL, *filteropts = NULL; 1893 char *loopFile = NULL, *filteropts = NULL;
@@ -2026,7 +2027,20 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2026 if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { 2027 if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) {
2027 loopFile = bb_simplify_path(mp->mnt_fsname); 2028 loopFile = bb_simplify_path(mp->mnt_fsname);
2028 mp->mnt_fsname = NULL; // will receive malloced loop dev name 2029 mp->mnt_fsname = NULL; // will receive malloced loop dev name
2029 if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) { 2030
2031 // mount always creates AUTOCLEARed loopdevs, so that umounting
2032 // drops them without any code in the userspace.
2033 // This happens since circa linux-2.6.25:
2034 // commit 96c5865559cee0f9cbc5173f3c949f6ce3525581
2035 // Date: Wed Feb 6 01:36:27 2008 -0800
2036 // Subject: Allow auto-destruction of loop devices
2037 loopfd = set_loop(&mp->mnt_fsname,
2038 loopFile,
2039 0,
2040 ((vfsflags & MS_RDONLY) ? BB_LO_FLAGS_READ_ONLY : 0)
2041 | BB_LO_FLAGS_AUTOCLEAR
2042 );
2043 if (loopfd < 0) {
2030 if (errno == EPERM || errno == EACCES) 2044 if (errno == EPERM || errno == EACCES)
2031 bb_error_msg(bb_msg_perm_denied_are_you_root); 2045 bb_error_msg(bb_msg_perm_denied_are_you_root);
2032 else 2046 else
@@ -2074,6 +2088,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2074 } 2088 }
2075 2089
2076 // If mount failed, clean up loop file (if any). 2090 // If mount failed, clean up loop file (if any).
2091 // (Newer kernels which support LO_FLAGS_AUTOCLEAR should not need this,
2092 // merely "close(loopfd)" should do it?)
2077 if (ENABLE_FEATURE_MOUNT_LOOP && rc && loopFile) { 2093 if (ENABLE_FEATURE_MOUNT_LOOP && rc && loopFile) {
2078 del_loop(mp->mnt_fsname); 2094 del_loop(mp->mnt_fsname);
2079 if (ENABLE_FEATURE_CLEAN_UP) { 2095 if (ENABLE_FEATURE_CLEAN_UP) {
@@ -2086,6 +2102,9 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2086 if (ENABLE_FEATURE_CLEAN_UP) 2102 if (ENABLE_FEATURE_CLEAN_UP)
2087 free(filteropts); 2103 free(filteropts);
2088 2104
2105 if (loopfd >= 0)
2106 close(loopfd);
2107
2089 if (errno == EBUSY && ignore_busy) 2108 if (errno == EBUSY && ignore_busy)
2090 return 0; 2109 return 0;
2091 if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL)) 2110 if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL))