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
char *full_path = NULL;
struct inode * newinode = NULL;
if (!old_valid_dev(device_number))
return -EINVAL;
xid = GetXid();
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
if ( coda_hasmknod == 0 )
return -EIO;
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel();
coda_vfs_stat.create++;
......
......@@ -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)
{
struct inode * inode = ext2_new_inode (dir, mode);
int err = PTR_ERR(inode);
struct inode * inode;
int err;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = ext2_new_inode (dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev);
#ifdef CONFIG_EXT2_FS_XATTR
......
......@@ -1659,6 +1659,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
struct inode *inode;
int err;
if (!old_valid_dev(rdev))
return -EINVAL;
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
if (IS_ERR(handle))
......
......@@ -194,6 +194,8 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
int 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 (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel();
if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
memset(&dee, 0, sizeof dee);
......
......@@ -726,6 +726,9 @@ static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, de
struct dentry *parent = dentry->d_parent;
struct lento_vfs_context info;
if (!old_valid_dev(rdev))
return -EINVAL;
ENTRY;
error = presto_check_set_fsdata(dentry);
if ( error ) {
......
......@@ -1086,6 +1086,8 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
D1(printk("***jffs_mknod()\n"));
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel();
dir_f = (struct jffs_file *)dir->u.generic_ip;
c = dir_f->c;
......
......@@ -594,6 +594,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
uint32_t writtenlen;
int ret;
if (!old_valid_dev(rdev))
return -EINVAL;
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
......
......@@ -1311,6 +1311,9 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
tid_t tid;
struct tblock *tblk;
if (!old_valid_dev(rdev))
return -EINVAL;
jfs_info("jfs_mknod: %s", dentry->d_name.name);
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
......
......@@ -3,6 +3,7 @@
* Library for filesystems writers.
*/
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/vfs.h>
......@@ -428,3 +429,22 @@ 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);
......@@ -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)
{
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) {
inode->i_mode = mode;
......
......@@ -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,
int mode, dev_t rdev)
{
if (!old_valid_dev(rdev))
return -EINVAL;
if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
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)
dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name);
if (!old_valid_dev(rdev))
return -EINVAL;
attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE;
......
......@@ -613,6 +613,9 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
if (!old_valid_dev(rdev))
return -EINVAL;
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
}
......
......@@ -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_gid = current->egid;
if (!old_valid_dev(dev))
return -EINVAL;
smb_invalid_dir_cache(dir);
error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
if (!error) {
......
......@@ -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)
{
struct inode * inode = sysv_new_inode(dir, mode);
int err = PTR_ERR(inode);
struct inode * inode;
int err;
if (!old_valid_dev(rdev))
return -EINVAL;
inode = sysv_new_inode(dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
sysv_set_inode(inode, rdev);
......
......@@ -677,6 +677,9 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
int err;
struct fileIdentDesc cfi, *fi;
if (!old_valid_dev(rdev))
return -EINVAL;
lock_kernel();
err = -EIO;
inode = udf_new_inode(dir, mode, &err);
......
......@@ -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)
{
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);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
......
......@@ -113,6 +113,9 @@ linvfs_mknod(
xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS;
int error;
if (!old_valid_dev(rdev))
return -EINVAL;
if (test_default_acl && test_default_acl(dvp)) {
if (!_ACL_ALLOC(default_acl))
return -ENOMEM;
......
......@@ -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_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 *);
......
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