Commit e454cea2 authored by Kay Sievers's avatar Kay Sievers Committed by Live-CD User

Driver-Core: extend devnode callbacks to provide permissions

This allows subsytems to provide devtmpfs with non-default permissions
for the device node. Instead of the default mode of 0600, null, zero,
random, urandom, full, tty, ptmx now have a mode of 0666, which allows
non-privileged processes to access standard device nodes in case no
other userspace process applies the expected permissions.

This also fixes a wrong assignment in pktcdvd and a checkpatch.pl complain.
Signed-off-by: default avatarKay Sievers <kay.sievers@vrfy.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 78f28b7c
...@@ -182,7 +182,7 @@ static struct notifier_block __refdata cpuid_class_cpu_notifier = ...@@ -182,7 +182,7 @@ static struct notifier_block __refdata cpuid_class_cpu_notifier =
.notifier_call = cpuid_class_cpu_callback, .notifier_call = cpuid_class_cpu_callback,
}; };
static char *cpuid_nodename(struct device *dev) static char *cpuid_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt)); return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
} }
...@@ -203,7 +203,7 @@ static int __init cpuid_init(void) ...@@ -203,7 +203,7 @@ static int __init cpuid_init(void)
err = PTR_ERR(cpuid_class); err = PTR_ERR(cpuid_class);
goto out_chrdev; goto out_chrdev;
} }
cpuid_class->nodename = cpuid_nodename; cpuid_class->devnode = cpuid_devnode;
for_each_online_cpu(i) { for_each_online_cpu(i) {
err = cpuid_device_create(i); err = cpuid_device_create(i);
if (err != 0) if (err != 0)
......
...@@ -236,7 +236,7 @@ static const struct file_operations microcode_fops = { ...@@ -236,7 +236,7 @@ static const struct file_operations microcode_fops = {
static struct miscdevice microcode_dev = { static struct miscdevice microcode_dev = {
.minor = MICROCODE_MINOR, .minor = MICROCODE_MINOR,
.name = "microcode", .name = "microcode",
.devnode = "cpu/microcode", .nodename = "cpu/microcode",
.fops = &microcode_fops, .fops = &microcode_fops,
}; };
......
...@@ -241,7 +241,7 @@ static struct notifier_block __refdata msr_class_cpu_notifier = { ...@@ -241,7 +241,7 @@ static struct notifier_block __refdata msr_class_cpu_notifier = {
.notifier_call = msr_class_cpu_callback, .notifier_call = msr_class_cpu_callback,
}; };
static char *msr_nodename(struct device *dev) static char *msr_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt)); return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
} }
...@@ -262,7 +262,7 @@ static int __init msr_init(void) ...@@ -262,7 +262,7 @@ static int __init msr_init(void)
err = PTR_ERR(msr_class); err = PTR_ERR(msr_class);
goto out_chrdev; goto out_chrdev;
} }
msr_class->nodename = msr_nodename; msr_class->devnode = msr_devnode;
for_each_online_cpu(i) { for_each_online_cpu(i) {
err = msr_device_create(i); err = msr_device_create(i);
if (err != 0) if (err != 0)
......
...@@ -1062,7 +1062,7 @@ EXPORT_SYMBOL_GPL(bsg_register_queue); ...@@ -1062,7 +1062,7 @@ EXPORT_SYMBOL_GPL(bsg_register_queue);
static struct cdev bsg_cdev; static struct cdev bsg_cdev;
static char *bsg_nodename(struct device *dev) static char *bsg_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev));
} }
...@@ -1087,7 +1087,7 @@ static int __init bsg_init(void) ...@@ -1087,7 +1087,7 @@ static int __init bsg_init(void)
ret = PTR_ERR(bsg_class); ret = PTR_ERR(bsg_class);
goto destroy_kmemcache; goto destroy_kmemcache;
} }
bsg_class->nodename = bsg_nodename; bsg_class->devnode = bsg_devnode;
ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg"); ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg");
if (ret) if (ret)
......
...@@ -998,12 +998,12 @@ struct class block_class = { ...@@ -998,12 +998,12 @@ struct class block_class = {
.name = "block", .name = "block",
}; };
static char *block_nodename(struct device *dev) static char *block_devnode(struct device *dev, mode_t *mode)
{ {
struct gendisk *disk = dev_to_disk(dev); struct gendisk *disk = dev_to_disk(dev);
if (disk->nodename) if (disk->devnode)
return disk->nodename(disk); return disk->devnode(disk, mode);
return NULL; return NULL;
} }
...@@ -1011,7 +1011,7 @@ static struct device_type disk_type = { ...@@ -1011,7 +1011,7 @@ static struct device_type disk_type = {
.name = "disk", .name = "disk",
.groups = disk_attr_groups, .groups = disk_attr_groups,
.release = disk_release, .release = disk_release,
.nodename = block_nodename, .devnode = block_devnode,
}; };
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, ...@@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (MAJOR(dev->devt)) { if (MAJOR(dev->devt)) {
const char *tmp; const char *tmp;
const char *name; const char *name;
mode_t mode = 0;
add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
name = device_get_nodename(dev, &tmp); name = device_get_devnode(dev, &mode, &tmp);
if (name) { if (name) {
add_uevent_var(env, "DEVNAME=%s", name); add_uevent_var(env, "DEVNAME=%s", name);
kfree(tmp); kfree(tmp);
if (mode)
add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
} }
} }
...@@ -1148,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i) ...@@ -1148,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i)
} }
/** /**
* device_get_nodename - path of device node file * device_get_devnode - path of device node file
* @dev: device * @dev: device
* @mode: returned file access mode
* @tmp: possibly allocated string * @tmp: possibly allocated string
* *
* Return the relative path of a possible device node. * Return the relative path of a possible device node.
...@@ -1157,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i) ...@@ -1157,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i)
* a name. This memory is returned in tmp and needs to be * a name. This memory is returned in tmp and needs to be
* freed by the caller. * freed by the caller.
*/ */
const char *device_get_nodename(struct device *dev, const char **tmp) const char *device_get_devnode(struct device *dev,
mode_t *mode, const char **tmp)
{ {
char *s; char *s;
*tmp = NULL; *tmp = NULL;
/* the device type may provide a specific name */ /* the device type may provide a specific name */
if (dev->type && dev->type->nodename) if (dev->type && dev->type->devnode)
*tmp = dev->type->nodename(dev); *tmp = dev->type->devnode(dev, mode);
if (*tmp) if (*tmp)
return *tmp; return *tmp;
/* the class may provide a specific name */ /* the class may provide a specific name */
if (dev->class && dev->class->nodename) if (dev->class && dev->class->devnode)
*tmp = dev->class->nodename(dev); *tmp = dev->class->devnode(dev, mode);
if (*tmp) if (*tmp)
return *tmp; return *tmp;
......
...@@ -6,9 +6,10 @@ ...@@ -6,9 +6,10 @@
* During bootup, before any driver core device is registered, * During bootup, before any driver core device is registered,
* devtmpfs, a tmpfs-based filesystem is created. Every driver-core * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
* device which requests a device node, will add a node in this * device which requests a device node, will add a node in this
* filesystem. The node is named after the the name of the device, * filesystem.
* or the susbsytem can provide a custom name. All devices are * By default, all devices are named after the the name of the
* owned by root and have a mode of 0600. * device, owned by root and have a default mode of 0600. Subsystems
* can overwrite the default setting if needed.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/sched.h>
#include <linux/init_task.h> #include <linux/init_task.h>
static struct vfsmount *dev_mnt; static struct vfsmount *dev_mnt;
...@@ -134,7 +136,7 @@ int devtmpfs_create_node(struct device *dev) ...@@ -134,7 +136,7 @@ int devtmpfs_create_node(struct device *dev)
const char *tmp = NULL; const char *tmp = NULL;
const char *nodename; const char *nodename;
const struct cred *curr_cred; const struct cred *curr_cred;
mode_t mode; mode_t mode = 0;
struct nameidata nd; struct nameidata nd;
struct dentry *dentry; struct dentry *dentry;
int err; int err;
...@@ -142,14 +144,16 @@ int devtmpfs_create_node(struct device *dev) ...@@ -142,14 +144,16 @@ int devtmpfs_create_node(struct device *dev)
if (!dev_mnt) if (!dev_mnt)
return 0; return 0;
nodename = device_get_nodename(dev, &tmp); nodename = device_get_devnode(dev, &mode, &tmp);
if (!nodename) if (!nodename)
return -ENOMEM; return -ENOMEM;
if (mode == 0)
mode = 0600;
if (is_blockdev(dev)) if (is_blockdev(dev))
mode = S_IFBLK|0600; mode |= S_IFBLK;
else else
mode = S_IFCHR|0600; mode |= S_IFCHR;
curr_cred = override_creds(&init_cred); curr_cred = override_creds(&init_cred);
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
...@@ -165,8 +169,12 @@ int devtmpfs_create_node(struct device *dev) ...@@ -165,8 +169,12 @@ int devtmpfs_create_node(struct device *dev)
dentry = lookup_create(&nd, 0); dentry = lookup_create(&nd, 0);
if (!IS_ERR(dentry)) { if (!IS_ERR(dentry)) {
int umask;
umask = sys_umask(0000);
err = vfs_mknod(nd.path.dentry->d_inode, err = vfs_mknod(nd.path.dentry->d_inode,
dentry, mode, dev->devt); dentry, mode, dev->devt);
sys_umask(umask);
/* mark as kernel created inode */ /* mark as kernel created inode */
if (!err) if (!err)
dentry->d_inode->i_private = &dev_mnt; dentry->d_inode->i_private = &dev_mnt;
...@@ -271,7 +279,7 @@ int devtmpfs_delete_node(struct device *dev) ...@@ -271,7 +279,7 @@ int devtmpfs_delete_node(struct device *dev)
if (!dev_mnt) if (!dev_mnt)
return 0; return 0;
nodename = device_get_nodename(dev, &tmp); nodename = device_get_devnode(dev, NULL, &tmp);
if (!nodename) if (!nodename)
return -ENOMEM; return -ENOMEM;
......
...@@ -266,7 +266,7 @@ static const struct file_operations aoe_fops = { ...@@ -266,7 +266,7 @@ static const struct file_operations aoe_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static char *aoe_nodename(struct device *dev) static char *aoe_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev));
} }
...@@ -288,7 +288,7 @@ aoechr_init(void) ...@@ -288,7 +288,7 @@ aoechr_init(void)
unregister_chrdev(AOE_MAJOR, "aoechr"); unregister_chrdev(AOE_MAJOR, "aoechr");
return PTR_ERR(aoe_class); return PTR_ERR(aoe_class);
} }
aoe_class->nodename = aoe_nodename; aoe_class->devnode = aoe_devnode;
for (i = 0; i < ARRAY_SIZE(chardevs); ++i) for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
device_create(aoe_class, NULL, device_create(aoe_class, NULL,
......
...@@ -2857,7 +2857,7 @@ static struct block_device_operations pktcdvd_ops = { ...@@ -2857,7 +2857,7 @@ static struct block_device_operations pktcdvd_ops = {
.media_changed = pkt_media_changed, .media_changed = pkt_media_changed,
}; };
static char *pktcdvd_nodename(struct gendisk *gd) static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name); return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name);
} }
...@@ -2914,7 +2914,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) ...@@ -2914,7 +2914,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
disk->fops = &pktcdvd_ops; disk->fops = &pktcdvd_ops;
disk->flags = GENHD_FL_REMOVABLE; disk->flags = GENHD_FL_REMOVABLE;
strcpy(disk->disk_name, pd->name); strcpy(disk->disk_name, pd->name);
disk->nodename = pktcdvd_nodename; disk->devnode = pktcdvd_devnode;
disk->private_data = pd; disk->private_data = pd;
disk->queue = blk_alloc_queue(GFP_KERNEL); disk->queue = blk_alloc_queue(GFP_KERNEL);
if (!disk->queue) if (!disk->queue)
...@@ -3070,7 +3070,7 @@ static const struct file_operations pkt_ctl_fops = { ...@@ -3070,7 +3070,7 @@ static const struct file_operations pkt_ctl_fops = {
static struct miscdevice pkt_misc = { static struct miscdevice pkt_misc = {
.minor = MISC_DYNAMIC_MINOR, .minor = MISC_DYNAMIC_MINOR,
.name = DRIVER_NAME, .name = DRIVER_NAME,
.name = "pktcdvd/control", .nodename = "pktcdvd/control",
.fops = &pkt_ctl_fops .fops = &pkt_ctl_fops
}; };
......
...@@ -153,7 +153,7 @@ static const struct file_operations rng_chrdev_ops = { ...@@ -153,7 +153,7 @@ static const struct file_operations rng_chrdev_ops = {
static struct miscdevice rng_miscdev = { static struct miscdevice rng_miscdev = {
.minor = RNG_MISCDEV_MINOR, .minor = RNG_MISCDEV_MINOR,
.name = RNG_MODULE_NAME, .name = RNG_MODULE_NAME,
.devnode = "hwrng", .nodename = "hwrng",
.fops = &rng_chrdev_ops, .fops = &rng_chrdev_ops,
}; };
......
...@@ -866,24 +866,25 @@ static const struct file_operations kmsg_fops = { ...@@ -866,24 +866,25 @@ static const struct file_operations kmsg_fops = {
static const struct memdev { static const struct memdev {
const char *name; const char *name;
mode_t mode;
const struct file_operations *fops; const struct file_operations *fops;
struct backing_dev_info *dev_info; struct backing_dev_info *dev_info;
} devlist[] = { } devlist[] = {
[ 1] = { "mem", &mem_fops, &directly_mappable_cdev_bdi }, [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
#ifdef CONFIG_DEVKMEM #ifdef CONFIG_DEVKMEM
[ 2] = { "kmem", &kmem_fops, &directly_mappable_cdev_bdi }, [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
#endif #endif
[ 3] = {"null", &null_fops, NULL }, [3] = { "null", 0666, &null_fops, NULL },
#ifdef CONFIG_DEVPORT #ifdef CONFIG_DEVPORT
[ 4] = { "port", &port_fops, NULL }, [4] = { "port", 0, &port_fops, NULL },
#endif #endif
[ 5] = { "zero", &zero_fops, &zero_bdi }, [5] = { "zero", 0666, &zero_fops, &zero_bdi },
[ 7] = { "full", &full_fops, NULL }, [7] = { "full", 0666, &full_fops, NULL },
[ 8] = { "random", &random_fops, NULL }, [8] = { "random", 0666, &random_fops, NULL },
[ 9] = { "urandom", &urandom_fops, NULL }, [9] = { "urandom", 0666, &urandom_fops, NULL },
[11] = { "kmsg", &kmsg_fops, NULL }, [11] = { "kmsg", 0, &kmsg_fops, NULL },
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
[12] = { "oldmem", &oldmem_fops, NULL }, [12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif #endif
}; };
...@@ -920,6 +921,13 @@ static const struct file_operations memory_fops = { ...@@ -920,6 +921,13 @@ static const struct file_operations memory_fops = {
.open = memory_open, .open = memory_open,
}; };
static char *mem_devnode(struct device *dev, mode_t *mode)
{
if (mode && devlist[MINOR(dev->devt)].mode)
*mode = devlist[MINOR(dev->devt)].mode;
return NULL;
}
static struct class *mem_class; static struct class *mem_class;
static int __init chr_dev_init(void) static int __init chr_dev_init(void)
...@@ -935,6 +943,7 @@ static int __init chr_dev_init(void) ...@@ -935,6 +943,7 @@ static int __init chr_dev_init(void)
printk("unable to get major %d for memory devs\n", MEM_MAJOR); printk("unable to get major %d for memory devs\n", MEM_MAJOR);
mem_class = class_create(THIS_MODULE, "mem"); mem_class = class_create(THIS_MODULE, "mem");
mem_class->devnode = mem_devnode;
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name) if (!devlist[minor].name)
continue; continue;
......
...@@ -263,12 +263,14 @@ int misc_deregister(struct miscdevice *misc) ...@@ -263,12 +263,14 @@ int misc_deregister(struct miscdevice *misc)
EXPORT_SYMBOL(misc_register); EXPORT_SYMBOL(misc_register);
EXPORT_SYMBOL(misc_deregister); EXPORT_SYMBOL(misc_deregister);
static char *misc_nodename(struct device *dev) static char *misc_devnode(struct device *dev, mode_t *mode)
{ {
struct miscdevice *c = dev_get_drvdata(dev); struct miscdevice *c = dev_get_drvdata(dev);
if (c->devnode) if (mode && c->mode)
return kstrdup(c->devnode, GFP_KERNEL); *mode = c->mode;
if (c->nodename)
return kstrdup(c->nodename, GFP_KERNEL);
return NULL; return NULL;
} }
...@@ -287,7 +289,7 @@ static int __init misc_init(void) ...@@ -287,7 +289,7 @@ static int __init misc_init(void)
err = -EIO; err = -EIO;
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
goto fail_printk; goto fail_printk;
misc_class->nodename = misc_nodename; misc_class->devnode = misc_devnode;
return 0; return 0;
fail_printk: fail_printk:
......
...@@ -261,7 +261,7 @@ static const struct file_operations raw_ctl_fops = { ...@@ -261,7 +261,7 @@ static const struct file_operations raw_ctl_fops = {
static struct cdev raw_cdev; static struct cdev raw_cdev;
static char *raw_nodename(struct device *dev) static char *raw_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
} }
...@@ -289,7 +289,7 @@ static int __init raw_init(void) ...@@ -289,7 +289,7 @@ static int __init raw_init(void)
ret = PTR_ERR(raw_class); ret = PTR_ERR(raw_class);
goto error_region; goto error_region;
} }
raw_class->nodename = raw_nodename; raw_class->devnode = raw_devnode;
device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
return 0; return 0;
......
...@@ -3056,11 +3056,22 @@ void __init console_init(void) ...@@ -3056,11 +3056,22 @@ void __init console_init(void)
} }
} }
static char *tty_devnode(struct device *dev, mode_t *mode)
{
if (!mode)
return NULL;
if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
dev->devt == MKDEV(TTYAUX_MAJOR, 2))
*mode = 0666;
return NULL;
}
static int __init tty_class_init(void) static int __init tty_class_init(void)
{ {
tty_class = class_create(THIS_MODULE, "tty"); tty_class = class_create(THIS_MODULE, "tty");
if (IS_ERR(tty_class)) if (IS_ERR(tty_class))
return PTR_ERR(tty_class); return PTR_ERR(tty_class);
tty_class->devnode = tty_devnode;
return 0; return 0;
} }
......
...@@ -76,7 +76,7 @@ static ssize_t version_show(struct class *dev, char *buf) ...@@ -76,7 +76,7 @@ static ssize_t version_show(struct class *dev, char *buf)
CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
} }
static char *drm_nodename(struct device *dev) static char *drm_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
} }
...@@ -112,7 +112,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name) ...@@ -112,7 +112,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
if (err) if (err)
goto err_out_class; goto err_out_class;
class->nodename = drm_nodename; class->devnode = drm_devnode;
return class; return class;
......
...@@ -852,14 +852,14 @@ static const struct file_operations hiddev_fops = { ...@@ -852,14 +852,14 @@ static const struct file_operations hiddev_fops = {
#endif #endif
}; };
static char *hiddev_nodename(struct device *dev) static char *hiddev_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
} }
static struct usb_class_driver hiddev_class = { static struct usb_class_driver hiddev_class = {
.name = "hiddev%d", .name = "hiddev%d",
.nodename = hiddev_nodename, .devnode = hiddev_devnode,
.fops = &hiddev_fops, .fops = &hiddev_fops,
.minor_base = HIDDEV_MINOR_BASE, .minor_base = HIDDEV_MINOR_BASE,
}; };
......
...@@ -1265,14 +1265,14 @@ static struct device_type input_dev_type = { ...@@ -1265,14 +1265,14 @@ static struct device_type input_dev_type = {
.uevent = input_dev_uevent, .uevent = input_dev_uevent,
}; };
static char *input_nodename(struct device *dev) static char *input_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev));
} }
struct class input_class = { struct class input_class = {
.name = "input", .name = "input",
.nodename = input_nodename, .devnode = input_devnode,
}; };
EXPORT_SYMBOL_GPL(input_class); EXPORT_SYMBOL_GPL(input_class);
......
...@@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = { ...@@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = {
static struct miscdevice _dm_misc = { static struct miscdevice _dm_misc = {
.minor = MISC_DYNAMIC_MINOR, .minor = MISC_DYNAMIC_MINOR,
.name = DM_NAME, .name = DM_NAME,
.devnode = "mapper/control", .nodename = "mapper/control",
.fops = &_ctl_fops .fops = &_ctl_fops
}; };
......
...@@ -447,7 +447,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -447,7 +447,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0; return 0;
} }
static char *dvb_nodename(struct device *dev) static char *dvb_devnode(struct device *dev, mode_t *mode)
{ {
struct dvb_device *dvbdev = dev_get_drvdata(dev); struct dvb_device *dvbdev = dev_get_drvdata(dev);
...@@ -478,7 +478,7 @@ static int __init init_dvbdev(void) ...@@ -478,7 +478,7 @@ static int __init init_dvbdev(void)
goto error; goto error;
} }
dvb_class->dev_uevent = dvb_uevent; dvb_class->dev_uevent = dvb_uevent;
dvb_class->nodename = dvb_nodename; dvb_class->devnode = dvb_devnode;
return 0; return 0;
error: error:
......
...@@ -1370,7 +1370,7 @@ static const struct file_operations tun_fops = { ...@@ -1370,7 +1370,7 @@ static const struct file_operations tun_fops = {
static struct miscdevice tun_miscdev = { static struct miscdevice tun_miscdev = {
.minor = TUN_MINOR, .minor = TUN_MINOR,
.name = "tun", .name = "tun",
.devnode = "net/tun", .nodename = "net/tun",
.fops = &tun_fops, .fops = &tun_fops,
}; };
......
...@@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = { ...@@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = {
.release = usblp_release, .release = usblp_release,
}; };
static char *usblp_nodename(struct device *dev) static char *usblp_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
} }
static struct usb_class_driver usblp_class = { static struct usb_class_driver usblp_class = {
.name = "lp%d", .name = "lp%d",
.nodename = usblp_nodename, .devnode = usblp_devnode,
.fops = &usblp_fops, .fops = &usblp_fops,
.minor_base = USBLP_MINOR_BASE, .minor_base = USBLP_MINOR_BASE,
}; };
......
...@@ -67,14 +67,14 @@ static struct usb_class { ...@@ -67,14 +67,14 @@ static struct usb_class {
struct class *class; struct class *class;
} *usb_class; } *usb_class;
static char *usb_nodename(struct device *dev) static char *usb_devnode(struct device *dev, mode_t *mode)
{ {
struct usb_class_driver *drv; struct usb_class_driver *drv;
drv = dev_get_drvdata(dev); drv = dev_get_drvdata(dev);
if (!drv || !drv->nodename) if (!drv || !drv->devnode)
return NULL; return NULL;
return drv->nodename(dev); return drv->devnode(dev, mode);
} }
static int init_usb_class(void) static int init_usb_class(void)
...@@ -100,7 +100,7 @@ static int init_usb_class(void) ...@@ -100,7 +100,7 @@ static int init_usb_class(void)
kfree(usb_class); kfree(usb_class);
usb_class = NULL; usb_class = NULL;
} }
usb_class->class->nodename = usb_nodename; usb_class->class->devnode = usb_devnode;
exit: exit:
return result; return result;
......
...@@ -311,7 +311,7 @@ static struct dev_pm_ops usb_device_pm_ops = { ...@@ -311,7 +311,7 @@ static struct dev_pm_ops usb_device_pm_ops = {
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
static char *usb_nodename(struct device *dev) static char *usb_devnode(struct device *dev, mode_t *mode)
{ {
struct usb_device *usb_dev; struct usb_device *usb_dev;
...@@ -324,7 +324,7 @@ struct device_type usb_device_type = { ...@@ -324,7 +324,7 @@ struct device_type usb_device_type = {
.name = "usb_device", .name = "usb_device",
.release = usb_release_dev, .release = usb_release_dev,
.uevent = usb_dev_uevent, .uevent = usb_dev_uevent,
.nodename = usb_nodename, .devnode = usb_devnode,
.pm = &usb_device_pm_ops, .pm = &usb_device_pm_ops,
}; };
......
...@@ -727,7 +727,7 @@ static const struct file_operations iowarrior_fops = { ...@@ -727,7 +727,7 @@ static const struct file_operations iowarrior_fops = {
.poll = iowarrior_poll, .poll = iowarrior_poll,
}; };
static char *iowarrior_nodename(struct device *dev) static char *iowarrior_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
} }
...@@ -738,7 +738,7 @@ static char *iowarrior_nodename(struct device *dev) ...@@ -738,7 +738,7 @@ static char *iowarrior_nodename(struct device *dev)
*/ */
static struct usb_class_driver iowarrior_class = { static struct usb_class_driver iowarrior_class = {
.name = "iowarrior%d", .name = "iowarrior%d",
.nodename = iowarrior_nodename, .devnode = iowarrior_devnode,
.fops = &iowarrior_fops, .fops = &iowarrior_fops,
.minor_base = IOWARRIOR_MINOR_BASE, .minor_base = IOWARRIOR_MINOR_BASE,
}; };
......
...@@ -266,7 +266,7 @@ static const struct file_operations tower_fops = { ...@@ -266,7 +266,7 @@ static const struct file_operations tower_fops = {
.llseek = tower_llseek, .llseek = tower_llseek,
}; };
static char *legousbtower_nodename(struct device *dev) static char *legousbtower_devnode(struct device *dev, mode_t *mode)
{ {
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
} }
...@@ -277,7 +277,7 @@ static char *legousbtower_nodename(struct device *dev) ...@@ -277,7 +277,7 @@ static char *legousbtower_nodename(struct device *dev)
*/ */
static struct usb_class_driver tower_class = { static struct usb_class_driver tower_class = {
.name = "legousbtower%d", .name = "legousbtower%d",
.nodename = legousbtower_nodename, .devnode = legousbtower_devnode,
.fops = &tower_fops, .fops = &tower_fops,
.minor_base = LEGO_USB_TOWER_MINOR_BASE, .minor_base = LEGO_USB_TOWER_MINOR_BASE,
}; };
......
...@@ -193,7 +193,7 @@ struct class { ...@@ -193,7 +193,7 @@ struct class {
struct kobject *dev_kobj; struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*nodename)(struct device *dev); char *(*devnode)(struct device *dev, mode_t *mode);
void (*class_release)(struct class *class); void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev); void (*dev_release)(struct device *dev);
...@@ -298,7 +298,7 @@ struct device_type { ...@@ -298,7 +298,7 @@ struct device_type {
const char *name; const char *name;
const struct attribute_group **groups; const struct attribute_group **groups;
int (*uevent)(struct device *dev, struct kobj_uevent_env *env); int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*nodename)(struct device *dev); char *(*devnode)(struct device *dev, mode_t *mode);
void (*release)(struct device *dev); void (*release)(struct device *dev);
const struct dev_pm_ops *pm; const struct dev_pm_ops *pm;
...@@ -487,7 +487,8 @@ extern struct device *device_find_child(struct device *dev, void *data, ...@@ -487,7 +487,8 @@ extern struct device *device_find_child(struct device *dev, void *data,
extern int device_rename(struct device *dev, char *new_name); extern int device_rename(struct device *dev, char *new_name);
extern int device_move(struct device *dev, struct device *new_parent, extern int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order); enum dpm_order dpm_order);
extern const char *device_get_nodename(struct device *dev, const char **tmp); extern const char *device_get_devnode(struct device *dev,
mode_t *mode, const char **tmp);
extern void *dev_get_drvdata(const struct device *dev); extern void *dev_get_drvdata(const struct device *dev);
extern void dev_set_drvdata(struct device *dev, void *data); extern void dev_set_drvdata(struct device *dev, void *data);
......
...@@ -142,7 +142,7 @@ struct gendisk { ...@@ -142,7 +142,7 @@ struct gendisk {
* disks that can't be partitioned. */ * disks that can't be partitioned. */
char disk_name[DISK_NAME_LEN]; /* name of major driver */ char disk_name[DISK_NAME_LEN]; /* name of major driver */
char *(*nodename)(struct gendisk *gd); char *(*devnode)(struct gendisk *gd, mode_t *mode);
/* Array of pointers to partitions indexed by partno. /* Array of pointers to partitions indexed by partno.
* Protected with matching bdev lock but stat and other * Protected with matching bdev lock but stat and other
* non-critical accesses use RCU. Always access through * non-critical accesses use RCU. Always access through
......
...@@ -41,7 +41,8 @@ struct miscdevice { ...@@ -41,7 +41,8 @@ struct miscdevice {
struct list_head list; struct list_head list;
struct device *parent; struct device *parent;
struct device *this_device; struct device *this_device;
const char *devnode; const char *nodename;
mode_t mode;
}; };
extern int misc_register(struct miscdevice * misc); extern int misc_register(struct miscdevice * misc);
......
...@@ -922,7 +922,7 @@ extern struct bus_type usb_bus_type; ...@@ -922,7 +922,7 @@ extern struct bus_type usb_bus_type;
/** /**
* struct usb_class_driver - identifies a USB driver that wants to use the USB major number * struct usb_class_driver - identifies a USB driver that wants to use the USB major number
* @name: the usb class device name for this driver. Will show up in sysfs. * @name: the usb class device name for this driver. Will show up in sysfs.
* @nodename: Callback to provide a naming hint for a possible * @devnode: Callback to provide a naming hint for a possible
* device node to create. * device node to create.
* @fops: pointer to the struct file_operations of this driver. * @fops: pointer to the struct file_operations of this driver.
* @minor_base: the start of the minor range for this driver. * @minor_base: the start of the minor range for this driver.
...@@ -933,7 +933,7 @@ extern struct bus_type usb_bus_type; ...@@ -933,7 +933,7 @@ extern struct bus_type usb_bus_type;
*/ */
struct usb_class_driver { struct usb_class_driver {
char *name; char *name;
char *(*nodename)(struct device *dev); char *(*devnode)(struct device *dev, mode_t *mode);
const struct file_operations *fops; const struct file_operations *fops;
int minor_base; int minor_base;
}; };
......
...@@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module"); ...@@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module");
MODULE_AUTHOR("Alan Cox"); MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static char *sound_nodename(struct device *dev) static char *sound_devnode(struct device *dev, mode_t *mode)
{ {
if (MAJOR(dev->devt) == SOUND_MAJOR) if (MAJOR(dev->devt) == SOUND_MAJOR)
return NULL; return NULL;
...@@ -50,7 +50,7 @@ static int __init init_soundcore(void) ...@@ -50,7 +50,7 @@ static int __init init_soundcore(void)
return PTR_ERR(sound_class); return PTR_ERR(sound_class);
} }
sound_class->nodename = sound_nodename; sound_class->devnode = sound_devnode;
return 0; return 0;
} }
......
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