Commit 40d2adc6 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] 32-bit dev_t: internal use

Starting the conversion:
	* internal dev_t made 32bit.
	* new helpers - new_encode_dev(), new_decode_dev(), huge_encode_dev(),
huge_decode_dev(), new_valid_dev().  They do encoding/decoding of 32bit and
64bit values; for now huge_... are aliases for new_... and new_valid_dev()
is always true.  We do 12:20 for 32bit; representation is compatible with
16bit one - we have major in bits 19--8 and minor in 31--20,7--0.  That's
what the userland sees; internally we have (major << 20)|minor, of course.
	* MKDEV(), MAJOR() and MINOR() updated.
	* several places used to handle Missed'em'V dev_t (14:18 split)
manually; that stuff had been taken into common helpers.
	Now we can start replacing old_... with new_... and huge_..., depending
on the width available.  MKDEV() callers should (for now) make sure that major
and minor are within 12:20.  That's what the next chunk will do.
parent 18d0c6d3
......@@ -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;
......
......@@ -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) ||
......
......@@ -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)
/*
......
......@@ -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);
......@@ -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:
......
......@@ -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;
......
......@@ -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 */
......@@ -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 *);
......
#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__ */
/*
......
......@@ -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:
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment