Busybox 1.21.0 squashed commit for jellybean

Change-Id: I423c7fc1254050c6495126b1b18dd33af07fed6b
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 64baae4..135d6a5 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -741,6 +741,15 @@
 	help
 	  TODO
 
+config FEATURE_VOLUMEID_EXFAT
+	bool "exFAT filesystem"
+	default y
+	depends on VOLUMEID
+	help
+	  exFAT (extended FAT) is a proprietary file system designed especially
+	  for flash drives. It has many features from NTFS, but with less
+	  overhead. exFAT is used on most SDXC cards for consumer electronics.
+
 config FEATURE_VOLUMEID_HFS
 	bool "hfs filesystem"
 	default y
@@ -769,6 +778,13 @@
 	help
 	  TODO
 
+config FEATURE_VOLUMEID_NILFS
+	bool "nilfs filesystem"
+	default y
+	depends on VOLUMEID
+	help
+	  TODO
+
 config FEATURE_VOLUMEID_NTFS
 	bool "ntfs filesystem"
 	default y
@@ -832,6 +848,16 @@
 	help
 	  TODO
 
+config FEATURE_VOLUMEID_SQUASHFS
+	bool "SquashFS filesystem"
+	default y
+	depends on VOLUMEID && FEATURE_BLKID_TYPE
+	help
+	  Squashfs is a compressed read-only filesystem for Linux. Squashfs is
+	  intended for general read-only filesystem use and in constrained block
+	  device/memory systems (e.g. embedded systems) where low overhead is
+	  needed.
+
 config FEATURE_VOLUMEID_SYSV
 	bool "sysv filesystem"
 	default y
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 1b22f3a..38421c2 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -75,6 +75,7 @@
 static const struct acpi_event f_evt_tab[] = {
 	{ "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" },
 	{ "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" },
+	{ "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" },
 };
 
 struct acpi_action {
@@ -234,7 +235,7 @@
 	const char *opt_action = "/etc/acpid.conf";
 	const char *opt_map = "/etc/acpi.map";
 #if ENABLE_FEATURE_PIDFILE
-	const char *opt_pidfile = "/var/run/acpid.pid";
+	const char *opt_pidfile = CONFIG_PID_FILE_PATH "/acpid.pid";
 #endif
 
 	INIT_G();
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index 14051b5..84173ce 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -70,7 +70,7 @@
 		int in = 0, l, color;
 		char pfx[16], *lvl;
 
-		/* Skip <#> at the start of lines */
+		/* Skip <[0-9]+> at the start of lines */
 		while (1) {
 			if (last == '\n' && buf[in] == '<') {
 				if (opts & OPT_C) {
@@ -96,13 +96,12 @@
 
 					full_write(STDOUT_FILENO, pfx, l);
 				}
-				in += 3;
-				if (in >= len)
-					break;
+				while (buf[in++] != '>' && in < len)
+					;
+			} else {
+				last = buf[in++];
+				putchar(last);
 			}
-			last = buf[in];
-			putchar(last);
-			in++;
 			if (in >= len)
 				break;
 		}
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c
index 2f0854a..b3e918f 100644
--- a/util-linux/fdformat.c
+++ b/util-linux/fdformat.c
@@ -116,7 +116,7 @@
 			/* Check backwards so we don't need a counter */
 			while (--read_bytes >= 0) {
 				if (data[read_bytes] != FD_FILL_BYTE) {
-					 printf("bad data in cyl %d\nContinuing... ", cyl);
+					printf("bad data in cyl %d\nContinuing... ", cyl);
 				}
 			}
 		}
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 1fb256e..c1cca10 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -3023,7 +3023,7 @@
 				printf("\nThe current boot file is: %s\n",
 					sgi_get_bootfile());
 				if (read_maybe_empty("Please enter the name of the "
-						   "new boot file: ") == '\n')
+						"new boot file: ") == '\n')
 					printf("Boot file unchanged\n");
 				else
 					sgi_set_bootfile(line_ptr);
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 65e6bd7..ff16389 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -898,8 +898,7 @@
 	pp->p_fstype = BSD_FS_UNUSED;
 #else
 	d->d_npartitions = 3;
-	pp = &d->d_partitions[2];             /* Partition C should be
-						   the whole disk */
+	pp = &d->d_partitions[2]; /* Partition C should be the whole disk */
 	pp->p_offset = 0;
 	pp->p_size   = d->d_secperunit;
 	pp->p_fstype = BSD_FS_UNUSED;
@@ -935,7 +934,7 @@
 		fdisk_fatal(unable_to_read);
 
 	memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
-		   sizeof(struct xbsd_disklabel));
+			sizeof(struct xbsd_disklabel));
 
 	if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC)
 		return 0;
diff --git a/util-linux/flock.c b/util-linux/flock.c
index e9be4ee..05a747f 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -45,7 +45,7 @@
 	if (argv[1]) {
 		fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666);
 		if (fd < 0 && errno == EISDIR)
-		        fd = open(argv[0], O_RDONLY|O_NOCTTY);
+			fd = open(argv[0], O_RDONLY|O_NOCTTY);
 		if (fd < 0)
 			bb_perror_msg_and_die("can't open '%s'", argv[0]);
 		//TODO? close_on_exec_on(fd);
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 1508ecb..c1d1b2c 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -13,7 +13,7 @@
  * 10.11.91  -  updated, does checking, no repairs yet.
  *		Sent out to the mailing-list for testing.
  *
- * 14.11.91  -	Testing seems to have gone well. Added some
+ * 14.11.91  -  Testing seems to have gone well. Added some
  *		correction-code, and changed some functions.
  *
  * 15.11.91  -  More correction code. Hopefully it notices most
@@ -22,11 +22,10 @@
  * 16.11.91  -  More corrections (thanks to Mika Jalava). Most
  *		things seem to work now. Yeah, sure.
  *
- *
- * 19.04.92  -	Had to start over again from this old version, as a
+ * 19.04.92  -  Had to start over again from this old version, as a
  *		kernel bug ate my enhanced fsck in february.
  *
- * 28.02.93  -	added support for different directory entry sizes..
+ * 28.02.93  -  added support for different directory entry sizes..
  *
  * Sat Mar  6 18:59:42 1993, faith@cs.unc.edu: Output namelen with
  *                           superblock information
@@ -35,31 +34,31 @@
  *                           to that required by fsutil
  *
  * Mon Jan  3 11:06:52 1994 - Dr. Wettstein (greg%wind.uucp@plains.nodak.edu)
- *			      Added support for file system valid flag.  Also
- *			      added program_version variable and output of
- *			      program name and version number when program
- *			      is executed.
+ *                            Added support for file system valid flag.  Also
+ *                            added program_version variable and output of
+ *                            program name and version number when program
+ *                            is executed.
  *
- * 30.10.94 - added support for v2 filesystem
- *            (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
+ * 30.10.94  - added support for v2 filesystem
+ *             (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
  *
- * 10.12.94  -  added test to prevent checking of mounted fs adapted
- *              from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck
- *              program.  (Daniel Quinlan, quinlan@yggdrasil.com)
+ * 10.12.94  - added test to prevent checking of mounted fs adapted
+ *             from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck
+ *             program.  (Daniel Quinlan, quinlan@yggdrasil.com)
  *
  * 01.07.96  - Fixed the v2 fs stuff to use the right #defines and such
- *	       for modern libcs (janl@math.uio.no, Nicolai Langfeldt)
+ *             for modern libcs (janl@math.uio.no, Nicolai Langfeldt)
  *
  * 02.07.96  - Added C bit fiddling routines from rmk@ecs.soton.ac.uk
  *             (Russell King).  He made them for ARM.  It would seem
- *	       that the ARM is powerful enough to do this in C whereas
+ *             that the ARM is powerful enough to do this in C whereas
  *             i386 and m64k must use assembly to get it fast >:-)
- *	       This should make minix fsck system-independent.
- *	       (janl@math.uio.no, Nicolai Langfeldt)
+ *             This should make minix fsck system-independent.
+ *             (janl@math.uio.no, Nicolai Langfeldt)
  *
  * 04.11.96  - Added minor fixes from Andreas Schwab to avoid compiler
  *             warnings.  Added mc68k bitops from
- *	       Joerg Dorchain <dorchain@mpi-sb.mpg.de>.
+ *             Joerg Dorchain <dorchain@mpi-sb.mpg.de>.
  *
  * 06.11.96  - Added v2 code submitted by Joerg Dorchain, but written by
  *             Andreas Schwab.
@@ -1131,7 +1130,7 @@
 			continue;
 		}
 		printf("Zone %d: %sin use, counted=%d\n",
-			   i, zone_in_use(i) ? "" : "not ", zone_count[i]);
+			i, zone_in_use(i) ? "" : "not ", zone_count[i]);
 	}
 }
 
@@ -1183,7 +1182,7 @@
 			continue;
 		}
 		printf("Zone %d: %sin use, counted=%d\n",
-			   i, zone_in_use(i) ? "" : "not ", zone_count[i]);
+			i, zone_in_use(i) ? "" : "not ", zone_count[i]);
 	}
 }
 #endif
@@ -1253,7 +1252,7 @@
 		printf("Forcing filesystem check on %s\n", device_name);
 	else if (OPT_repair)
 		printf("Filesystem on %s is dirty, needs checking\n",
-			   device_name);
+			device_name);
 
 	read_tables();
 
@@ -1280,23 +1279,23 @@
 			if (!inode_in_use(i))
 				free_cnt++;
 		printf("\n%6u inodes used (%u%%)\n", (INODES - free_cnt),
-			   100 * (INODES - free_cnt) / INODES);
+			100 * (INODES - free_cnt) / INODES);
 		for (i = FIRSTZONE, free_cnt = 0; i < ZONES; i++)
 			if (!zone_in_use(i))
 				free_cnt++;
 		printf("%6u zones used (%u%%)\n\n"
-			   "%6u regular files\n"
-			   "%6u directories\n"
-			   "%6u character device files\n"
-			   "%6u block device files\n"
-			   "%6u links\n"
-			   "%6u symbolic links\n"
-			   "------\n"
-			   "%6u files\n",
-			   (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES,
-			   regular, directory, chardev, blockdev,
-			   links - 2 * directory + 1, symlinks,
-			   total - 2 * directory + 1);
+			"%6u regular files\n"
+			"%6u directories\n"
+			"%6u character device files\n"
+			"%6u block device files\n"
+			"%6u links\n"
+			"%6u symbolic links\n"
+			"------\n"
+			"%6u files\n",
+			(ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES,
+			regular, directory, chardev, blockdev,
+			links - 2 * directory + 1, symlinks,
+			total - 2 * directory + 1);
 	}
 	if (changed) {
 		write_tables();
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index d662c81..1ae0c59 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -372,7 +372,7 @@
 	if (!argv[1]) {
 		if (compatible) {
 			/* For some reason, the original getopt gave no error
-			   when there were no arguments. */
+			 * when there were no arguments. */
 			printf(" --\n");
 			return 0;
 		}
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c
index 274050c..888f70e 100644
--- a/util-linux/ipcrm.c
+++ b/util-linux/ipcrm.c
@@ -160,7 +160,7 @@
 
 			/* convert key to id */
 			id = ((c == 'q') ? msgget(key, 0) :
-				  (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
+				(c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
 
 			if (id < 0) {
 				const char *errmsg;
@@ -189,8 +189,8 @@
 		}
 
 		result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
-				  (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
-				  semctl(id, 0, IPC_RMID, arg));
+				(c == 'm') ? shmctl(id, IPC_RMID, NULL) :
+				semctl(id, 0, IPC_RMID, arg));
 
 		if (result) {
 			const char *errmsg;
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c
index ee7df5e..2668caf 100644
--- a/util-linux/ipcs.c
+++ b/util-linux/ipcs.c
@@ -152,54 +152,54 @@
 		if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0)
 			return;
 		/* glibc 2.1.3 and all earlier libc's have ints as fields
-		   of struct shminfo; glibc 2.1.91 has unsigned long; ach */
+		 * of struct shminfo; glibc 2.1.91 has unsigned long; ach */
 		printf("max number of segments = %lu\n"
-				  "max seg size (kbytes) = %lu\n"
-				  "max total shared memory (pages) = %lu\n"
-				  "min seg size (bytes) = %lu\n",
-				  (unsigned long) shminfo.shmmni,
-				  (unsigned long) (shminfo.shmmax >> 10),
-				  (unsigned long) shminfo.shmall,
-				  (unsigned long) shminfo.shmmin);
+				"max seg size (kbytes) = %lu\n"
+				"max total shared memory (pages) = %lu\n"
+				"min seg size (bytes) = %lu\n",
+				(unsigned long) shminfo.shmmni,
+				(unsigned long) (shminfo.shmmax >> 10),
+				(unsigned long) shminfo.shmall,
+				(unsigned long) shminfo.shmmin);
 		return;
 
 	case STATUS:
 		printf("------ Shared Memory %s --------\n", "Status");
-		printf(	  "segments allocated %d\n"
-				  "pages allocated %ld\n"
-				  "pages resident  %ld\n"
-				  "pages swapped   %ld\n"
-				  "Swap performance: %ld attempts\t%ld successes\n",
-				  shm_info.used_ids,
-				  shm_info.shm_tot,
-				  shm_info.shm_rss,
-				  shm_info.shm_swp,
-				  shm_info.swap_attempts, shm_info.swap_successes);
+		printf("segments allocated %d\n"
+				"pages allocated %ld\n"
+				"pages resident  %ld\n"
+				"pages swapped   %ld\n"
+				"Swap performance: %ld attempts\t%ld successes\n",
+				shm_info.used_ids,
+				shm_info.shm_tot,
+				shm_info.shm_rss,
+				shm_info.shm_swp,
+				shm_info.swap_attempts, shm_info.swap_successes);
 		return;
 
 	case CREATOR:
 		printf("------ Shared Memory %s --------\n", "Segment Creators/Owners");
-		printf(	  "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-				  "shmid", "perms", "cuid", "cgid", "uid", "gid");
+		printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+				"shmid", "perms", "cuid", "cgid", "uid", "gid");
 		break;
 
 	case TIME:
 		printf("------ Shared Memory %s --------\n", "Attach/Detach/Change Times");
-		printf(	  "%-10s %-10s %-20s %-20s %-20s\n",
-				  "shmid", "owner", "attached", "detached", "changed");
+		printf("%-10s %-10s %-20s %-20s %-20s\n",
+				"shmid", "owner", "attached", "detached", "changed");
 		break;
 
 	case PID:
 		printf("------ Shared Memory %s --------\n", "Creator/Last-op");
-		printf(	  "%-10s %-10s %-10s %-10s\n",
-				  "shmid", "owner", "cpid", "lpid");
+		printf("%-10s %-10s %-10s %-10s\n",
+				"shmid", "owner", "cpid", "lpid");
 		break;
 
 	default:
 		printf("------ Shared Memory %s --------\n", "Segments");
-		printf(	  "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
-				  "key", "shmid", "owner", "perms", "bytes", "nattch",
-				  "status");
+		printf("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
+				"key", "shmid", "owner", "perms", "bytes", "nattch",
+				"status");
 		break;
 	}
 
@@ -220,11 +220,11 @@
 				printf("%-10d %-10d", shmid, ipcp->uid);
 			/* ctime uses static buffer: use separate calls */
 			printf(" %-20.16s", shmseg.shm_atime
-					  ? ctime(&shmseg.shm_atime) + 4 : "Not set");
+					? ctime(&shmseg.shm_atime) + 4 : "Not set");
 			printf(" %-20.16s", shmseg.shm_dtime
-					  ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
+					? ctime(&shmseg.shm_dtime) + 4 : "Not set");
 			printf(" %-20.16s\n", shmseg.shm_ctime
-					  ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
+					? ctime(&shmseg.shm_ctime) + 4 : "Not set");
 			break;
 		case PID:
 			if (pw)
@@ -241,17 +241,17 @@
 			else
 				printf("%-10d %-10d", shmid, ipcp->uid);
 			printf(" %-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
-					  /*
-					   * earlier: int, Austin has size_t
-					   */
-					  (unsigned long) shmseg.shm_segsz,
-					  /*
-					   * glibc-2.1.3 and earlier has unsigned short;
-					   * Austin has shmatt_t
-					   */
-					  (long) shmseg.shm_nattch,
-					  ipcp->mode & SHM_DEST ? "dest" : " ",
-					  ipcp->mode & SHM_LOCKED ? "locked" : " ");
+					/*
+					 * earlier: int, Austin has size_t
+					 */
+					(unsigned long) shmseg.shm_segsz,
+					/*
+					 * glibc-2.1.3 and earlier has unsigned short;
+					 * Austin has shmatt_t
+					 */
+					(long) shmseg.shm_nattch,
+					ipcp->mode & SHM_DEST ? "dest" : " ",
+					ipcp->mode & SHM_LOCKED ? "locked" : " ");
 			break;
 		}
 	}
@@ -281,32 +281,32 @@
 		if ((semctl(0, 0, IPC_INFO, arg)) < 0)
 			return;
 		printf("max number of arrays = %d\n"
-				  "max semaphores per array = %d\n"
-				  "max semaphores system wide = %d\n"
-				  "max ops per semop call = %d\n"
-				  "semaphore max value = %d\n",
-				  seminfo.semmni,
-				  seminfo.semmsl,
-				  seminfo.semmns, seminfo.semopm, seminfo.semvmx);
+				"max semaphores per array = %d\n"
+				"max semaphores system wide = %d\n"
+				"max ops per semop call = %d\n"
+				"semaphore max value = %d\n",
+				seminfo.semmni,
+				seminfo.semmsl,
+				seminfo.semmns, seminfo.semopm, seminfo.semvmx);
 		return;
 
 	case STATUS:
 		printf("------ Semaphore %s --------\n", "Status");
-		printf(	  "used arrays = %d\n"
-				  "allocated semaphores = %d\n",
-				  seminfo.semusz, seminfo.semaem);
+		printf("used arrays = %d\n"
+				"allocated semaphores = %d\n",
+				seminfo.semusz, seminfo.semaem);
 		return;
 
 	case CREATOR:
 		printf("------ Semaphore %s --------\n", "Arrays Creators/Owners");
-		printf(	  "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-				  "semid", "perms", "cuid", "cgid", "uid", "gid");
+		printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+				"semid", "perms", "cuid", "cgid", "uid", "gid");
 		break;
 
 	case TIME:
 		printf("------ Shared Memory %s --------\n", "Operation/Change Times");
-		printf(	  "%-8s %-10s %-26.24s %-26.24s\n",
-				  "shmid", "owner", "last-op", "last-changed");
+		printf("%-8s %-10s %-26.24s %-26.24s\n",
+				"shmid", "owner", "last-op", "last-changed");
 		break;
 
 	case PID:
@@ -314,8 +314,8 @@
 
 	default:
 		printf("------ Semaphore %s --------\n", "Arrays");
-		printf(	  "%-10s %-10s %-10s %-10s %-10s\n",
-				  "key", "semid", "owner", "perms", "nsems");
+		printf("%-10s %-10s %-10s %-10s %-10s\n",
+				"key", "semid", "owner", "perms", "nsems");
 		break;
 	}
 
@@ -337,9 +337,9 @@
 				printf("%-8d %-10d", semid, ipcp->uid);
 			/* ctime uses static buffer: use separate calls */
 			printf("  %-26.24s", semary.sem_otime
-					  ? ctime(&semary.sem_otime) : "Not set");
+					? ctime(&semary.sem_otime) : "Not set");
 			printf(" %-26.24s\n", semary.sem_ctime
-					  ? ctime(&semary.sem_ctime) : "Not set");
+					? ctime(&semary.sem_ctime) : "Not set");
 			break;
 		case PID:
 			break;
@@ -351,13 +351,13 @@
 			else
 				printf("%-10d %-9d", semid, ipcp->uid);
 			printf(" %-10o %-10ld\n", ipcp->mode & 0777,
-					  /*
-					   * glibc-2.1.3 and earlier has unsigned short;
-					   * glibc-2.1.91 has variation between
-					   * unsigned short and unsigned long
-					   * Austin prescribes unsigned short.
-					   */
-					  (long) semary.sem_nsems);
+					/*
+					 * glibc-2.1.3 and earlier has unsigned short;
+					 * glibc-2.1.91 has variation between
+					 * unsigned short and unsigned long
+					 * Austin prescribes unsigned short.
+					 */
+					(long) semary.sem_nsems);
 			break;
 		}
 	}
@@ -383,42 +383,42 @@
 		if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0)
 			return;
 		printf("------ Message%s --------\n", "s: Limits");
-		printf(	  "max queues system wide = %d\n"
-				  "max size of message (bytes) = %d\n"
-				  "default max size of queue (bytes) = %d\n",
-				  msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
+		printf("max queues system wide = %d\n"
+				"max size of message (bytes) = %d\n"
+				"default max size of queue (bytes) = %d\n",
+				msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
 		return;
 
 	case STATUS:
 		printf("------ Message%s --------\n", "s: Status");
-		printf(	  "allocated queues = %d\n"
-				  "used headers = %d\n"
-				  "used space = %d bytes\n",
-				  msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
+		printf("allocated queues = %d\n"
+				"used headers = %d\n"
+				"used space = %d bytes\n",
+				msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
 		return;
 
 	case CREATOR:
 		printf("------ Message%s --------\n", " Queues: Creators/Owners");
-		printf(	  "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-				  "msqid", "perms", "cuid", "cgid", "uid", "gid");
+		printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+				"msqid", "perms", "cuid", "cgid", "uid", "gid");
 		break;
 
 	case TIME:
 		printf("------ Message%s --------\n", " Queues Send/Recv/Change Times");
-		printf(	  "%-8s %-10s %-20s %-20s %-20s\n",
-				  "msqid", "owner", "send", "recv", "change");
+		printf("%-8s %-10s %-20s %-20s %-20s\n",
+				"msqid", "owner", "send", "recv", "change");
 		break;
 
 	case PID:
 		printf("------ Message%s --------\n", " Queues PIDs");
-		printf(	  "%-10s %-10s %-10s %-10s\n",
-				  "msqid", "owner", "lspid", "lrpid");
+		printf("%-10s %-10s %-10s %-10s\n",
+				"msqid", "owner", "lspid", "lrpid");
 		break;
 
 	default:
 		printf("------ Message%s --------\n", " Queues");
-		printf(	  "%-10s %-10s %-10s %-10s %-12s %-12s\n",
-				  "key", "msqid", "owner", "perms", "used-bytes", "messages");
+		printf("%-10s %-10s %-10s %-10s %-12s %-12s\n",
+				"key", "msqid", "owner", "perms", "used-bytes", "messages");
 		break;
 	}
 
@@ -438,11 +438,11 @@
 			else
 				printf("%-8d %-10d", msqid, ipcp->uid);
 			printf(" %-20.16s", msgque.msg_stime
-					  ? ctime(&msgque.msg_stime) + 4 : "Not set");
+					? ctime(&msgque.msg_stime) + 4 : "Not set");
 			printf(" %-20.16s", msgque.msg_rtime
-					  ? ctime(&msgque.msg_rtime) + 4 : "Not set");
+					? ctime(&msgque.msg_rtime) + 4 : "Not set");
 			printf(" %-20.16s\n", msgque.msg_ctime
-					  ? ctime(&msgque.msg_ctime) + 4 : "Not set");
+					? ctime(&msgque.msg_ctime) + 4 : "Not set");
 			break;
 		case PID:
 			if (pw)
@@ -459,13 +459,13 @@
 			else
 				printf("%-10d %-10d", msqid, ipcp->uid);
 			printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
-					  /*
-					   * glibc-2.1.3 and earlier has unsigned short;
-					   * glibc-2.1.91 has variation between
-					   * unsigned short, unsigned long
-					   * Austin has msgqnum_t
-					   */
-					  (long) msgque.msg_cbytes, (long) msgque.msg_qnum);
+					/*
+					 * glibc-2.1.3 and earlier has unsigned short;
+					 * glibc-2.1.91 has variation between
+					 * unsigned short, unsigned long
+					 * Austin has msgqnum_t
+					 */
+					(long) msgque.msg_cbytes, (long) msgque.msg_qnum);
 			break;
 		}
 	}
@@ -483,18 +483,18 @@
 	}
 
 	printf("\nShared memory Segment shmid=%d\n"
-			  "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
-			  "mode=%#o\taccess_perms=%#o\n"
-			  "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
-			  shmid,
-			  ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
-			  ipcp->mode, ipcp->mode & 0777,
-			  (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
-			  (long) shmds.shm_nattch);
+			"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
+			"mode=%#o\taccess_perms=%#o\n"
+			"bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
+			shmid,
+			ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+			ipcp->mode, ipcp->mode & 0777,
+			(long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
+			(long) shmds.shm_nattch);
 	printf("att_time=%-26.24s\n",
-			  shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
+			shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
 	printf("det_time=%-26.24s\n",
-			  shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
+			shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
 	printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
 }
 
@@ -510,24 +510,24 @@
 	}
 
 	printf("\nMessage Queue msqid=%d\n"
-			  "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
-			  "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
-			  msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
-			  /*
-			   * glibc-2.1.3 and earlier has unsigned short;
-			   * glibc-2.1.91 has variation between
-			   * unsigned short, unsigned long
-			   * Austin has msgqnum_t (for msg_qbytes)
-			   */
-			  (long) buf.msg_cbytes, (long) buf.msg_qbytes,
-			  (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
+			"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
+			"cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
+			msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
+			/*
+			 * glibc-2.1.3 and earlier has unsigned short;
+			 * glibc-2.1.91 has variation between
+			 * unsigned short, unsigned long
+			 * Austin has msgqnum_t (for msg_qbytes)
+			 */
+			(long) buf.msg_cbytes, (long) buf.msg_qbytes,
+			(long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
 
 	printf("send_time=%-26.24s\n",
-			  buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
+			buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
 	printf("rcv_time=%-26.24s\n",
-			  buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
+			buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
 	printf("change_time=%-26.24s\n\n",
-			  buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
+			buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
 }
 
 static void print_sem(int semid)
@@ -544,19 +544,19 @@
 	}
 
 	printf("\nSemaphore Array semid=%d\n"
-			  "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
-			  "mode=%#o, access_perms=%#o\n"
-			  "nsems = %ld\n"
-			  "otime = %-26.24s\n",
-			  semid,
-			  ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
-			  ipcp->mode, ipcp->mode & 0777,
-			  (long) semds.sem_nsems,
-			  semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
+			"uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
+			"mode=%#o, access_perms=%#o\n"
+			"nsems = %ld\n"
+			"otime = %-26.24s\n",
+			semid,
+			ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+			ipcp->mode, ipcp->mode & 0777,
+			(long) semds.sem_nsems,
+			semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
 	printf("ctime = %-26.24s\n"
-			  "%-10s %-10s %-10s %-10s %-10s\n",
-			  ctime(&semds.sem_ctime),
-			  "semnum", "value", "ncount", "zcount", "pid");
+			"%-10s %-10s %-10s %-10s %-10s\n",
+			ctime(&semds.sem_ctime),
+			"semnum", "value", "ncount", "zcount", "pid");
 
 	arg.val = 0;
 	for (i = 0; i < semds.sem_nsems; i++) {
diff --git a/util-linux/lspci.c b/util-linux/lspci.c
index 5184858..514678a 100644
--- a/util-linux/lspci.c
+++ b/util-linux/lspci.c
@@ -74,11 +74,11 @@
 
 	if (option_mask32 & OPT_m) {
 		printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"",
-		       pci_slot_name, pci_class, pci_vid, pci_did,
-		       pci_subsys_vid, pci_subsys_did);
+			pci_slot_name, pci_class, pci_vid, pci_did,
+			pci_subsys_vid, pci_subsys_did);
 	} else {
 		printf("%s Class %04x: %04x:%04x",
-		       pci_slot_name, pci_class, pci_vid, pci_did);
+			pci_slot_name, pci_class, pci_vid, pci_did);
 	}
 
 	if ((option_mask32 & OPT_k) && driver) {
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index c4829a5..75de14f 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -92,7 +92,9 @@
 //usage:       "\n"
 //usage:       "If /dev/mdev.seq file exists, mdev will wait for its value\n"
 //usage:       "to match $SEQNUM variable. This prevents plug/unplug races.\n"
-//usage:       "To activate this feature, create empty /dev/mdev.seq at boot."
+//usage:       "To activate this feature, create empty /dev/mdev.seq at boot.\n"
+//usage:       "\n"
+//usage:       "If /dev/mdev.log file exists, debug log will be appended to it."
 
 #include "libbb.h"
 #include "xregex.h"
@@ -139,10 +141,101 @@
  * This happens regardless of /sys/class/.../dev existence.
  */
 
+/* Kernel's hotplug environment constantly changes.
+ * Here are new cases I observed on 3.1.0:
+ *
+ * Case with $DEVNAME and $DEVICE, not just $DEVPATH:
+ * ACTION=add
+ * BUSNUM=001
+ * DEVICE=/proc/bus/usb/001/003
+ * DEVNAME=bus/usb/001/003
+ * DEVNUM=003
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5
+ * DEVTYPE=usb_device
+ * MAJOR=189
+ * MINOR=2
+ * PRODUCT=18d1/4e12/227
+ * SUBSYSTEM=usb
+ * TYPE=0/0/0
+ *
+ * Case with $DEVICE, but no $DEVNAME - apparenty, usb iface notification?
+ * "Please load me a module" thing?
+ * ACTION=add
+ * DEVICE=/proc/bus/usb/001/003
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0
+ * DEVTYPE=usb_interface
+ * INTERFACE=8/6/80
+ * MODALIAS=usb:v18D1p4E12d0227dc00dsc00dp00ic08isc06ip50
+ * PRODUCT=18d1/4e12/227
+ * SUBSYSTEM=usb
+ * TYPE=0/0/0
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5
+ * DEVTYPE=scsi_host
+ * SUBSYSTEM=scsi
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/scsi_host/host5
+ * SUBSYSTEM=scsi_host
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0
+ * DEVTYPE=scsi_target
+ * SUBSYSTEM=scsi
+ *
+ * Case with strange $MODALIAS:
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0
+ * DEVTYPE=scsi_device
+ * MODALIAS=scsi:t-0x00
+ * SUBSYSTEM=scsi
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_disk/5:0:0:0
+ * SUBSYSTEM=scsi_disk
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_device/5:0:0:0
+ * SUBSYSTEM=scsi_device
+ *
+ * Case with explicit $MAJOR/$MINOR (no need to read /sys/$DEVPATH/dev?):
+ * ACTION=add
+ * DEVNAME=bsg/5:0:0:0
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/bsg/5:0:0:0
+ * MAJOR=253
+ * MINOR=1
+ * SUBSYSTEM=bsg
+ *
+ * ACTION=add
+ * DEVPATH=/devices/virtual/bdi/8:16
+ * SUBSYSTEM=bdi
+ *
+ * ACTION=add
+ * DEVNAME=sdb
+ * DEVPATH=/block/sdb
+ * DEVTYPE=disk
+ * MAJOR=8
+ * MINOR=16
+ * SUBSYSTEM=block
+ *
+ * Case with ACTION=change:
+ * ACTION=change
+ * DEVNAME=sdb
+ * DEVPATH=/block/sdb
+ * DEVTYPE=disk
+ * DISK_MEDIA_CHANGE=1
+ * MAJOR=8
+ * MINOR=16
+ * SUBSYSTEM=block
+ */
+
+static const char keywords[] ALIGN1 = "add\0remove\0change\0";
+enum { OP_add, OP_remove };
+
 struct rule {
 	bool keep_matching;
 	bool regex_compiled;
-	bool regex_has_slash;
 	mode_t mode;
 	int maj, min0, min1;
 	struct bb_uidgid_t ugid;
@@ -154,6 +247,7 @@
 
 struct globals {
 	int root_major, root_minor;
+	smallint verbose;
 	char *subsystem;
 #if ENABLE_FEATURE_MDEV_CONF
 	const char *filename;
@@ -245,7 +339,6 @@
 			}
 			xregcomp(&G.cur_rule.match, val, REG_EXTENDED);
 			G.cur_rule.regex_compiled = 1;
-			G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL);
 		}
 
 		/* 2nd field: uid:gid - device ownership */
@@ -336,6 +429,18 @@
 
 #endif
 
+static void mkdir_recursive(char *name)
+{
+	/* if name has many levels ("dir1/dir2"),
+	 * bb_make_directory() will create dir1 according to umask,
+	 * not according to its "mode" parameter.
+	 * Since we run with umask=0, need to temporarily switch it.
+	 */
+	umask(022); /* "dir1" (if any) will be 0755 too */
+	bb_make_directory(name, 0755, FILEUTILS_RECUR);
+	umask(0);
+}
+
 /* Builds an alias path.
  * This function potentionally reallocates the alias parameter.
  * Only used for ENABLE_FEATURE_MDEV_RENAME
@@ -349,7 +454,7 @@
 	dest = strrchr(alias, '/');
 	if (dest) { /* ">bar/[baz]" ? */
 		*dest = '\0'; /* mkdir bar */
-		bb_make_directory(alias, 0755, FILEUTILS_RECUR);
+		mkdir_recursive(alias);
 		*dest = '/';
 		if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */
 			dest = alias;
@@ -366,13 +471,16 @@
  * after NUL, but we promise to not mangle (IOW: to restore if needed)
  * path string.
  * NB2: "mdev -s" may call us many times, do not leak memory/fds!
+ *
+ * device_name = $DEVNAME (may be NULL)
+ * path        = /sys/$DEVPATH
  */
-static void make_device(char *path, int delete)
+static void make_device(char *device_name, char *path, int operation)
 {
-	char *device_name, *subsystem_slash_devname;
 	int major, minor, type, len;
 
-	dbg("%s('%s', delete:%d)", __func__, path, delete);
+	if (G.verbose)
+		bb_error_msg("device: %s, %s", device_name, path);
 
 	/* Try to read major/minor string.  Note that the kernel puts \n after
 	 * the data, so we don't need to worry about null terminating the string
@@ -380,7 +488,7 @@
 	 * We also depend on path having writeable space after it.
 	 */
 	major = -1;
-	if (!delete) {
+	if (operation == OP_add) {
 		char *dev_maj_min = path + strlen(path);
 
 		strcpy(dev_maj_min, "/dev");
@@ -391,40 +499,27 @@
 				return;
 			/* no "dev" file, but we can still run scripts
 			 * based on device name */
-		} else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) {
+		} else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) == 2) {
+			if (G.verbose)
+				bb_error_msg("maj,min: %u,%u", major, minor);
+		} else {
 			major = -1;
 		}
 	}
 	/* else: for delete, -1 still deletes the node, but < -1 suppresses that */
 
 	/* Determine device name, type, major and minor */
-	device_name = (char*) bb_basename(path);
+	if (!device_name)
+		device_name = (char*) bb_basename(path);
 	/* http://kernel.org/doc/pending/hotplug.txt says that only
 	 * "/sys/block/..." is for block devices. "/sys/bus" etc is not.
 	 * But since 2.6.25 block devices are also in /sys/class/block.
-	 * We use strstr("/block/") to forestall future surprises. */
+	 * We use strstr("/block/") to forestall future surprises.
+	 */
 	type = S_IFCHR;
 	if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0))
 		type = S_IFBLK;
 
-	/* Make path point to "subsystem/device_name" */
-	subsystem_slash_devname = NULL;
-	/* Check for coldplug invocations first */
-	if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */
-		path += sizeof("/sys/") - 1;
-	else if (strncmp(path, "/sys/class/", 11) == 0)
-		path += sizeof("/sys/class/") - 1;
-	else {
-		/* Example of a hotplug invocation:
-		 * SUBSYSTEM="block"
-		 * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3"
-		 * ("/sys" is added by mdev_main)
-		 * - path does not contain subsystem
-		 */
-		subsystem_slash_devname = concat_path_file(G.subsystem, device_name);
-		path = subsystem_slash_devname;
-	}
-
 #if ENABLE_FEATURE_MDEV_CONF
 	G.rule_idx = 0; /* restart from the beginning (think mdev -s) */
 #endif
@@ -434,10 +529,10 @@
 		char *command;
 		char *alias;
 		char aliaslink = aliaslink; /* for compiler */
-		const char *node_name;
+		char *node_name;
 		const struct rule *rule;
 
-		str_to_match = "";
+		str_to_match = device_name;
 
 		rule = next_rule();
 
@@ -455,10 +550,8 @@
 			dbg("getenv('%s'):'%s'", rule->envvar, str_to_match);
 			if (!str_to_match)
 				continue;
-		} else {
-			/* regex to match [subsystem/]device_name */
-			str_to_match = (rule->regex_has_slash ? path : device_name);
 		}
+		/* else: str_to_match = device_name */
 
 		if (rule->regex_compiled) {
 			int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0);
@@ -537,7 +630,7 @@
 			/* Are we running this command now?
 			 * Run $cmd on delete, @cmd on create, *cmd on both
 			 */
-			if (s2 - s != delete) {
+			if (s2 - s != (operation == OP_remove) || *s2 == '*') {
 				/* We are here if: '*',
 				 * or: '@' and delete = 0,
 				 * or: '$' and delete = 1
@@ -556,21 +649,30 @@
 			dbg("alias2:'%s'", alias);
 		}
 
-		if (!delete && major >= 0) {
-			dbg("mknod('%s',%o,(%d,%d))", node_name, rule->mode | type, major, minor);
+		if (operation == OP_add && major >= 0) {
+			char *slash = strrchr(node_name, '/');
+			if (slash) {
+				*slash = '\0';
+				mkdir_recursive(node_name);
+				*slash = '/';
+			}
+			if (G.verbose)
+				bb_error_msg("mknod: %s (%d,%d) %o", node_name, major, minor, rule->mode | type);
 			if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST)
 				bb_perror_msg("can't create '%s'", node_name);
-			if (major == G.root_major && minor == G.root_minor)
-				symlink(node_name, "root");
 			if (ENABLE_FEATURE_MDEV_CONF) {
 				chmod(node_name, rule->mode);
 				chown(node_name, rule->ugid.uid, rule->ugid.gid);
 			}
+			if (major == G.root_major && minor == G.root_minor)
+				symlink(node_name, "root");
 			if (ENABLE_FEATURE_MDEV_RENAME && alias) {
 				if (aliaslink == '>') {
 //TODO: on devtmpfs, device_name already exists and symlink() fails.
 //End result is that instead of symlink, we have two nodes.
 //What should be done?
+					if (G.verbose)
+						bb_error_msg("symlink: %s", device_name);
 					symlink(node_name, device_name);
 				}
 			}
@@ -582,17 +684,24 @@
 			char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem);
 			putenv(s);
 			putenv(s1);
+			if (G.verbose)
+				bb_error_msg("running: %s", command);
 			if (system(command) == -1)
 				bb_perror_msg("can't run '%s'", command);
 			bb_unsetenv_and_free(s1);
 			bb_unsetenv_and_free(s);
 		}
 
-		if (delete && major >= -1) {
+		if (operation == OP_remove && major >= -1) {
 			if (ENABLE_FEATURE_MDEV_RENAME && alias) {
-				if (aliaslink == '>')
+				if (aliaslink == '>') {
+					if (G.verbose)
+						bb_error_msg("unlink: %s", device_name);
 					unlink(device_name);
+				}
 			}
+			if (G.verbose)
+				bb_error_msg("unlink: %s", node_name);
 			unlink(node_name);
 		}
 
@@ -605,8 +714,6 @@
 		if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching)
 			break;
 	} /* for (;;) */
-
-	free(subsystem_slash_devname);
 }
 
 /* File callback for /sys/ traversal */
@@ -624,7 +731,7 @@
 
 	strcpy(scratch, fileName);
 	scratch[len] = '\0';
-	make_device(scratch, /*delete:*/ 0);
+	make_device(/*DEVNAME:*/ NULL, scratch, OP_add);
 
 	return TRUE;
 }
@@ -696,7 +803,7 @@
 	}
 
 	/* Tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading"
-	 * Note: we emit -1 if firmware file wasn't found.
+	 * Note: we emit -1 also if firmware file wasn't found.
 	 * There are cases when otherwise kernel would wait for minutes
 	 * before timing out.
 	 */
@@ -769,9 +876,8 @@
 		char *fw;
 		char *seq;
 		char *action;
-		char *env_path;
-		static const char keywords[] ALIGN1 = "remove\0add\0";
-		enum { OP_remove = 0, OP_add };
+		char *env_devname;
+		char *env_devpath;
 		smalluint op;
 
 		/* Hotplug:
@@ -780,12 +886,13 @@
 		 * DEVPATH is like "/block/sda" or "/class/input/mice"
 		 */
 		action = getenv("ACTION");
-		env_path = getenv("DEVPATH");
+		op = index_in_strings(keywords, action);
+		env_devname = getenv("DEVNAME"); /* can be NULL */
+		env_devpath = getenv("DEVPATH");
 		G.subsystem = getenv("SUBSYSTEM");
-		if (!action || !env_path /*|| !G.subsystem*/)
+		if (!action || !env_devpath /*|| !G.subsystem*/)
 			bb_show_usage();
 		fw = getenv("FIRMWARE");
-		op = index_in_strings(keywords, action);
 		/* If it exists, does /dev/mdev.seq match $SEQNUM?
 		 * If it does not match, earlier mdev is running
 		 * in parallel, and we need to wait */
@@ -811,16 +918,25 @@
 			} while (--timeout);
 		}
 
-		snprintf(temp, PATH_MAX, "/sys%s", env_path);
+		{
+			int logfd = open("/dev/mdev.log", O_WRONLY | O_APPEND);
+			if (logfd >= 0) {
+				xmove_fd(logfd, STDERR_FILENO);
+				G.verbose = 1;
+				bb_error_msg("seq: %s action: %s", seq, action);
+			}
+		}
+
+		snprintf(temp, PATH_MAX, "/sys%s", env_devpath);
 		if (op == OP_remove) {
 			/* Ignoring "remove firmware". It was reported
 			 * to happen and to cause erroneous deletion
 			 * of device nodes. */
 			if (!fw)
-				make_device(temp, /*delete:*/ 1);
+				make_device(env_devname, temp, op);
 		}
 		else if (op == OP_add) {
-			make_device(temp, /*delete:*/ 0);
+			make_device(env_devname, temp, op);
 			if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
 				if (fw)
 					load_firmware(fw, temp);
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 34543bb..7e547fe 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -36,6 +36,10 @@
 //usage:	IF_FEATURE_MTAB_SUPPORT(
 //usage:     "\n	-n		Don't update /etc/mtab"
 //usage:	)
+//usage:	IF_FEATURE_MOUNT_VERBOSE(
+//usage:     "\n	-v		Verbose"
+//usage:	)
+////usage:   "\n	-s		Sloppy (ignored)"
 //usage:     "\n	-r		Read-only mount"
 //usage:     "\n	-w		Read-write mount (default)"
 //usage:     "\n	-t FSTYPE[,...]	Filesystem type(s)"
@@ -113,6 +117,12 @@
 #ifndef MS_RELATIME
 # define MS_RELATIME    (1 << 21)
 #endif
+#ifndef MS_STRICTATIME
+# define MS_STRICTATIME (1 << 24)
+#endif
+
+/* Any ~MS_FOO value has this bit set: */
+#define BB_MS_INVERTED_VALUE (1u << 31)
 
 #include "libbb.h"
 #if ENABLE_FEATURE_MOUNT_LABEL
@@ -218,6 +228,7 @@
 		IF_DESKTOP(/* "user"  */ MOUNT_USERS,)
 		IF_DESKTOP(/* "users" */ MOUNT_USERS,)
 		/* "_netdev" */ 0,
+		IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */
 	)
 
 	IF_FEATURE_MOUNT_FLAGS(
@@ -239,6 +250,7 @@
 		/* "nomand"      */ ~MS_MANDLOCK,
 		/* "relatime"    */ MS_RELATIME,
 		/* "norelatime"  */ ~MS_RELATIME,
+		/* "strictatime" */ MS_STRICTATIME,
 		/* "loud"        */ ~MS_SILENT,
 		/* "rbind"       */ MS_BIND|MS_RECURSIVE,
 
@@ -275,6 +287,7 @@
 		IF_DESKTOP("user\0")
 		IF_DESKTOP("users\0")
 		"_netdev\0"
+		IF_DESKTOP("comment=\0") /* systemd uses this in fstab */
 	)
 	IF_FEATURE_MOUNT_FLAGS(
 		// vfs flags
@@ -295,6 +308,7 @@
 		"nomand\0"
 		"relatime\0"
 		"norelatime\0"
+		"strictatime\0"
 		"loud\0"
 		"rbind\0"
 
@@ -450,9 +464,9 @@
 
 // Use the mount_options list to parse options into flags.
 // Also update list of unrecognized options if unrecognized != NULL
-static long parse_mount_options(char *options, char **unrecognized)
+static unsigned long parse_mount_options(char *options, char **unrecognized)
 {
-	long flags = MS_SILENT;
+	unsigned long flags = MS_SILENT;
 
 	// Loop through options
 	for (;;) {
@@ -465,15 +479,22 @@
 // FIXME: use hasmntopt()
 		// Find this option in mount_options
 		for (i = 0; i < ARRAY_SIZE(mount_options); i++) {
-			if (strcasecmp(option_str, options) == 0) {
-				long fl = mount_options[i];
-				if (fl < 0)
+			unsigned opt_len = strlen(option_str);
+
+			if (strncasecmp(option_str, options, opt_len) == 0
+			 && (options[opt_len] == '\0'
+			    /* or is it "comment=" thingy in fstab? */
+			    IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' ))
+			    )
+			) {
+				unsigned long fl = mount_options[i];
+				if (fl & BB_MS_INVERTED_VALUE)
 					flags &= fl;
 				else
 					flags |= fl;
 				goto found;
 			}
-			option_str += strlen(option_str) + 1;
+			option_str += opt_len + 1;
 		}
 		// We did not recognize this option.
 		// If "unrecognized" is not NULL, append option there.
@@ -548,7 +569,7 @@
 
 // Perform actual mount of specific filesystem at specific location.
 // NB: mp->xxx fields may be trashed on exit
-static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
+static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filteropts)
 {
 	int rc = 0;
 
@@ -913,7 +934,7 @@
 static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp)
 {
 	if (!xdr_u_int(xdrs, &objp->fhs_status))
-		 return FALSE;
+		return FALSE;
 	if (objp->fhs_status == 0)
 		return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle);
 	return TRUE;
@@ -927,8 +948,8 @@
 static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
 {
 	return xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
-			   (unsigned int *) &objp->fhandle3_len,
-			   FHSIZE3);
+			(unsigned int *) &objp->fhandle3_len,
+			FHSIZE3);
 }
 
 static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
@@ -936,10 +957,10 @@
 	if (!xdr_fhandle3(xdrs, &objp->fhandle))
 		return FALSE;
 	return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val),
-			   &(objp->auth_flavours.auth_flavours_len),
-			   ~0,
-			   sizeof(int),
-			   (xdrproc_t) xdr_int);
+			&(objp->auth_flavours.auth_flavours_len),
+			~0,
+			sizeof(int),
+			(xdrproc_t) xdr_int);
 }
 
 static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
@@ -1080,7 +1101,7 @@
 }
 
 /* NB: mp->xxx fields may be trashed on exit */
-static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
+static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
 {
 	CLIENT *mclient;
 	char *hostname;
@@ -1508,19 +1529,19 @@
 		switch (pm_mnt.pm_prot) {
 		case IPPROTO_UDP:
 			mclient = clntudp_create(&mount_server_addr,
-						 pm_mnt.pm_prog,
-						 pm_mnt.pm_vers,
-						 retry_timeout,
-						 &msock);
+						pm_mnt.pm_prog,
+						pm_mnt.pm_vers,
+						retry_timeout,
+						&msock);
 			if (mclient)
 				break;
 			mount_server_addr.sin_port = htons(pm_mnt.pm_port);
 			msock = RPC_ANYSOCK;
 		case IPPROTO_TCP:
 			mclient = clnttcp_create(&mount_server_addr,
-						 pm_mnt.pm_prog,
-						 pm_mnt.pm_vers,
-						 &msock, 0, 0);
+						pm_mnt.pm_prog,
+						pm_mnt.pm_vers,
+						&msock, 0, 0);
 			break;
 		default:
 			mclient = NULL;
@@ -1541,18 +1562,18 @@
 
 			if (pm_mnt.pm_vers == 3)
 				clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
-					      (xdrproc_t) xdr_dirpath,
-					      (caddr_t) &pathname,
-					      (xdrproc_t) xdr_mountres3,
-					      (caddr_t) &status,
-					      total_timeout);
+						(xdrproc_t) xdr_dirpath,
+						(caddr_t) &pathname,
+						(xdrproc_t) xdr_mountres3,
+						(caddr_t) &status,
+						total_timeout);
 			else
 				clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
-					      (xdrproc_t) xdr_dirpath,
-					      (caddr_t) &pathname,
-					      (xdrproc_t) xdr_fhstatus,
-					      (caddr_t) &status,
-					      total_timeout);
+						(xdrproc_t) xdr_dirpath,
+						(caddr_t) &pathname,
+						(xdrproc_t) xdr_fhstatus,
+						(caddr_t) &status,
+						total_timeout);
 
 			if (clnt_stat == RPC_SUCCESS)
 				goto prepare_kernel_data; /* we're done */
@@ -1711,7 +1732,7 @@
  * For older kernels, you must build busybox with ENABLE_FEATURE_MOUNT_NFS.
  * (However, note that then you lose any chances that NFS over IPv6 would work).
  */
-static int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
+static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
 {
 	len_and_sockaddr *lsa;
 	char *opts;
@@ -1753,7 +1774,7 @@
 static int singlemount(struct mntent *mp, int ignore_busy)
 {
 	int rc = -1;
-	long vfsflags;
+	unsigned long vfsflags;
 	char *loopFile = NULL, *filteropts = NULL;
 	llist_t *fl = NULL;
 	struct stat st;
@@ -1803,17 +1824,44 @@
 	) {
 		int len;
 		char c;
+		char *hostname, *share;
+		char *dotted, *ip;
 		len_and_sockaddr *lsa;
-		char *hostname, *dotted, *ip;
+
+		// Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]"
 
 		hostname = mp->mnt_fsname + 2;
 		len = strcspn(hostname, "/\\");
-		if (len == 0 || hostname[len] == '\0')
+		share = hostname + len + 1;
+		if (len == 0          // 3rd char is a [back]slash (IOW: empty hostname)
+		 || share[-1] == '\0' // no [back]slash after hostname
+		 || share[0] == '\0'  // empty share name
+		) {
 			goto report_error;
-		c = hostname[len];
-		hostname[len] = '\0';
+		}
+		c = share[-1];
+		share[-1] = '\0';
+		len = strcspn(share, "/\\");
+
+		// "unc=\\hostname\share" option is mandatory
+		// after CIFS option parsing was rewritten in Linux 3.4.
+		// Must use backslashes.
+		// If /dir1/dir2 is present, also add "prefixpath=dir1/dir2"
+		{
+			char *unc = xasprintf(
+				share[len] != '\0'  /* "/dir1/dir2" exists? */
+					? "unc=\\\\%s\\%.*s,prefixpath=%s"
+					: "unc=\\\\%s\\%.*s",
+				hostname,
+				len, share,
+				share + len + 1  /* "dir1/dir2" */
+			);
+ 			parse_mount_options(unc, &filteropts);
+ 			if (ENABLE_FEATURE_CLEAN_UP) free(unc);
+		}
+
 		lsa = host2sockaddr(hostname, 0);
-		hostname[len] = c;
+		share[-1] = c;
 		if (!lsa)
 			goto report_error;
 
@@ -1825,8 +1873,6 @@
 		parse_mount_options(ip, &filteropts);
 		if (ENABLE_FEATURE_CLEAN_UP) free(ip);
 
-		// "-o mand" is required [why?]
-		vfsflags |= MS_MANDLOCK;
 		mp->mnt_type = (char*)"cifs";
 		rc = mount_it_now(mp, vfsflags, filteropts);
 
@@ -1854,7 +1900,7 @@
 		if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) {
 			loopFile = bb_simplify_path(mp->mnt_fsname);
 			mp->mnt_fsname = NULL; // will receive malloced loop dev name
-			if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) {
+			if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) {
 				if (errno == EPERM || errno == EACCES)
 					bb_error_msg("%s", bb_msg_perm_denied_are_you_root);
 				else
@@ -1992,6 +2038,7 @@
 	FILE *fstab;
 	int i, j;
 	int rc = EXIT_SUCCESS;
+	unsigned long cmdopt_flags;
 	unsigned opt;
 	struct mntent mtpair[2], *mtcur = mtpair;
 	IF_NOT_DESKTOP(const int nonroot = 0;)
@@ -2066,16 +2113,16 @@
 	// Past this point, we are handling either "mount -a [opts]"
 	// or "mount [opts] single_param"
 
-	i = parse_mount_options(cmdopts, NULL); // FIXME: should be "long", not "int"
-	if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
+	cmdopt_flags = parse_mount_options(cmdopts, NULL);
+	if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags
 		bb_error_msg_and_die("%s", bb_msg_you_must_be_root);
 
 	// If we have a shared subtree flag, don't worry about fstab or mtab.
 	if (ENABLE_FEATURE_MOUNT_FLAGS
-	 && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
+	 && (cmdopt_flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
 	) {
 		// verbose_mount(source, target, type, flags, data)
-		rc = verbose_mount("", argv[0], "", i, "");
+		rc = verbose_mount("", argv[0], "", cmdopt_flags, "");
 		if (rc)
 			bb_simple_perror_msg_and_die(argv[0]);
 		return rc;
@@ -2083,7 +2130,7 @@
 
 	// Open either fstab or mtab
 	fstabname = "/etc/fstab";
-	if (i & MS_REMOUNT) {
+	if (cmdopt_flags & MS_REMOUNT) {
 		// WARNING. I am not sure this matches util-linux's
 		// behavior. It's possible util-linux does not
 		// take -o opts from mtab (takes only mount source).
@@ -2182,7 +2229,7 @@
 	// End of fstab/mtab is reached.
 	// Were we looking for something specific?
 	if (argv[0]) { // yes
-		long l;
+		unsigned long l;
 
 		// If we didn't find anything, complain
 		if (!mtcur->mnt_fsname)
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index 1f36d8f..6e35cd5 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -1,7 +1,7 @@
 /* vi: set sw=4 ts=4: */
 /*
  * The Rdate command will ask a time server for the RFC 868 time
- *  and optionally set the system time.
+ * and optionally set the system time.
  *
  * by Sterling Huxley <sterling@europa.com>
  *
@@ -11,9 +11,9 @@
 //usage:#define rdate_trivial_usage
 //usage:       "[-sp] HOST"
 //usage:#define rdate_full_usage "\n\n"
-//usage:       "Get and possibly set the system date and time from a remote HOST\n"
-//usage:     "\n	-s	Set the system date and time (default)"
-//usage:     "\n	-p	Print the date and time"
+//usage:       "Get and possibly set the system date/time from a remote HOST\n"
+//usage:     "\n	-s	Set the system date/time (default)"
+//usage:     "\n	-p	Print the date/time"
 
 #include "libbb.h"
 
@@ -35,15 +35,16 @@
 
 	fd = create_and_connect_stream_or_die(host, bb_lookup_port("time", "tcp", 37));
 
-	if (safe_read(fd, (void *)&nett, 4) != 4)    /* read time from server */
+	if (safe_read(fd, &nett, 4) != 4)    /* read time from server */
 		bb_error_msg_and_die("%s did not send the complete time", host);
-	close(fd);
+	if (ENABLE_FEATURE_CLEAN_UP)
+		close(fd);
 
-	/* convert from network byte order to local byte order.
+	/* Convert from network byte order to local byte order.
 	 * RFC 868 time is the number of seconds
 	 * since 00:00 (midnight) 1 January 1900 GMT
 	 * the RFC 868 time 2,208,988,800 corresponds to 00:00  1 Jan 1970 GMT
-	 * Subtract the RFC 868 time to get Linux epoch
+	 * Subtract the RFC 868 time to get Linux epoch.
 	 */
 
 	return ntohl(nett) - RFC_868_BIAS;
@@ -53,14 +54,14 @@
 int rdate_main(int argc UNUSED_PARAM, char **argv)
 {
 	time_t remote_time;
-	unsigned long flags;
+	unsigned flags;
 
 	opt_complementary = "-1";
 	flags = getopt32(argv, "sp");
 
 	remote_time = askremotedate(argv[optind]);
 
-	if ((flags & 2) == 0) {
+	if (!(flags & 2)) { /* no -p (-s may be present) */
 		time_t current_time;
 
 		time(&current_time);
@@ -71,7 +72,7 @@
 				bb_perror_msg_and_die("can't set time of day");
 	}
 
-	if ((flags & 1) == 0)
+	if (flags != 1) /* not lone -s */
 		printf("%s", ctime(&remote_time));
 
 	return EXIT_SUCCESS;
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c
index 4ed8011..974fe89 100644
--- a/util-linux/readprofile.c
+++ b/util-linux/readprofile.c
@@ -163,7 +163,7 @@
 	while (fgets(mapline, S_LEN, map)) {
 		if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3)
 			bb_error_msg_and_die("%s(%i): wrong map line",
-					     mapFile, maplineno);
+					mapFile, maplineno);
 
 		if (!strcmp(fn_name, "_stext")) /* only elf works like this */ {
 			add0 = fn_add;
@@ -198,7 +198,7 @@
 
 		if (indx >= len / sizeof(*buf))
 			bb_error_msg_and_die("profile address out of range. "
-					     "Wrong map file?");
+					"Wrong map file?");
 
 		while (indx < (next_add-add0)/step) {
 			if (optBins && (buf[indx] || optAll)) {
@@ -220,10 +220,10 @@
 		) {
 			if (optVerbose)
 				printf("%016llx %-40s %6i %8.4f\n", fn_add,
-				       fn_name, this, this/(double)fn_len);
+					fn_name, this, this/(double)fn_len);
 			else
 				printf("%6i %-40s %8.4f\n",
-				       this, fn_name, this/(double)fn_len);
+					this, fn_name, this/(double)fn_len);
 			if (optSub) {
 				unsigned long long scan;
 
@@ -233,8 +233,8 @@
 
 					addr = (scan - 1)*step + add0;
 					printf("\t%#llx\t%s+%#llx\t%u\n",
-					       addr, fn_name, addr - fn_add,
-					       buf[scan]);
+						addr, fn_name, addr - fn_add,
+						buf[scan]);
 				}
 			}
 		}
@@ -251,10 +251,10 @@
 	/* trailer */
 	if (optVerbose)
 		printf("%016x %-40s %6i %8.4f\n",
-		       0, "total", total, total/(double)(fn_add-add0));
+			0, "total", total, total/(double)(fn_add-add0));
 	else
 		printf("%6i %-40s %8.4f\n",
-		       total, "total", total/(double)(fn_add-add0));
+			total, "total", total/(double)(fn_add-add0));
 
 	fclose(map);
 	free(buf);
diff --git a/util-linux/volume_id/Kbuild.src b/util-linux/volume_id/Kbuild.src
index 70da654..759fdaa 100644
--- a/util-linux/volume_id/Kbuild.src
+++ b/util-linux/volume_id/Kbuild.src
@@ -31,7 +31,9 @@
 ### lib-$(CONFIG_FEATURE_VOLUMEID_LVM)              += lvm.o
 ### lib-$(CONFIG_FEATURE_VOLUMEID_MAC)              += mac.o
 ### lib-$(CONFIG_FEATURE_VOLUMEID_MSDOS)            += msdos.o
+lib-$(CONFIG_FEATURE_VOLUMEID_NILFS)            += nilfs.o
 lib-$(CONFIG_FEATURE_VOLUMEID_NTFS)             += ntfs.o
+lib-$(CONFIG_FEATURE_VOLUMEID_EXFAT)            += exfat.o
 lib-$(CONFIG_FEATURE_VOLUMEID_REISERFS)         += reiserfs.o
 lib-$(CONFIG_FEATURE_VOLUMEID_UDF)              += udf.o
 ### lib-$(CONFIG_FEATURE_VOLUMEID_UFS)              += ufs.o
diff --git a/util-linux/volume_id/btrfs.c b/util-linux/volume_id/btrfs.c
index 777b809..ee71d2e 100644
--- a/util-linux/volume_id/btrfs.c
+++ b/util-linux/volume_id/btrfs.c
@@ -102,6 +102,7 @@
 	// N.B.: btrfs natively supports 256 (>VOLUME_ID_LABEL_SIZE) size labels
 	volume_id_set_label_string(id, sb->label, VOLUME_ID_LABEL_SIZE);
 	volume_id_set_uuid(id, sb->fsid, UUID_DCE);
+	IF_FEATURE_BLKID_TYPE(id->type = "btrfs";)
 
 	return 0;
 }
diff --git a/util-linux/volume_id/exfat.c b/util-linux/volume_id/exfat.c
new file mode 100644
index 0000000..a38a891
--- /dev/null
+++ b/util-linux/volume_id/exfat.c
@@ -0,0 +1,130 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ *	This library is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU Lesser General Public
+ *	License as published by the Free Software Foundation; either
+ *	version 2.1 of the License, or (at your option) any later version.
+ *
+ *	This library is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *	Lesser General Public License for more details.
+ *
+ *	You should have received a copy of the GNU Lesser General Public
+ *	License along with this library; if not, write to the Free Software
+ *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "volume_id_internal.h"
+
+#define EXFAT_SB_OFFSET		0
+#define EXFAT_DIR_ENTRY_SZ	32
+#define EXFAT_MAX_DIR_ENTRIES	100
+
+struct exfat_super_block {
+/* 0x00 */	uint8_t		boot_jump[3];
+/* 0x03 */	uint8_t		fs_name[8];
+/* 0x0B */	uint8_t		must_be_zero[53];
+/* 0x40 */	uint64_t	partition_offset;
+/* 0x48 */	uint64_t	volume_length;
+/* 0x50 */	uint32_t	fat_offset;		// Sector address of 1st FAT
+/* 0x54 */	uint32_t	fat_size;		// In sectors
+/* 0x58 */	uint32_t	cluster_heap_offset;	// Sector address of Data Region
+/* 0x5C */	uint32_t	cluster_count;
+/* 0x60 */	uint32_t	root_dir;		// Cluster address of Root Directory
+/* 0x64 */	uint8_t		vol_serial_nr[4];	// Volume ID
+/* 0x68 */	uint16_t	fs_revision;		// VV.MM
+/* 0x6A */	uint16_t	vol_flags;
+/* 0x6C */	uint8_t		bytes_per_sector;	// Power of 2: 9 => 512, 12 => 4096
+/* 0x6D */	uint8_t		sectors_per_cluster;	// Power of 2
+/* 0x6E */	uint8_t		nr_of_fats;		// 2 for TexFAT
+/* 0x6F */	// ...
+} PACKED;
+
+struct exfat_dir_entry {
+/* 0x00 */	uint8_t		entry_type;
+		union {
+			struct volume_label {
+/* 0x01 */			uint8_t		char_count;		// Length of label
+/* 0x02 */			uint16_t	vol_label[11];		// UTF16 string without null termination
+/* 0x18 */			uint8_t		reserved[8];
+/* 0x20 */		} PACKED label;
+			struct volume_guid {
+/* 0x01 */			uint8_t		sec_count;
+/* 0x02 */			uint16_t	set_checksum;
+/* 0x04 */			uint16_t	flags;
+/* 0x06 */			uint8_t		vol_guid[16];
+/* 0x16 */			uint8_t		reserved[10];
+/* 0x20 */		} PACKED guid;
+		} PACKED type;
+} PACKED;
+
+int FAST_FUNC volume_id_probe_exfat(struct volume_id *id /*,uint64_t off*/)
+{
+	struct exfat_super_block *sb;
+	struct exfat_dir_entry *de;
+	unsigned	sector_sz;
+	unsigned	cluster_sz;
+	uint64_t	root_dir_off;
+	unsigned	count;
+	unsigned	need_lbl_guid;
+
+	// Primary super block
+	dbg("exFAT: probing at offset 0x%x", EXFAT_SB_OFFSET);
+	sb = volume_id_get_buffer(id, EXFAT_SB_OFFSET, sizeof(*sb));
+
+	if (!sb)
+		return -1;
+
+	if (memcmp(sb->fs_name, "EXFAT   ", 8) != 0)
+		return -1;
+
+	sector_sz = 1 << sb->bytes_per_sector;
+	cluster_sz = sector_sz << sb->sectors_per_cluster;
+	// There are no clusters 0 and 1, so the first cluster is 2.
+	root_dir_off = (uint64_t)EXFAT_SB_OFFSET +
+		// Hmm... should we cast sector_sz/cluster_sz to uint64_t?
+		(le32_to_cpu(sb->cluster_heap_offset)) * sector_sz +
+		(le32_to_cpu(sb->root_dir) - 2) * cluster_sz;
+	dbg("exFAT: sector size 0x%x bytes", sector_sz);
+	dbg("exFAT: cluster size 0x%x bytes", cluster_sz);
+	dbg("exFAT: root dir is at 0x%llx", (long long)root_dir_off);
+
+	// Use DOS uuid as fallback, if no GUID set
+	volume_id_set_uuid(id, sb->vol_serial_nr, UUID_DOS);
+
+	// EXFAT_MAX_DIR_ENTRIES is used as a safety belt.
+	// The Root Directory may hold an unlimited number of entries,
+	// so we do not want to check all. Usually label and GUID
+	// are in the beginning, but there are no guarantees.
+	need_lbl_guid = (1 << 0) | (1 << 1);
+	for (count = 0; count < EXFAT_MAX_DIR_ENTRIES; count++) {
+		de = volume_id_get_buffer(id, root_dir_off + (count * EXFAT_DIR_ENTRY_SZ), EXFAT_DIR_ENTRY_SZ);
+		if (de == NULL)
+			break;
+		if (de->entry_type == 0x00) {
+			// End of Directory Marker
+			dbg("exFAT: End of root directory reached after %u entries", count);
+			break;
+		}
+		if (de->entry_type == 0x83) {
+			// Volume Label Directory Entry
+			volume_id_set_label_unicode16(id, (uint8_t *)de->type.label.vol_label,
+						LE, 2 * de->type.label.char_count);
+			need_lbl_guid &= ~(1 << 0);
+		}
+		if (de->entry_type == 0xA0) {
+			// Volume GUID Directory Entry
+			volume_id_set_uuid(id, de->type.guid.vol_guid, UUID_DCE);
+			need_lbl_guid &= ~(1 << 1);
+		}
+		if (!need_lbl_guid)
+			break;
+	}
+
+	IF_FEATURE_BLKID_TYPE(id->type = "exfat";)
+	return 0;
+}
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c
index 230102d..665cb9b 100644
--- a/util-linux/volume_id/get_devname.c
+++ b/util-linux/volume_id/get_devname.c
@@ -49,7 +49,11 @@
 	if (volume_id_probe_all(vid, /*0,*/ size) != 0)
 		goto ret;
 
-	if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
+	if (vid->label[0] != '\0' || vid->uuid[0] != '\0'
+#if ENABLE_FEATURE_BLKID_TYPE
+	 || vid->type != NULL
+#endif
+	) {
 		*label = xstrndup(vid->label, sizeof(vid->label));
 		*uuid  = xstrndup(vid->uuid, sizeof(vid->uuid));
 #if ENABLE_FEATURE_BLKID_TYPE
diff --git a/util-linux/volume_id/hfs.c b/util-linux/volume_id/hfs.c
index f3f19db..3d9704d 100644
--- a/util-linux/volume_id/hfs.c
+++ b/util-linux/volume_id/hfs.c
@@ -131,6 +131,27 @@
 #define HFS_NODE_LEAF			0xff
 #define HFSPLUS_POR_CNID		1
 
+static void FAST_FUNC hfs_set_uuid(struct volume_id *id, const uint8_t *hfs_id)
+{
+#define hfs_id_len 8
+	md5_ctx_t md5c;
+	uint8_t uuid[16];
+	unsigned i;
+
+	for (i = 0; i < hfs_id_len; i++)
+		if (hfs_id[i] != 0)
+			goto do_md5;
+	return;
+ do_md5:
+	md5_begin(&md5c);
+	md5_hash(&md5c, "\263\342\17\71\362\222\21\326\227\244\0\60\145\103\354\254", 16);
+	md5_hash(&md5c, hfs_id, hfs_id_len);
+	md5_end(&md5c, uuid);
+	uuid[6] = 0x30 | (uuid[6] & 0x0f);
+	uuid[8] = 0x80 | (uuid[8] & 0x3f);
+	volume_id_set_uuid(id, uuid, UUID_DCE);
+}
+
 int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/)
 {
 	uint64_t off = 0;
@@ -193,7 +214,7 @@
 		volume_id_set_label_string(id, hfs->label, hfs->label_len) ;
 	}
 
-	volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS);
+	hfs_set_uuid(id, hfs->finder_info.id);
 //	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
 	IF_FEATURE_BLKID_TYPE(id->type = "hfs";)
 
@@ -207,7 +228,7 @@
 	return -1;
 
  hfsplus:
-	volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS);
+	hfs_set_uuid(id, hfsplus->finder_info.id);
 
 	blocksize = be32_to_cpu(hfsplus->blocksize);
 	dbg("blocksize %u", blocksize);
@@ -286,7 +307,7 @@
 
  found:
 //	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
-//	id->type = "hfsplus";
+	IF_FEATURE_BLKID_TYPE(id->type = "hfsplus";)
 
 	return 0;
 }
diff --git a/util-linux/volume_id/linux_raid.c b/util-linux/volume_id/linux_raid.c
index 761e54f..209eaab 100644
--- a/util-linux/volume_id/linux_raid.c
+++ b/util-linux/volume_id/linux_raid.c
@@ -69,9 +69,9 @@
 	volume_id_set_uuid(id, uuid, UUID_DCE);
 
 //	snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u",
-//		 le32_to_cpu(mdp->major_version),
-//		 le32_to_cpu(mdp->minor_version),
-//		 le32_to_cpu(mdp->patch_version));
+//		le32_to_cpu(mdp->major_version),
+//		le32_to_cpu(mdp->minor_version),
+//		le32_to_cpu(mdp->patch_version));
 
 	dbg("found raid signature");
 //	volume_id_set_usage(id, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/nilfs.c b/util-linux/volume_id/nilfs.c
new file mode 100644
index 0000000..b88a9e4
--- /dev/null
+++ b/util-linux/volume_id/nilfs.c
@@ -0,0 +1,96 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ *	This library is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU Lesser General Public
+ *	License as published by the Free Software Foundation; either
+ *	version 2.1 of the License, or (at your option) any later version.
+ *
+ *	This library is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *	Lesser General Public License for more details.
+ *
+ *	You should have received a copy of the GNU Lesser General Public
+ *	License along with this library; if not, write to the Free Software
+ *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "volume_id_internal.h"
+
+#define NILFS_UUID_SIZE 16
+#define NILFS_LABEL_SIZE 80
+#define NILFS_SB1_OFFSET 0x400
+#define NILFS_SB2_OFFSET 0x1000
+#define NILFS_MAGIC 0x3434
+
+struct nilfs2_super_block {
+/* 0x00 */	uint32_t s_rev_level;				// Major revision level.
+/* 0x04 */	uint16_t s_minor_rev_level;			// Minor revision level.
+/* 0x06 */	uint16_t s_magic;				// Magic signature.
+/* 0x08 */	uint16_t s_bytes;
+/* 0x0A */	uint16_t s_flags;
+/* 0x0C */	uint32_t s_crc_seed;
+/* 0x10 */	uint32_t s_sum;
+/* 0x14 */	uint32_t s_log_block_size;
+/* 0x18 */	uint64_t s_nsegments;
+/* 0x20 */	uint64_t s_dev_size;				// Block device size in bytes.
+/* 0x28 */	uint64_t s_first_data_block;
+/* 0x30 */	uint32_t s_blocks_per_segment;
+/* 0x34 */	uint32_t s_r_segments_percentage;
+/* 0x38 */	uint64_t s_last_cno;
+/* 0x40 */	uint64_t s_last_pseg;
+/* 0x48 */	uint64_t s_last_seq;
+/* 0x50 */	uint64_t s_free_blocks_count;
+/* 0x58 */	uint64_t s_ctime;
+/* 0x60 */	uint64_t s_mtime;
+/* 0x68 */	uint64_t s_wtime;
+/* 0x70 */	uint16_t s_mnt_count;
+/* 0x72 */	uint16_t s_max_mnt_count;
+/* 0x74 */	uint16_t s_state;
+/* 0x76 */	uint16_t s_errors;
+/* 0x78 */	uint64_t s_lastcheck;
+/* 0x80 */	uint32_t s_checkinterval;
+/* 0x84 */	uint32_t s_creator_os;
+/* 0x88 */	uint16_t s_def_resuid;
+/* 0x8A */	uint16_t s_def_resgid;
+/* 0x8C */	uint32_t s_first_ino;
+/* 0x90 */	uint16_t s_inode_size;
+/* 0x92 */	uint16_t s_dat_entry_size;
+/* 0x94 */	uint16_t s_checkpoint_size;
+/* 0x96 */	uint16_t s_segment_usage_size;
+/* 0x98 */	uint8_t s_uuid[NILFS_UUID_SIZE];		// 128-bit UUID for volume.
+/* 0xA8 */	uint8_t s_volume_name[NILFS_LABEL_SIZE];	// Volume label.
+/* 0xF8 */	// ...
+} PACKED;
+
+int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/)
+{
+	struct nilfs2_super_block *sb;
+
+	// Primary super block
+	dbg("nilfs: probing at offset 0x%x", NILFS_SB1_OFFSET);
+
+	sb = volume_id_get_buffer(id, NILFS_SB1_OFFSET, sizeof(*sb));
+
+	if (sb == NULL)
+		return -1;
+
+	if (sb->s_magic != NILFS_MAGIC)
+		return -1;
+
+	// The secondary superblock is not always used, so ignore it for now.
+	// When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET).
+
+	volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ?
+				NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE);
+	volume_id_set_uuid(id, sb->s_uuid, UUID_DCE);
+
+	if (sb->s_rev_level == 2)
+		IF_FEATURE_BLKID_TYPE(id->type = "nilfs2");
+
+	return 0;
+}
diff --git a/util-linux/volume_id/ntfs.c b/util-linux/volume_id/ntfs.c
index 547f141..7b2612f 100644
--- a/util-linux/volume_id/ntfs.c
+++ b/util-linux/volume_id/ntfs.c
@@ -132,7 +132,7 @@
 	dbg("mft record size  %i", mft_record_size);
 
 	buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size),
-			 mft_record_size);
+			mft_record_size);
 	if (buf == NULL)
 		goto found;
 
@@ -165,7 +165,7 @@
 			break;
 
 		dbg("found attribute type 0x%x, len %i, at offset %i",
-		    attr_type, attr_len, attr_off);
+			attr_type, attr_len, attr_off);
 
 //		if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) {
 //			struct volume_info *info;
diff --git a/util-linux/volume_id/squashfs.c b/util-linux/volume_id/squashfs.c
new file mode 100644
index 0000000..c5b4f9c
--- /dev/null
+++ b/util-linux/volume_id/squashfs.c
@@ -0,0 +1,49 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o
+
+#include "volume_id_internal.h"
+
+struct squashfs_superblock {
+	uint32_t	magic;
+/*
+	uint32_t	dummy[6];
+	uint16_t        major;
+	uint16_t        minor;
+*/
+} PACKED;
+
+int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/)
+{
+#define off ((uint64_t)0)
+	struct squashfs_superblock *sb;
+
+	dbg("SquashFS: probing at offset 0x%llx", (unsigned long long) off);
+	sb = volume_id_get_buffer(id, off, 0x200);
+	if (!sb)
+		return -1;
+
+	// Old SquashFS (pre 4.0) can be both big and little endian, so test for both.
+	// Likewise, it is commonly used in firwmare with some non-standard signatures.
+#define pack(a,b,c,d) ( (uint32_t)((a * 256 + b) * 256 + c) * 256 + d )
+#define SIG1 pack('s','q','s','h')
+#define SIG2 pack('h','s','q','s')
+#define SIG3 pack('s','h','s','q')
+#define SIG4 pack('q','s','h','s')
+	if (sb->magic == SIG1
+	 || sb->magic == SIG2
+	 || sb->magic == SIG3
+	 || sb->magic == SIG4
+	) {
+		IF_FEATURE_BLKID_TYPE(id->type = "squashfs";)
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c
index cd63c8d..d3747fb 100644
--- a/util-linux/volume_id/udf.c
+++ b/util-linux/volume_id/udf.c
@@ -109,7 +109,7 @@
 			return -1;
 
 		dbg("vsd: %c%c%c%c%c",
-		    vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
+			vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
 
 		if (vsd->id[0] == '\0')
 			return -1;
diff --git a/util-linux/volume_id/unused_msdos.c b/util-linux/volume_id/unused_msdos.c
index 65fb885..2e8cb19 100644
--- a/util-linux/volume_id/unused_msdos.c
+++ b/util-linux/volume_id/unused_msdos.c
@@ -109,7 +109,7 @@
 				extended = off + poff;
 		} else {
 			dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
-			    part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
+				part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
 
 //			if (is_raid(part[i].sys_ind))
 //				volume_id_set_usage_part(p, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/unused_silicon_raid.c b/util-linux/volume_id/unused_silicon_raid.c
index d1c439e..878b881 100644
--- a/util-linux/volume_id/unused_silicon_raid.c
+++ b/util-linux/volume_id/unused_silicon_raid.c
@@ -62,7 +62,7 @@
 
 //	volume_id_set_usage(id, VOLUME_ID_RAID);
 //	snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u",
-//		 le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver));
+//		le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver));
 //	id->type = "silicon_medley_raid_member";
 
 	return 0;
diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c
index 11e2c00..9da5076 100644
--- a/util-linux/volume_id/util.c
+++ b/util-linux/volume_id/util.c
@@ -31,25 +31,29 @@
 			c = (buf[i+1] << 8) | buf[i];
 		else
 			c = (buf[i] << 8) | buf[i+1];
-		if (c == 0) {
-			str[j] = '\0';
+		if (c == 0)
 			break;
-		} else if (c < 0x80) {
-			if (j+1 >= len)
-				break;
-			str[j++] = (uint8_t) c;
-		} else if (c < 0x800) {
+		if (j+1 >= len)
+			break;
+		if (c < 0x80) {
+			/* 0xxxxxxx */
+		} else {
+			uint8_t topbits = 0xc0;
 			if (j+2 >= len)
 				break;
-			str[j++] = (uint8_t) (0xc0 | (c >> 6));
-			str[j++] = (uint8_t) (0x80 | (c & 0x3f));
-		} else {
-			if (j+3 >= len)
-				break;
-			str[j++] = (uint8_t) (0xe0 | (c >> 12));
-			str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
-			str[j++] = (uint8_t) (0x80 | (c & 0x3f));
+			if (c < 0x800) {
+				/* 110yyyxx 10xxxxxx */
+			} else {
+				if (j+3 >= len)
+					break;
+				/* 1110yyyy 10yyyyxx 10xxxxxx */
+				str[j++] = (uint8_t) (0xe0 | (c >> 12));
+				topbits = 0x80;
+			}
+			str[j++] = (uint8_t) (topbits | ((c >> 6) & 0x3f));
+			c = 0x80 | (c & 0x3f);
 		}
+		str[j++] = (uint8_t) c;
 	}
 	str[j] = '\0';
 }
@@ -125,30 +129,14 @@
 
 void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count)
 {
-	 volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
+	volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
 }
 
 void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format)
 {
 	unsigned i;
-	unsigned count = 0;
+	unsigned count = (format == UUID_DCE_STRING ? VOLUME_ID_UUID_SIZE : 4 << format);
 
-	switch (format) {
-	case UUID_DOS:
-		count = 4;
-		break;
-	case UUID_NTFS:
-	case UUID_HFS:
-		count = 8;
-		break;
-	case UUID_DCE:
-		count = 16;
-		break;
-	case UUID_DCE_STRING:
-		/* 36 is ok, id->uuid has one extra byte for NUL */
-		count = VOLUME_ID_UUID_SIZE;
-		break;
-	}
 //	memcpy(id->uuid_raw, buf, count);
 //	id->uuid_raw_len = count;
 
@@ -169,11 +157,6 @@
 			buf[7], buf[6], buf[5], buf[4],
 			buf[3], buf[2], buf[1], buf[0]);
 		break;
-	case UUID_HFS:
-		sprintf(id->uuid, "%02X%02X%02X%02X%02X%02X%02X%02X",
-			buf[0], buf[1], buf[2], buf[3],
-			buf[4], buf[5], buf[6], buf[7]);
-		break;
 	case UUID_DCE:
 		sprintf(id->uuid,
 			"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c
index 06d91eb..e928af5 100644
--- a/util-linux/volume_id/volume_id.c
+++ b/util-linux/volume_id/volume_id.c
@@ -93,9 +93,15 @@
 #if ENABLE_FEATURE_VOLUMEID_FAT
 	volume_id_probe_vfat,
 #endif
+#if ENABLE_FEATURE_VOLUMEID_EXFAT
+	volume_id_probe_exfat,
+#endif
 #if ENABLE_FEATURE_VOLUMEID_MAC
 	volume_id_probe_mac_partition_map,
 #endif
+#if ENABLE_FEATURE_VOLUMEID_SQUASHFS
+	volume_id_probe_squashfs,
+#endif
 #if ENABLE_FEATURE_VOLUMEID_XFS
 	volume_id_probe_xfs,
 #endif
@@ -130,6 +136,9 @@
 #if ENABLE_FEATURE_VOLUMEID_UFS
 	volume_id_probe_ufs,
 #endif
+#if ENABLE_FEATURE_VOLUMEID_NILFS
+	volume_id_probe_nilfs,
+#endif
 #if ENABLE_FEATURE_VOLUMEID_NTFS
 	volume_id_probe_ntfs,
 #endif
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h
index 1c64046..3f02bd5 100644
--- a/util-linux/volume_id/volume_id_internal.h
+++ b/util-linux/volume_id/volume_id_internal.h
@@ -136,12 +136,15 @@
 #define cpu_to_be32(x) (x)
 #endif
 
+/* volume_id_set_uuid(id,buf,fmt) assumes size of uuid buf
+ * by shifting: 4 << fmt, except for fmt == UUID_DCE_STRING.
+ * The constants below should match sizes.
+ */
 enum uuid_format {
-	UUID_DCE_STRING,
-	UUID_DCE,
-	UUID_DOS,
-	UUID_NTFS,
-	UUID_HFS,
+	UUID_DOS = 0,		/* 4 bytes */
+	UUID_NTFS = 1,		/* 8 bytes */
+	UUID_DCE = 2,		/* 16 bytes */
+	UUID_DCE_STRING = 3,	/* 36 bytes (VOLUME_ID_UUID_SIZE) */
 };
 
 enum endian {
@@ -212,14 +215,20 @@
 
 //int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id /*,uint64_t off*/);
 
+int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/);
+
 int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/);
 
+int FAST_FUNC volume_id_probe_exfat(struct volume_id *id /*,uint64_t off*/);
+
 int FAST_FUNC volume_id_probe_ocfs2(struct volume_id *id /*,uint64_t off*/);
 
 int FAST_FUNC volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/);
 
 int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/);
 
+int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/);
+
 int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/);
 
 int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/);