aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-08-17 19:07:20 +0000
committerRob Landley <rob@landley.net>2006-08-17 19:07:20 +0000
commit4470b74e29f98ffdd39acf8085e5b7cd0758edaa (patch)
treebf8214dbd36de26f10c48bd2f2811aab6eebc643
parenteb28ce46448e280742465d027e86701766c34d97 (diff)
downloadbusybox-w32-4470b74e29f98ffdd39acf8085e5b7cd0758edaa.tar.gz
busybox-w32-4470b74e29f98ffdd39acf8085e5b7cd0758edaa.tar.bz2
busybox-w32-4470b74e29f98ffdd39acf8085e5b7cd0758edaa.zip
The kernel can't handle umount /dev/hdc, we have to do it through mtab,
except that we still have to work when there is no mtab. Oh, and while we're at it, take advantage of the fact that modern processors avoid branches via conditional assignment where possible. ("x = a ? b : c;" turns into "x = c; if (a) x = b;" because that way there's no branch to potentially mispredict and thus never a bubble in the pipeline. The if(a) turns into an assembly test followed by a conditional assignment (rather than a conditional jump).) So since the compiler is going to do that _anyway_, we might as well take advantage of it to produce a slightly smaller binary. So there.
-rw-r--r--util-linux/umount.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 24c1d03a9..fabc3d049 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -78,6 +78,7 @@ int umount_main(int argc, char **argv)
78 // Loop through everything we're supposed to umount, and do so. 78 // Loop through everything we're supposed to umount, and do so.
79 for (;;) { 79 for (;;) {
80 int curstat; 80 int curstat;
81 char *zapit = *argv;
81 82
82 // Do we already know what to umount this time through the loop? 83 // Do we already know what to umount this time through the loop?
83 if (m) safe_strncpy(path, m->dir, PATH_MAX); 84 if (m) safe_strncpy(path, m->dir, PATH_MAX);
@@ -86,32 +87,37 @@ int umount_main(int argc, char **argv)
86 // Get next command line argument (and look it up in mtab list) 87 // Get next command line argument (and look it up in mtab list)
87 else if (!argc--) break; 88 else if (!argc--) break;
88 else { 89 else {
89 realpath(*argv++, path); 90 argv++;
91 realpath(zapit, path);
90 for (m = mtl; m; m = m->next) 92 for (m = mtl; m; m = m->next)
91 if (!strcmp(path, m->dir) || !strcmp(path, m->device)) 93 if (!strcmp(path, m->dir) || !strcmp(path, m->device))
92 break; 94 break;
93 } 95 }
96 // If we couldn't find this sucker in /etc/mtab, punt by passing our
97 // command line argument straight to the umount syscall. Otherwise,
98 // umount the directory even if we were given the block device.
99 if (m) zapit = m->dir;
94 100
95 // Let's ask the thing nicely to unmount. 101 // Let's ask the thing nicely to unmount.
96 curstat = umount(path); 102 curstat = umount(zapit);
97 103
98 // Force the unmount, if necessary. 104 // Force the unmount, if necessary.
99 if (curstat && doForce) { 105 if (curstat && doForce) {
100 curstat = umount2(path, doForce); 106 curstat = umount2(zapit, doForce);
101 if (curstat) 107 if (curstat)
102 bb_error_msg_and_die("forced umount of %s failed!", path); 108 bb_error_msg_and_die("forced umount of %s failed!", zapit);
103 } 109 }
104 110
105 // If still can't umount, maybe remount read-only? 111 // If still can't umount, maybe remount read-only?
106 if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) { 112 if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
107 curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL); 113 curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL);
108 bb_error_msg(curstat ? "Cannot remount %s read-only" : 114 bb_error_msg(curstat ? "Cannot remount %s read-only" :
109 "%s busy - remounted read-only", m->device); 115 "%s busy - remounted read-only", m->device);
110 } 116 }
111 117
112 if (curstat) { 118 if (curstat) {
113 status = EXIT_FAILURE; 119 status = EXIT_FAILURE;
114 bb_perror_msg("Couldn't umount %s", path); 120 bb_perror_msg("Couldn't umount %s", zapit);
115 } else { 121 } else {
116 /* De-allocate the loop device. This ioctl should be ignored on 122 /* De-allocate the loop device. This ioctl should be ignored on
117 * any non-loop block devices. */ 123 * any non-loop block devices. */
@@ -121,9 +127,9 @@ int umount_main(int argc, char **argv)
121 erase_mtab(m->dir); 127 erase_mtab(m->dir);
122 } 128 }
123 129
124
125
126 // Find next matching mtab entry for -a or umount /dev 130 // Find next matching mtab entry for -a or umount /dev
131 // Note this means that "umount /dev/blah" will unmount all instances
132 // of /dev/blah, not just the most recent.
127 while (m && (m = m->next)) 133 while (m && (m = m->next))
128 if ((opt & OPT_ALL) || !strcmp(path,m->device)) 134 if ((opt & OPT_ALL) || !strcmp(path,m->device))
129 break; 135 break;