diff options
author | Karel Zak | 2006-12-07 00:25:54 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:54 +0100 |
commit | 1d4ad1decc539c9729b592e6050460d6487c95f4 (patch) | |
tree | c158c5f5baf15ea4bab5c05b2f6e2bdaca332c29 /mount | |
parent | Imported from util-linux-2.11o tarball. (diff) | |
download | kernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.tar.gz kernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.tar.xz kernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.zip |
Imported from util-linux-2.11q tarball.
Diffstat (limited to 'mount')
-rw-r--r-- | mount/linux_fs.h | 4 | ||||
-rw-r--r-- | mount/mount.8 | 1 | ||||
-rw-r--r-- | mount/mount.c | 25 | ||||
-rw-r--r-- | mount/mount_by_label.c | 69 | ||||
-rw-r--r-- | mount/mount_by_label.h | 1 | ||||
-rw-r--r-- | mount/nfsmount.c | 12 | ||||
-rw-r--r-- | mount/umount.c | 10 |
7 files changed, 107 insertions, 15 deletions
diff --git a/mount/linux_fs.h b/mount/linux_fs.h index c6ef8105e..3885d724b 100644 --- a/mount/linux_fs.h +++ b/mount/linux_fs.h @@ -193,7 +193,9 @@ struct vxfs_super_block { #define VXFS_SUPER_MAGIC 0xa501FCF5 struct jfs_super_block { - char s_magic[4]; + char s_magic[4]; + u_char s_dummy1[97]; + char s_fpack[11]; }; #define JFS_SUPER1_OFF 0x8000 #define JFS_MAGIC "JFS1" diff --git a/mount/mount.8 b/mount/mount.8 index 01a722b7a..7f2f4d932 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -1375,6 +1375,7 @@ Possible values are: .TP .B old Old format of ufs, this is the default, read only. +(Don't forget to give the \-r option.) .TP .B 44bsd For filesystems created by a BSD-like system (NetBSD,FreeBSD,OpenBSD). diff --git a/mount/mount.c b/mount/mount.c index dc10e64bb..125cf1abf 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -1092,11 +1092,22 @@ mount_one (const char *spec, const char *node, char *types, const char *opts, opts = xstrconcat3(opts, ",", cmdlineopts); if (!strncmp(spec, "UUID=", 5)) { - nspec = get_spec_by_uuid(spec+5); specset = 1; + nspec = get_spec_by_uuid(spec+5); } else if (!strncmp(spec, "LABEL=", 6)) { - nspec = get_spec_by_volume_label(spec+6); + const char *nspec2; specset = 2; + nspec = get_spec_by_volume_label(spec+6); + nspec2 = second_occurrence_of_vol_label(spec+6); + if (nspec2) { + if (verbose) + printf(_("mount: the label %s occurs on " + "both %s and %s\n"), + spec+6, nspec, nspec2); + die (EX_FAIL, + _("mount: %s duplicate - not mounted"), + spec, _PATH_FSTAB); + } } else nspec = 0; /* just for gcc */ @@ -1496,8 +1507,16 @@ main (int argc, char *argv[]) { if (specseen) { if (uuid) spec = get_spec_by_uuid(uuid); - else + else { + const char *spec2; spec = get_spec_by_volume_label(volumelabel); + spec2 = second_occurrence_of_vol_label(volumelabel); + if (spec2) + die (EX_FAIL, + _("mount: the label %s occurs on " + "both %s and %s - not mounted\n"), + volumelabel, spec, spec2); + } if (!spec) die (EX_USAGE, _("mount: no such partition found")); if (verbose) diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c index 988974f77..ee3b1d52e 100644 --- a/mount/mount_by_label.c +++ b/mount/mount_by_label.c @@ -11,6 +11,8 @@ * - Added XFS support * 2001-11-22 Kirby Bohling <kbohling@birddog.com> * - Added support of labels on LVM + * 2002-03-21 Christoph Hellwig <hch@infradead.org> + * - Added JFS support */ #include <stdio.h> @@ -48,6 +50,7 @@ get_label_uuid(const char *device, char **label, char *uuid) { size_t namesize; struct ext2_super_block e2sb; struct xfs_super_block xfsb; + struct jfs_super_block jfssb; fd = open(device, O_RDONLY); if (fd < 0) @@ -71,6 +74,16 @@ get_label_uuid(const char *device, char **label, char *uuid) { memcpy(*label, xfsb.s_fname, namesize); rv = 0; } + else if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) == JFS_SUPER1_OFF + && read(fd, (char *) &jfssb, sizeof(jfssb)) == sizeof(jfssb) + && (strncmp(jfssb.s_magic, JFS_MAGIC, 4) == 0)) { + /* what to do with non-existant UUID? --hch */ + memset(uuid, 0, 16); + namesize = sizeof(jfssb.s_fpack); + if ((*label = calloc(namesize + 1, 1)) != NULL) + memcpy(*label, jfssb.s_fpack, namesize); + rv = 0; + } close(fd); return rv; @@ -83,7 +96,7 @@ uuidcache_addentry(char *device, char *label, char *uuid) { if (!uuidCache) { last = uuidCache = malloc(sizeof(*uuidCache)); } else { - for (last = uuidCache; last->next; last = last->next) ; + for (last = uuidCache; last->next; last = last->next); last->next = malloc(sizeof(*uuidCache)); last = last->next; } @@ -142,6 +155,9 @@ uuidcache_init(void) { char device[110]; int firstPass; int handleOnFirst; +#if 0 + char *iobuf = 0; +#endif if (uuidCache) return; @@ -155,6 +171,24 @@ uuidcache_init(void) { PROC_PARTITIONS); return; } +#if 0 +/* Ugly kludge - the contents of /proc/partitions change in time, + and this causes failures when the file is not read in one go. + In particular, one cannot use stdio on /proc/partitions. + Doing this ourselves is not easy either, since stat returns 0 + so the size is unknown. We might try increasing buffer sizes + until a single read gets all. For now only pick a largish buffer size. */ +/* All these troubles are mainly caused by people who patch the kernel + to keep statistics in /proc/partitions. Of course, statistics belong + in some /proc/diskstats, not in some /proc file that happened to + exist already. */ + { +#define CBBUF (16 * 1024) + iobuf = (char *) malloc(CBBUF); + if (iobuf) + setvbuf(procpt, iobuf, _IOFBF, CBBUF); + } +#endif for (firstPass = 1; firstPass >= 0; firstPass--) { fseek(procpt, 0, SEEK_SET); @@ -176,6 +210,7 @@ uuidcache_init(void) { /* skip entire disk (minor 0, 64, ... on ide; 0, 16, ... on sd) */ /* heuristic: partition name ends in a digit */ + /* devfs has .../disc and .../part1 etc. */ for(s = ptname; *s; s++); if (isdigit(s[-1])) { @@ -196,7 +231,10 @@ uuidcache_init(void) { } fclose(procpt); - +#if 0 + if (iobuf) + free(iobuf); +#endif uuidcache_init_lvm(); } @@ -273,7 +311,32 @@ get_volume_label_by_spec(const char *spec) { while(uc) { if (!strcmp(spec, uc->device)) return uc->label; - uc = uc->next; + uc = uc->next; } return NULL; } + +/* + * second_occurrence_of_vol_label() + * As labels are user defined they are not necessarily + * system-wide unique. Make sure that they are. + */ +const char * +second_occurrence_of_vol_label (const char *label) { + struct uuidCache_s *last; + int occurrences = 0; + + uuidcache_init(); + + for (last = uuidCache; last->next; last = last->next) { + if (!strcmp(last->label, label)) { + occurrences++; + if (occurrences == 2) + return last->device; + } + } + + return NULL; +} + + diff --git a/mount/mount_by_label.h b/mount/mount_by_label.h index 64bbbfa7d..451d06854 100644 --- a/mount/mount_by_label.h +++ b/mount/mount_by_label.h @@ -1,3 +1,4 @@ char *get_spec_by_uuid(const char *uuid); char *get_spec_by_volume_label(const char *volumelabel); const char *get_volume_label_by_spec(const char *spec); +const char *second_occurrence_of_vol_label(const char *label); diff --git a/mount/nfsmount.c b/mount/nfsmount.c index c0e27f0d4..a7f5770c9 100644 --- a/mount/nfsmount.c +++ b/mount/nfsmount.c @@ -32,6 +32,8 @@ * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp */ +#include "../defines.h" /* for HAVE_rpcsvc_nfs_prot_h and HAVE_inet_aton */ + #include <unistd.h> #include <stdio.h> #include <string.h> @@ -51,14 +53,18 @@ #include "sundries.h" #include "nfsmount.h" +#ifdef HAVE_rpcsvc_nfs_prot_h +#include <rpcsvc/nfs_prot.h> +#else #include <linux/nfs.h> +#define nfsstat nfs_stat +#endif + #include "mount_constants.h" #include "nfs_mount4.h" #include "nls.h" -#include "../defines.h" /* for HAVE_inet_aton */ - #ifndef NFS_PORT #define NFS_PORT 2049 #endif @@ -802,7 +808,7 @@ int nfsmount(const char *spec, const char *node, int *flags, #endif static struct { - enum nfs_stat stat; + enum nfsstat stat; int errnum; } nfs_errtbl[] = { { NFS_OK, 0 }, diff --git a/mount/umount.c b/mount/umount.c index 4688495e2..0c1306a2d 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -270,12 +270,11 @@ umount_one (const char *spec, const char *node, const char *type, umnt_err = umnt_err2 = 0; if (lazy) { res = umount2 (node, MNT_DETACH); - if (res < 0) { - complain(errno, node); - return 1; - } else - return 0; + if (res < 0) + umnt_err = errno; + goto writemtab; } + if (force) { /* only supported for NFS */ res = umount2 (node, MNT_FORCE); if (res == -1) { @@ -373,6 +372,7 @@ umount_one (const char *spec, const char *node, const char *type, if (loopdev) del_loop(loopdev); + writemtab: if (!nomtab && mtab_is_writable() && (umnt_err == 0 || umnt_err == EINVAL || umnt_err == ENOENT)) { update_mtab (node, NULL); |