root/drivers/char/raw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. raw_open
  2. raw_release
  3. raw_ioctl
  4. bind_set
  5. bind_get
  6. raw_ctl_ioctl
  7. raw_ctl_compat_ioctl
  8. raw_devnode
  9. raw_init
  10. raw_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/char/raw.c
   4  *
   5  * Front-end raw character devices.  These can be bound to any block
   6  * devices to provide genuine Unix raw character device semantics.
   7  *
   8  * We reserve minor number 0 for a control interface.  ioctl()s on this
   9  * device are used to bind the other minor numbers to block devices.
  10  */
  11 
  12 #include <linux/init.h>
  13 #include <linux/fs.h>
  14 #include <linux/major.h>
  15 #include <linux/blkdev.h>
  16 #include <linux/backing-dev.h>
  17 #include <linux/module.h>
  18 #include <linux/raw.h>
  19 #include <linux/capability.h>
  20 #include <linux/uio.h>
  21 #include <linux/cdev.h>
  22 #include <linux/device.h>
  23 #include <linux/mutex.h>
  24 #include <linux/gfp.h>
  25 #include <linux/compat.h>
  26 #include <linux/vmalloc.h>
  27 
  28 #include <linux/uaccess.h>
  29 
  30 struct raw_device_data {
  31         struct block_device *binding;
  32         int inuse;
  33 };
  34 
  35 static struct class *raw_class;
  36 static struct raw_device_data *raw_devices;
  37 static DEFINE_MUTEX(raw_mutex);
  38 static const struct file_operations raw_ctl_fops; /* forward declaration */
  39 
  40 static int max_raw_minors = MAX_RAW_MINORS;
  41 
  42 module_param(max_raw_minors, int, 0);
  43 MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
  44 
  45 /*
  46  * Open/close code for raw IO.
  47  *
  48  * We just rewrite the i_mapping for the /dev/raw/rawN file descriptor to
  49  * point at the blockdev's address_space and set the file handle to use
  50  * O_DIRECT.
  51  *
  52  * Set the device's soft blocksize to the minimum possible.  This gives the
  53  * finest possible alignment and has no adverse impact on performance.
  54  */
  55 static int raw_open(struct inode *inode, struct file *filp)
  56 {
  57         const int minor = iminor(inode);
  58         struct block_device *bdev;
  59         int err;
  60 
  61         if (minor == 0) {       /* It is the control device */
  62                 filp->f_op = &raw_ctl_fops;
  63                 return 0;
  64         }
  65 
  66         mutex_lock(&raw_mutex);
  67 
  68         /*
  69          * All we need to do on open is check that the device is bound.
  70          */
  71         bdev = raw_devices[minor].binding;
  72         err = -ENODEV;
  73         if (!bdev)
  74                 goto out;
  75         bdgrab(bdev);
  76         err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
  77         if (err)
  78                 goto out;
  79         err = set_blocksize(bdev, bdev_logical_block_size(bdev));
  80         if (err)
  81                 goto out1;
  82         filp->f_flags |= O_DIRECT;
  83         filp->f_mapping = bdev->bd_inode->i_mapping;
  84         if (++raw_devices[minor].inuse == 1)
  85                 file_inode(filp)->i_mapping =
  86                         bdev->bd_inode->i_mapping;
  87         filp->private_data = bdev;
  88         mutex_unlock(&raw_mutex);
  89         return 0;
  90 
  91 out1:
  92         blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
  93 out:
  94         mutex_unlock(&raw_mutex);
  95         return err;
  96 }
  97 
  98 /*
  99  * When the final fd which refers to this character-special node is closed, we
 100  * make its ->mapping point back at its own i_data.
 101  */
 102 static int raw_release(struct inode *inode, struct file *filp)
 103 {
 104         const int minor= iminor(inode);
 105         struct block_device *bdev;
 106 
 107         mutex_lock(&raw_mutex);
 108         bdev = raw_devices[minor].binding;
 109         if (--raw_devices[minor].inuse == 0)
 110                 /* Here  inode->i_mapping == bdev->bd_inode->i_mapping  */
 111                 inode->i_mapping = &inode->i_data;
 112         mutex_unlock(&raw_mutex);
 113 
 114         blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
 115         return 0;
 116 }
 117 
 118 /*
 119  * Forward ioctls to the underlying block device.
 120  */
 121 static long
 122 raw_ioctl(struct file *filp, unsigned int command, unsigned long arg)
 123 {
 124         struct block_device *bdev = filp->private_data;
 125         return blkdev_ioctl(bdev, 0, command, arg);
 126 }
 127 
 128 static int bind_set(int number, u64 major, u64 minor)
 129 {
 130         dev_t dev = MKDEV(major, minor);
 131         struct raw_device_data *rawdev;
 132         int err = 0;
 133 
 134         if (number <= 0 || number >= max_raw_minors)
 135                 return -EINVAL;
 136 
 137         if (MAJOR(dev) != major || MINOR(dev) != minor)
 138                 return -EINVAL;
 139 
 140         rawdev = &raw_devices[number];
 141 
 142         /*
 143          * This is like making block devices, so demand the
 144          * same capability
 145          */
 146         if (!capable(CAP_SYS_ADMIN))
 147                 return -EPERM;
 148 
 149         /*
 150          * For now, we don't need to check that the underlying
 151          * block device is present or not: we can do that when
 152          * the raw device is opened.  Just check that the
 153          * major/minor numbers make sense.
 154          */
 155 
 156         if (MAJOR(dev) == 0 && dev != 0)
 157                 return -EINVAL;
 158 
 159         mutex_lock(&raw_mutex);
 160         if (rawdev->inuse) {
 161                 mutex_unlock(&raw_mutex);
 162                 return -EBUSY;
 163         }
 164         if (rawdev->binding) {
 165                 bdput(rawdev->binding);
 166                 module_put(THIS_MODULE);
 167         }
 168         if (!dev) {
 169                 /* unbind */
 170                 rawdev->binding = NULL;
 171                 device_destroy(raw_class, MKDEV(RAW_MAJOR, number));
 172         } else {
 173                 rawdev->binding = bdget(dev);
 174                 if (rawdev->binding == NULL) {
 175                         err = -ENOMEM;
 176                 } else {
 177                         dev_t raw = MKDEV(RAW_MAJOR, number);
 178                         __module_get(THIS_MODULE);
 179                         device_destroy(raw_class, raw);
 180                         device_create(raw_class, NULL, raw, NULL,
 181                                       "raw%d", number);
 182                 }
 183         }
 184         mutex_unlock(&raw_mutex);
 185         return err;
 186 }
 187 
 188 static int bind_get(int number, dev_t *dev)
 189 {
 190         struct raw_device_data *rawdev;
 191         struct block_device *bdev;
 192 
 193         if (number <= 0 || number >= max_raw_minors)
 194                 return -EINVAL;
 195 
 196         rawdev = &raw_devices[number];
 197 
 198         mutex_lock(&raw_mutex);
 199         bdev = rawdev->binding;
 200         *dev = bdev ? bdev->bd_dev : 0;
 201         mutex_unlock(&raw_mutex);
 202         return 0;
 203 }
 204 
 205 /*
 206  * Deal with ioctls against the raw-device control interface, to bind
 207  * and unbind other raw devices.
 208  */
 209 static long raw_ctl_ioctl(struct file *filp, unsigned int command,
 210                           unsigned long arg)
 211 {
 212         struct raw_config_request rq;
 213         dev_t dev;
 214         int err;
 215 
 216         switch (command) {
 217         case RAW_SETBIND:
 218                 if (copy_from_user(&rq, (void __user *) arg, sizeof(rq)))
 219                         return -EFAULT;
 220 
 221                 return bind_set(rq.raw_minor, rq.block_major, rq.block_minor);
 222 
 223         case RAW_GETBIND:
 224                 if (copy_from_user(&rq, (void __user *) arg, sizeof(rq)))
 225                         return -EFAULT;
 226 
 227                 err = bind_get(rq.raw_minor, &dev);
 228                 if (err)
 229                         return err;
 230 
 231                 rq.block_major = MAJOR(dev);
 232                 rq.block_minor = MINOR(dev);
 233 
 234                 if (copy_to_user((void __user *)arg, &rq, sizeof(rq)))
 235                         return -EFAULT;
 236 
 237                 return 0;
 238         }
 239 
 240         return -EINVAL;
 241 }
 242 
 243 #ifdef CONFIG_COMPAT
 244 struct raw32_config_request {
 245         compat_int_t    raw_minor;
 246         compat_u64      block_major;
 247         compat_u64      block_minor;
 248 };
 249 
 250 static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
 251                                 unsigned long arg)
 252 {
 253         struct raw32_config_request __user *user_req = compat_ptr(arg);
 254         struct raw32_config_request rq;
 255         dev_t dev;
 256         int err = 0;
 257 
 258         switch (cmd) {
 259         case RAW_SETBIND:
 260                 if (copy_from_user(&rq, user_req, sizeof(rq)))
 261                         return -EFAULT;
 262 
 263                 return bind_set(rq.raw_minor, rq.block_major, rq.block_minor);
 264 
 265         case RAW_GETBIND:
 266                 if (copy_from_user(&rq, user_req, sizeof(rq)))
 267                         return -EFAULT;
 268 
 269                 err = bind_get(rq.raw_minor, &dev);
 270                 if (err)
 271                         return err;
 272 
 273                 rq.block_major = MAJOR(dev);
 274                 rq.block_minor = MINOR(dev);
 275 
 276                 if (copy_to_user(user_req, &rq, sizeof(rq)))
 277                         return -EFAULT;
 278 
 279                 return 0;
 280         }
 281 
 282         return -EINVAL;
 283 }
 284 #endif
 285 
 286 static const struct file_operations raw_fops = {
 287         .read_iter      = blkdev_read_iter,
 288         .write_iter     = blkdev_write_iter,
 289         .fsync          = blkdev_fsync,
 290         .open           = raw_open,
 291         .release        = raw_release,
 292         .unlocked_ioctl = raw_ioctl,
 293         .llseek         = default_llseek,
 294         .owner          = THIS_MODULE,
 295 };
 296 
 297 static const struct file_operations raw_ctl_fops = {
 298         .unlocked_ioctl = raw_ctl_ioctl,
 299 #ifdef CONFIG_COMPAT
 300         .compat_ioctl   = raw_ctl_compat_ioctl,
 301 #endif
 302         .open           = raw_open,
 303         .owner          = THIS_MODULE,
 304         .llseek         = noop_llseek,
 305 };
 306 
 307 static struct cdev raw_cdev;
 308 
 309 static char *raw_devnode(struct device *dev, umode_t *mode)
 310 {
 311         return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
 312 }
 313 
 314 static int __init raw_init(void)
 315 {
 316         dev_t dev = MKDEV(RAW_MAJOR, 0);
 317         int ret;
 318 
 319         if (max_raw_minors < 1 || max_raw_minors > 65536) {
 320                 printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
 321                         " between 1 and 65536), using %d\n", MAX_RAW_MINORS);
 322                 max_raw_minors = MAX_RAW_MINORS;
 323         }
 324 
 325         raw_devices = vzalloc(array_size(max_raw_minors,
 326                                          sizeof(struct raw_device_data)));
 327         if (!raw_devices) {
 328                 printk(KERN_ERR "Not enough memory for raw device structures\n");
 329                 ret = -ENOMEM;
 330                 goto error;
 331         }
 332 
 333         ret = register_chrdev_region(dev, max_raw_minors, "raw");
 334         if (ret)
 335                 goto error;
 336 
 337         cdev_init(&raw_cdev, &raw_fops);
 338         ret = cdev_add(&raw_cdev, dev, max_raw_minors);
 339         if (ret)
 340                 goto error_region;
 341         raw_class = class_create(THIS_MODULE, "raw");
 342         if (IS_ERR(raw_class)) {
 343                 printk(KERN_ERR "Error creating raw class.\n");
 344                 cdev_del(&raw_cdev);
 345                 ret = PTR_ERR(raw_class);
 346                 goto error_region;
 347         }
 348         raw_class->devnode = raw_devnode;
 349         device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 350 
 351         return 0;
 352 
 353 error_region:
 354         unregister_chrdev_region(dev, max_raw_minors);
 355 error:
 356         vfree(raw_devices);
 357         return ret;
 358 }
 359 
 360 static void __exit raw_exit(void)
 361 {
 362         device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
 363         class_destroy(raw_class);
 364         cdev_del(&raw_cdev);
 365         unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
 366 }
 367 
 368 module_init(raw_init);
 369 module_exit(raw_exit);
 370 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */