summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/sysirix.c34
-rw-r--r--arch/sparc64/solaris/fs.c41
-rw-r--r--drivers/s390/block/dasd_int.h3
-rw-r--r--fs/libfs.c19
-rw-r--r--fs/xfs/linux/xfs_iops.c8
-rw-r--r--fs/xfs/linux/xfs_super.c2
-rw-r--r--fs/xfs/xfs_types.h16
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/linux/kdev_t.h74
-rw-r--r--include/linux/raid/md_k.h6
-rw-r--r--include/linux/types.h2
11 files changed, 115 insertions, 93 deletions
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 0b9426f0aa9a..4e0e6c4290ba 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1187,13 +1187,7 @@ asmlinkage int irix_uname(struct iuname *buf)
#undef DEBUG_XSTAT
-static inline u32
-linux_to_irix_dev_t(dev_t t)
-{
- return MAJOR (t) << 18 | MINOR (t);
-}
-
-static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
{
struct xstat32 {
u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1206,13 +1200,15 @@ static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
u32 st_pad4[8];
} ub;
- ub.st_dev = linux_to_irix_dev_t(stat->dev);
+ if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+ ub.st_dev = sysv_encode_dev(stat->dev);
ub.st_ino = stat->ino;
ub.st_mode = stat->mode;
ub.st_nlink = stat->nlink;
SET_STAT_UID(ub, stat->uid);
SET_STAT_GID(ub, stat->gid);
- ub.st_rdev = linux_to_irix_dev_t(stat->rdev);
+ ub.st_rdev = sysv_encode_dev(stat->rdev);
#if BITS_PER_LONG == 32
if (stat->size > MAX_NON_LFS)
return -EOVERFLOW;
@@ -1231,7 +1227,7 @@ static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
}
-static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
{
struct xstat64 {
u32 st_dev; s32 st_pad1[3];
@@ -1248,14 +1244,17 @@ static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
s32 st_pad4[8];
} ks;
- ks.st_dev = linux_to_irix_dev_t(stat->dev);
+ if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+
+ ks.st_dev = sysv_encode_dev(stat->dev);
ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
ks.st_ino = (unsigned long long) stat->ino;
ks.st_mode = (u32) stat->mode;
ks.st_nlink = (u32) stat->nlink;
ks.st_uid = (s32) stat->uid;
ks.st_gid = (s32) stat->gid;
- ks.st_rdev = linux_to_irix_dev_t (stat->rdev);
+ ks.st_rdev = sysv_encode_dev (stat->rdev);
ks.st_pad2[0] = ks.st_pad2[1] = 0;
ks.st_size = (long long) stat->size;
ks.st_pad3 = 0;
@@ -1275,7 +1274,7 @@ static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
/* Now write it all back. */
- copy_to_user(ubuf, &ks, sizeof(struct xstat64));
+ return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
}
asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
@@ -1295,8 +1294,7 @@ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
retval = irix_xstat32_xlate(&stat, statbuf);
break;
case 3:
- irix_xstat64_xlate(&stat, statbuf);
- retval = 0; /* Really? */
+ retval = irix_xstat64_xlate(&stat, statbuf);
break;
default:
retval = -EINVAL;
@@ -1323,8 +1321,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
error = irix_xstat32_xlate(&stat, statbuf);
break;
case 3:
- irix_xstat64_xlate(&stat, statbuf);
- error = 0;
+ error = irix_xstat64_xlate(&stat, statbuf);
break;
default:
error = -EINVAL;
@@ -1350,8 +1347,7 @@ asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
error = irix_xstat32_xlate(&stat, statbuf);
break;
case 3:
- irix_xstat64_xlate(&stat, statbuf);
- error = 0;
+ error = irix_xstat64_xlate(&stat, statbuf);
break;
default:
error = -EINVAL;
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index f0693bfb472e..eea867e632ad 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -28,21 +28,6 @@
#include "conv.h"
-static inline u32 R4_DEV(dev_t DEV)
-{
- return MINOR(DEV) | (MAJOR(DEV) << 18);
-}
-
-static inline unsigned R4_MAJOR(u32 DEV)
-{
- return (DEV >> 18) & 0x3fff;
-}
-
-static inline unsigned R4_MINOR(u32 DEV)
-{
- return DEV & 0x3ffff;
-}
-
#define R3_VERSION 1
#define R4_VERSION 2
@@ -96,15 +81,17 @@ struct sol_stat64 {
static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
{
- if (kbuf->size > MAX_NON_LFS)
+ if (kbuf->size > MAX_NON_LFS ||
+ !sysv_valid_dev(kbuf->dev) ||
+ !sysv_valid_dev(kbuf->rdev))
return -EOVERFLOW;
- if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
+ if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
__put_user (kbuf->ino, &ubuf->st_ino) ||
__put_user (kbuf->mode, &ubuf->st_mode) ||
__put_user (kbuf->nlink, &ubuf->st_nlink) ||
__put_user (kbuf->uid, &ubuf->st_uid) ||
__put_user (kbuf->gid, &ubuf->st_gid) ||
- __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
+ __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
__put_user (kbuf->size, &ubuf->st_size) ||
__put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
__put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
@@ -121,13 +108,15 @@ static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf)
{
- if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
+ if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
+ return -EOVERFLOW;
+ if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
__put_user (kbuf->ino, &ubuf->st_ino) ||
__put_user (kbuf->mode, &ubuf->st_mode) ||
__put_user (kbuf->nlink, &ubuf->st_nlink) ||
__put_user (kbuf->uid, &ubuf->st_uid) ||
__put_user (kbuf->gid, &ubuf->st_gid) ||
- __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
+ __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
__put_user (kbuf->size, &ubuf->st_size) ||
__put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
__put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
@@ -261,8 +250,8 @@ asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
(int (*)(const char *,int,unsigned))SYS(mknod);
int major, minor;
- if ((major = R4_MAJOR(dev)) > 255 ||
- (minor = R4_MINOR(dev)) > 255) return -EINVAL;
+ if ((major = sysv_major(dev)) > 255 ||
+ (minor = sysv_minor(dev)) > 255) return -EINVAL;
return sys_mknod((const char *)A(path), mode, old_encode_dev(MKDEV(major,minor)));
}
@@ -415,6 +404,8 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
if (j > 15) j = 15;
if (IS_RDONLY(inode)) i = 1;
if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
+ if (!sysv_valid_dev(inode->i_sb->s_dev))
+ return -EOVERFLOW;
if (put_user (s.f_bsize, &ss->f_bsize) ||
__put_user (0, &ss->f_frsize) ||
__put_user (s.f_blocks, &ss->f_blocks) ||
@@ -423,7 +414,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
__put_user (s.f_files, &ss->f_files) ||
__put_user (s.f_ffree, &ss->f_ffree) ||
__put_user (s.f_ffree, &ss->f_favail) ||
- __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
+ __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
__copy_to_user (ss->f_basetype,p,j) ||
__put_user (0, (char *)&ss->f_basetype[j]) ||
__put_user (s.f_namelen, &ss->f_namemax) ||
@@ -449,6 +440,8 @@ static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
if (j > 15) j = 15;
if (IS_RDONLY(inode)) i = 1;
if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
+ if (!sysv_valid_dev(inode->i_sb->s_dev))
+ return -EOVERFLOW;
if (put_user (s.f_bsize, &ss->f_bsize) ||
__put_user (0, &ss->f_frsize) ||
__put_user (s.f_blocks, &ss->f_blocks) ||
@@ -457,7 +450,7 @@ static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
__put_user (s.f_files, &ss->f_files) ||
__put_user (s.f_ffree, &ss->f_ffree) ||
__put_user (s.f_ffree, &ss->f_favail) ||
- __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
+ __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
__copy_to_user (ss->f_basetype,p,j) ||
__put_user (0, (char *)&ss->f_basetype[j]) ||
__put_user (s.f_namelen, &ss->f_namemax) ||
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 0f2cdea8070d..9d36b632c5a9 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -14,7 +14,8 @@
#ifdef __KERNEL__
-#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
+/* we keep old device allocation scheme; IOW, minors are still in 0..255 */
+#define DASD_PER_MAJOR ( 1U<<(8-DASD_PARTN_BITS))
#define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
/*
diff --git a/fs/libfs.c b/fs/libfs.c
index fbf1d0e6e3e4..f323ac963d6d 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -429,22 +429,3 @@ void simple_release_fs(struct vfsmount **mount, int *count)
spin_unlock(&pin_fs_lock);
mntput(mnt);
}
-
-/* acceptable for old filesystems */
-int old_valid_dev(dev_t dev)
-{
- return MAJOR(dev) < 256 && MINOR(dev) < 256;
-}
-EXPORT_SYMBOL(old_valid_dev);
-
-u16 old_encode_dev(dev_t dev)
-{
- return (MAJOR(dev) << 8) | MINOR(dev);
-}
-EXPORT_SYMBOL(old_encode_dev);
-
-dev_t old_decode_dev(u16 val)
-{
- return MKDEV((val >> 8) & 255, val & 255);
-}
-EXPORT_SYMBOL(old_decode_dev);
diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
index 11c1736bf4f7..b37ac6166c20 100644
--- a/fs/xfs/linux/xfs_iops.c
+++ b/fs/xfs/linux/xfs_iops.c
@@ -113,7 +113,11 @@ linvfs_mknod(
xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS;
int error;
- if (!old_valid_dev(rdev))
+ /*
+ * Irix uses Missed'em'V split, but doesn't want to see
+ * the upper 5 bits of (14bit) major.
+ */
+ if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
return -EINVAL;
if (test_default_acl && test_default_acl(dvp)) {
@@ -135,7 +139,7 @@ linvfs_mknod(
switch (mode & S_IFMT) {
case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
- va.va_rdev = XFS_MKDEV(MAJOR(rdev), MINOR(rdev));
+ va.va_rdev = sysv_encode_dev(rdev);
va.va_mask |= XFS_AT_RDEV;
/*FALLTHROUGH*/
case S_IFREG:
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index c58952d14f6b..326dfe0553fa 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -174,7 +174,7 @@ xfs_revalidate_inode(
inode->i_rdev = 0;
} else {
xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
- inode->i_rdev = XFS_DEV_TO_DEVT(dev);
+ inode->i_rdev = MKDEV(sysv_major(dev) & 0x1ff, sysv_minor(dev));
}
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_generation = ip->i_d.di_gen;
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 59634d447545..a4cc7be2127e 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -197,20 +197,4 @@ typedef enum {
XFS_BTNUM_MAX
} xfs_btnum_t;
-
-/*
- * Juggle IRIX device numbers - still used in ondisk structures
- */
-#define XFS_DEV_BITSMAJOR 14
-#define XFS_DEV_BITSMINOR 18
-#define XFS_DEV_MAXMAJ 0x1ff
-#define XFS_DEV_MAXMIN 0x3ffff
-#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
- & XFS_DEV_MAXMAJ))
-#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN))
-#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
- | (minor&XFS_DEV_MAXMIN)))
-
-#define XFS_DEV_TO_DEVT(dev) MKDEV(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
-
#endif /* !__XFS_TYPES_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 20a7b18b0841..b3a714c094d2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1392,9 +1392,6 @@ struct tree_descr { char *name; struct file_operations *ops; int mode; };
extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count);
-extern int old_valid_dev(dev_t);
-extern u16 old_encode_dev(dev_t);
-extern dev_t old_decode_dev(u16);
extern int inode_change_ok(struct inode *, struct iattr *);
extern int inode_setattr(struct inode *, struct iattr *);
diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h
index f60508da024d..bceea527dd37 100644
--- a/include/linux/kdev_t.h
+++ b/include/linux/kdev_t.h
@@ -1,8 +1,7 @@
#ifndef _LINUX_KDEV_T_H
#define _LINUX_KDEV_T_H
#ifdef __KERNEL__
-/* These are for user-level "dev_t" */
-#define MINORBITS 8
+#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
@@ -18,6 +17,77 @@
buffer; \
})
+/* acceptable for old filesystems */
+static inline int old_valid_dev(dev_t dev)
+{
+ return MAJOR(dev) < 256 && MINOR(dev) < 256;
+}
+
+static inline u16 old_encode_dev(dev_t dev)
+{
+ return (MAJOR(dev) << 8) | MINOR(dev);
+}
+
+static inline dev_t old_decode_dev(u16 val)
+{
+ return MKDEV((val >> 8) & 255, val & 255);
+}
+
+static inline int new_valid_dev(dev_t dev)
+{
+ return 1;
+}
+
+static inline u32 new_encode_dev(dev_t dev)
+{
+ unsigned major = MAJOR(dev);
+ unsigned minor = MINOR(dev);
+ return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+}
+
+static inline dev_t new_decode_dev(u32 dev)
+{
+ unsigned major = (dev & 0xfff00) >> 8;
+ unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
+ return MKDEV(major, minor);
+}
+
+static inline int huge_valid_dev(dev_t dev)
+{
+ return 1;
+}
+
+static inline u64 huge_encode_dev(dev_t dev)
+{
+ return new_encode_dev(dev);
+}
+
+static inline dev_t huge_decode_dev(u64 dev)
+{
+ return new_decode_dev(dev);
+}
+
+static inline int sysv_valid_dev(dev_t dev)
+{
+ return MAJOR(dev) < (1<<14) && MINOR(dev) < (1<<18);
+}
+
+static inline u32 sysv_encode_dev(dev_t dev)
+{
+ return MINOR(dev) | (MAJOR(dev) << 18);
+}
+
+static inline unsigned sysv_major(u32 dev)
+{
+ return (dev >> 18) & 0x3fff;
+}
+
+static inline unsigned sysv_minor(u32 dev)
+{
+ return dev & 0x3ffff;
+}
+
+
#else /* __KERNEL__ */
/*
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 70c5d117da8d..c9466321a2b2 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -64,11 +64,7 @@ static inline int level_to_pers (int level)
typedef struct mddev_s mddev_t;
typedef struct mdk_rdev_s mdk_rdev_t;
-#if (MINORBITS != 8)
-#error MD does not handle bigger kdev yet
-#endif
-
-#define MAX_MD_DEVS (1<<MINORBITS) /* Max number of md dev */
+#define MAX_MD_DEVS 256 /* Max number of md dev */
/*
* options passed in raidrun:
diff --git a/include/linux/types.h b/include/linux/types.h
index e3a3d8b1b6bb..3b407b06b48f 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -17,7 +17,7 @@
#ifndef __KERNEL_STRICT_NAMES
-typedef __u16 __kernel_dev_t;
+typedef __u32 __kernel_dev_t;
typedef __kernel_fd_set fd_set;
typedef __kernel_dev_t dev_t;