Commit b418f880 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] large dev_t - second series (9/15)

beginning of fs side work:
	* new helpers - old_valid_dev(), old_encode_dev() and old_decode_dev()
	* old_valid_dev() checks if dev_t value is OK for old filesystems
(i.e. both major and minor are below 256).
	* old_valid_dev() calls are added in ->mknod() instances that care
about dev_t values (disk-backed and network ones).
	* old_encode_dev() and old_decode_dev() convert dev_t -> u16
and u16 -> dev_t resp; currently these are no-ops, places that use current
formar (minor in bits 0--7, major in bits 8--15) will switch to these before
we widen dev_t.
parent 5900b098
...@@ -265,6 +265,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev ...@@ -265,6 +265,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
char *full_path = NULL; char *full_path = NULL;
struct inode * newinode = NULL; struct inode * newinode = NULL;
if (!old_valid_dev(device_number))
return -EINVAL;
xid = GetXid(); xid = GetXid();
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
......
...@@ -242,6 +242,9 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev ...@@ -242,6 +242,9 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev
if ( coda_hasmknod == 0 ) if ( coda_hasmknod == 0 )
return -EIO; return -EIO;
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel(); lock_kernel();
coda_vfs_stat.create++; coda_vfs_stat.create++;
......
...@@ -139,8 +139,14 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st ...@@ -139,8 +139,14 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st
static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{ {
struct inode * inode = ext2_new_inode (dir, mode); struct inode * inode;
int err = PTR_ERR(inode); int err;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = ext2_new_inode (dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev); init_special_inode(inode, inode->i_mode, rdev);
#ifdef CONFIG_EXT2_FS_XATTR #ifdef CONFIG_EXT2_FS_XATTR
......
...@@ -1659,6 +1659,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, ...@@ -1659,6 +1659,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
struct inode *inode; struct inode *inode;
int err; int err;
if (!old_valid_dev(rdev))
return -EINVAL;
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
if (IS_ERR(handle)) if (IS_ERR(handle))
......
...@@ -194,6 +194,8 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -194,6 +194,8 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
int err; int err;
if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err; if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM; if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel(); lock_kernel();
if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail; if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
memset(&dee, 0, sizeof dee); memset(&dee, 0, sizeof dee);
......
...@@ -726,6 +726,9 @@ static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, de ...@@ -726,6 +726,9 @@ static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, de
struct dentry *parent = dentry->d_parent; struct dentry *parent = dentry->d_parent;
struct lento_vfs_context info; struct lento_vfs_context info;
if (!old_valid_dev(rdev))
return -EINVAL;
ENTRY; ENTRY;
error = presto_check_set_fsdata(dentry); error = presto_check_set_fsdata(dentry);
if ( error ) { if ( error ) {
......
...@@ -1086,6 +1086,8 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -1086,6 +1086,8 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
D1(printk("***jffs_mknod()\n")); D1(printk("***jffs_mknod()\n"));
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel(); lock_kernel();
dir_f = (struct jffs_file *)dir->u.generic_ip; dir_f = (struct jffs_file *)dir->u.generic_ip;
c = dir_f->c; c = dir_f->c;
......
...@@ -594,6 +594,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk ...@@ -594,6 +594,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
uint32_t writtenlen; uint32_t writtenlen;
int ret; int ret;
if (!old_valid_dev(rdev))
return -EINVAL;
ri = jffs2_alloc_raw_inode(); ri = jffs2_alloc_raw_inode();
if (!ri) if (!ri)
return -ENOMEM; return -ENOMEM;
......
...@@ -1311,6 +1311,9 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -1311,6 +1311,9 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
tid_t tid; tid_t tid;
struct tblock *tblk; struct tblock *tblk;
if (!old_valid_dev(rdev))
return -EINVAL;
jfs_info("jfs_mknod: %s", dentry->d_name.name); jfs_info("jfs_mknod: %s", dentry->d_name.name);
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Library for filesystems writers. * Library for filesystems writers.
*/ */
#include <linux/module.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/vfs.h> #include <linux/vfs.h>
...@@ -428,3 +429,22 @@ void simple_release_fs(struct vfsmount **mount, int *count) ...@@ -428,3 +429,22 @@ void simple_release_fs(struct vfsmount **mount, int *count)
spin_unlock(&pin_fs_lock); spin_unlock(&pin_fs_lock);
mntput(mnt); 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);
...@@ -78,7 +78,12 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st ...@@ -78,7 +78,12 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st
static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{ {
int error; int error;
struct inode * inode = minix_new_inode(dir, &error); struct inode *inode;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = minix_new_inode(dir, &error);
if (inode) { if (inode) {
inode->i_mode = mode; inode->i_mode = mode;
......
...@@ -1170,6 +1170,8 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1170,6 +1170,8 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
static int ncp_mknod(struct inode * dir, struct dentry *dentry, static int ncp_mknod(struct inode * dir, struct dentry *dentry,
int mode, dev_t rdev) int mode, dev_t rdev)
{ {
if (!old_valid_dev(rdev))
return -EINVAL;
if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) { if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode); DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
return ncp_create_new(dir, dentry, mode, rdev, 0); return ncp_create_new(dir, dentry, mode, rdev, 0);
......
...@@ -859,6 +859,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -859,6 +859,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id, dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name); dir->i_ino, dentry->d_name.name);
if (!old_valid_dev(rdev))
return -EINVAL;
attr.ia_mode = mode; attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
......
...@@ -613,6 +613,9 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, ...@@ -613,6 +613,9 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
if (!old_valid_dev(rdev))
return -EINVAL;
if (!(inode = new_inode(dir->i_sb))) { if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ; return -ENOMEM ;
} }
......
...@@ -661,6 +661,9 @@ smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -661,6 +661,9 @@ smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
attr.ia_uid = current->euid; attr.ia_uid = current->euid;
attr.ia_gid = current->egid; attr.ia_gid = current->egid;
if (!old_valid_dev(dev))
return -EINVAL;
smb_invalid_dir_cache(dir); smb_invalid_dir_cache(dir);
error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev)); error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
if (!error) { if (!error) {
......
...@@ -85,8 +85,14 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st ...@@ -85,8 +85,14 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st
static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev)
{ {
struct inode * inode = sysv_new_inode(dir, mode); struct inode * inode;
int err = PTR_ERR(inode); int err;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = sysv_new_inode(dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
sysv_set_inode(inode, rdev); sysv_set_inode(inode, rdev);
......
...@@ -677,6 +677,9 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t ...@@ -677,6 +677,9 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
int err; int err;
struct fileIdentDesc cfi, *fi; struct fileIdentDesc cfi, *fi;
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel(); lock_kernel();
err = -EIO; err = -EIO;
inode = udf_new_inode(dir, mode, &err); inode = udf_new_inode(dir, mode, &err);
......
...@@ -111,7 +111,10 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, ...@@ -111,7 +111,10 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{ {
struct inode * inode = ufs_new_inode(dir, mode); struct inode * inode;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = ufs_new_inode(dir, mode);
int err = PTR_ERR(inode); int err = PTR_ERR(inode);
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev); init_special_inode(inode, mode, rdev);
......
...@@ -113,6 +113,9 @@ linvfs_mknod( ...@@ -113,6 +113,9 @@ linvfs_mknod(
xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS; xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS;
int error; int error;
if (!old_valid_dev(rdev))
return -EINVAL;
if (test_default_acl && test_default_acl(dvp)) { if (test_default_acl && test_default_acl(dvp)) {
if (!_ACL_ALLOC(default_acl)) if (!_ACL_ALLOC(default_acl))
return -ENOMEM; return -ENOMEM;
......
...@@ -1389,6 +1389,9 @@ struct tree_descr { char *name; struct file_operations *ops; int mode; }; ...@@ -1389,6 +1389,9 @@ 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_fill_super(struct super_block *, int, struct tree_descr *);
extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count); extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
extern void simple_release_fs(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_change_ok(struct inode *, struct iattr *);
extern int inode_setattr(struct inode *, struct iattr *); extern int inode_setattr(struct inode *, struct iattr *);
......
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