

Patch from Andries.Brouwer@cwi.nl

Below some random patch, not to be applied, so that people can play with a
32-bit dev_t.

Nothing here is hewn in stone.  By some coincidence the division below is
16+16, but a simple edit turns that into 12+20 or 32+32.  Elsewhere there are
no (well, there still are a few, but they will be eliminated), there are no
assumptions on the sizes involved.

A major and a minor are unsigned ints of unknown size.

Of course not all filesystems can handle all sizes.

[I still see a B_FREE here - had removed that earlier, but perhaps the patch
was not applied.  There is another occurrence in video/pm3fb.h that can be
removed, and one in video/pm3fb.c that should become NODEV.  Will find this
patch again.]



 include/asm-i386/posix_types.h |    2 -
 include/linux/kdev_t.h         |   58 +++++++++++++++++++++++++++++++----------
 include/linux/root_dev.h       |   20 +++++++-------
 3 files changed, 55 insertions(+), 25 deletions(-)

diff -puN include/asm-i386/posix_types.h~dev_t-32-bit include/asm-i386/posix_types.h
--- 25/include/asm-i386/posix_types.h~dev_t-32-bit	2003-04-12 00:30:36.000000000 -0700
+++ 25-akpm/include/asm-i386/posix_types.h	2003-04-12 00:30:36.000000000 -0700
@@ -7,7 +7,7 @@
  * assume GCC is being used.
  */
 
-typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_dev_t;
 typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
 typedef unsigned short	__kernel_nlink_t;
diff -puN include/linux/kdev_t.h~dev_t-32-bit include/linux/kdev_t.h
--- 25/include/linux/kdev_t.h~dev_t-32-bit	2003-04-12 00:30:36.000000000 -0700
+++ 25-akpm/include/linux/kdev_t.h	2003-04-12 00:46:39.000000000 -0700
@@ -70,13 +70,13 @@ aeb - 950811
  * static arrays, and they are sized for a 8-bit index.
  */
 typedef struct {
-	unsigned short value;
+	unsigned int value;
 } kdev_t;
 
-#define KDEV_MINOR_BITS		8
-#define KDEV_MAJOR_BITS		8
+#define KDEV_MINOR_BITS		16
+#define KDEV_MAJOR_BITS		16
 
-#define __mkdev(major,minor)	(((major) << KDEV_MINOR_BITS) + (minor))
+#define __mkdev(major, minor)	(((major) << KDEV_MINOR_BITS) + (minor))
 
 #define mk_kdev(major, minor)	((kdev_t) { __mkdev(major,minor) } )
 
@@ -99,7 +99,6 @@ static inline kdev_t val_to_kdev(unsigne
 
 #define HASHDEV(dev)	(kdev_val(dev))
 #define NODEV		(mk_kdev(0,0))
-#define B_FREE		(mk_kdev(0xff,0xff))
 
 static inline int kdev_same(kdev_t dev1, kdev_t dev2)
 {
@@ -108,17 +107,44 @@ static inline int kdev_same(kdev_t dev1,
 
 #define kdev_none(d1)	(!kdev_val(d1))
 
-/* Mask off the high bits for now.. */
-#define minor(dev)	((dev).value & 0xff)
-#define major(dev)	(((dev).value >> KDEV_MINOR_BITS) & 0xff)
+#define minor(dev)	((dev).value & 0xffff)
+#define major(dev)	(((dev).value >> KDEV_MINOR_BITS) & 0xffff)
 
 /* These are for user-level "dev_t" */
 #define MINORBITS	8
 #define MINORMASK	((1U << MINORBITS) - 1)
 
-#define MAJOR(dev)	((unsigned int) ((dev) >> MINORBITS))
-#define MINOR(dev)	((unsigned int) ((dev) & MINORMASK))
-#define MKDEV(ma,mi)	(((ma) << MINORBITS) | (mi))
+#include <linux/types.h>	/* dev_t */
+
+/*
+ * We use the 12 bits 20:31 for the major and the 20 bits 0:19 for the minor.
+ * If the 16 MSB's are zero then it is a "legacy" dev_t, in which case the
+ * major is in bits 8:15 and the minor in bits 0:7.
+ */
+
+static inline unsigned int MAJOR(dev_t dev)
+{
+	if (dev & 0xffff0000)
+		return (dev >> 20) & 0xfff;
+	return (dev >> 8) & 0xff;
+}
+
+static inline unsigned int MINOR(dev_t dev)
+{
+	if (dev & 0xffff0000)
+		return dev & 0xfffff;
+	return dev & 0xff;
+}
+
+static inline dev_t MKDEV(unsigned int ma, unsigned int mi)
+{
+	if ((ma & ~0xff) == 0 && (mi & ~0xff) == 0)
+		return (ma << 8) | mi;
+	return (ma << 20) | mi;
+}
+
+/* For static initialisers in root_dev.h */
+#define MK_OLD_DEV(ma, mi) (((ma) << 8) | (mi))
 
 /*
  * Conversion functions
@@ -126,12 +152,16 @@ static inline int kdev_same(kdev_t dev1,
 
 static inline int kdev_t_to_nr(kdev_t dev)
 {
-	return MKDEV(major(dev), minor(dev));
+	unsigned int ma = major(dev);
+	unsigned int mi = minor(dev);
+	return MKDEV(ma, mi);
 }
 
-static inline kdev_t to_kdev_t(int dev)
+static inline kdev_t to_kdev_t(dev_t dev)
 {
-	return mk_kdev(MAJOR(dev),MINOR(dev));
+	unsigned int ma = MAJOR(dev);
+	unsigned int mi = MINOR(dev);
+	return mk_kdev(ma, mi);
 }
 
 #else /* __KERNEL__ */
diff -puN include/linux/root_dev.h~dev_t-32-bit include/linux/root_dev.h
--- 25/include/linux/root_dev.h~dev_t-32-bit	2003-04-12 00:46:46.000000000 -0700
+++ 25-akpm/include/linux/root_dev.h	2003-04-12 00:47:17.000000000 -0700
@@ -2,16 +2,16 @@
 #define _ROOT_DEV_H_
 
 enum {
-	Root_NFS = MKDEV(UNNAMED_MAJOR, 255),
-	Root_RAM0 = MKDEV(RAMDISK_MAJOR, 0),
-	Root_RAM1 = MKDEV(RAMDISK_MAJOR, 1),
-	Root_FD0 = MKDEV(FLOPPY_MAJOR, 0),
-	Root_HDA1 = MKDEV(IDE0_MAJOR, 1),
-	Root_HDA2 = MKDEV(IDE0_MAJOR, 2),
-	Root_SDA1 = MKDEV(SCSI_DISK0_MAJOR, 1),
-	Root_SDA2 = MKDEV(SCSI_DISK0_MAJOR, 2),
-	Root_HDC1 = MKDEV(IDE1_MAJOR, 1),
-	Root_SR0 = MKDEV(SCSI_CDROM_MAJOR, 0),
+	Root_NFS = MK_OLD_DEV(UNNAMED_MAJOR, 255),
+	Root_RAM0 = MK_OLD_DEV(RAMDISK_MAJOR, 0),
+	Root_RAM1 = MK_OLD_DEV(RAMDISK_MAJOR, 1),
+	Root_FD0 = MK_OLD_DEV(FLOPPY_MAJOR, 0),
+	Root_HDA1 = MK_OLD_DEV(IDE0_MAJOR, 1),
+	Root_HDA2 = MK_OLD_DEV(IDE0_MAJOR, 2),
+	Root_SDA1 = MK_OLD_DEV(SCSI_DISK0_MAJOR, 1),
+	Root_SDA2 = MK_OLD_DEV(SCSI_DISK0_MAJOR, 2),
+	Root_HDC1 = MK_OLD_DEV(IDE1_MAJOR, 1),
+	Root_SR0 = MK_OLD_DEV(SCSI_CDROM_MAJOR, 0),
 };
 
 extern dev_t ROOT_DEV;

_
