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 /* 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; _