| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/drivers/char/raw.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 27 | 28 | #include <linux/uaccess.h> |
|---|
| 28 | 29 | |
|---|
| 29 | 30 | struct raw_device_data { |
|---|
| 30 | | - struct block_device *binding; |
|---|
| 31 | + dev_t binding; |
|---|
| 32 | + struct block_device *bdev; |
|---|
| 31 | 33 | int inuse; |
|---|
| 32 | 34 | }; |
|---|
| 33 | 35 | |
|---|
| .. | .. |
|---|
| 36 | 38 | static DEFINE_MUTEX(raw_mutex); |
|---|
| 37 | 39 | static const struct file_operations raw_ctl_fops; /* forward declaration */ |
|---|
| 38 | 40 | |
|---|
| 39 | | -static int max_raw_minors = MAX_RAW_MINORS; |
|---|
| 41 | +static int max_raw_minors = CONFIG_MAX_RAW_DEVS; |
|---|
| 40 | 42 | |
|---|
| 41 | 43 | module_param(max_raw_minors, int, 0); |
|---|
| 42 | 44 | MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)"); |
|---|
| .. | .. |
|---|
| 62 | 64 | return 0; |
|---|
| 63 | 65 | } |
|---|
| 64 | 66 | |
|---|
| 67 | + pr_warn_ratelimited( |
|---|
| 68 | + "process %s (pid %d) is using the deprecated raw device\n" |
|---|
| 69 | + "support will be removed in Linux 5.14.\n", |
|---|
| 70 | + current->comm, current->pid); |
|---|
| 71 | + |
|---|
| 65 | 72 | mutex_lock(&raw_mutex); |
|---|
| 66 | 73 | |
|---|
| 67 | 74 | /* |
|---|
| 68 | 75 | * All we need to do on open is check that the device is bound. |
|---|
| 69 | 76 | */ |
|---|
| 70 | | - bdev = raw_devices[minor].binding; |
|---|
| 71 | 77 | err = -ENODEV; |
|---|
| 72 | | - if (!bdev) |
|---|
| 78 | + if (!raw_devices[minor].binding) |
|---|
| 73 | 79 | goto out; |
|---|
| 74 | | - bdgrab(bdev); |
|---|
| 75 | | - err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open); |
|---|
| 76 | | - if (err) |
|---|
| 80 | + bdev = blkdev_get_by_dev(raw_devices[minor].binding, |
|---|
| 81 | + filp->f_mode | FMODE_EXCL, raw_open); |
|---|
| 82 | + if (IS_ERR(bdev)) { |
|---|
| 83 | + err = PTR_ERR(bdev); |
|---|
| 77 | 84 | goto out; |
|---|
| 85 | + } |
|---|
| 78 | 86 | err = set_blocksize(bdev, bdev_logical_block_size(bdev)); |
|---|
| 79 | 87 | if (err) |
|---|
| 80 | 88 | goto out1; |
|---|
| .. | .. |
|---|
| 84 | 92 | file_inode(filp)->i_mapping = |
|---|
| 85 | 93 | bdev->bd_inode->i_mapping; |
|---|
| 86 | 94 | filp->private_data = bdev; |
|---|
| 95 | + raw_devices[minor].bdev = bdev; |
|---|
| 87 | 96 | mutex_unlock(&raw_mutex); |
|---|
| 88 | 97 | return 0; |
|---|
| 89 | 98 | |
|---|
| .. | .. |
|---|
| 104 | 113 | struct block_device *bdev; |
|---|
| 105 | 114 | |
|---|
| 106 | 115 | mutex_lock(&raw_mutex); |
|---|
| 107 | | - bdev = raw_devices[minor].binding; |
|---|
| 116 | + bdev = raw_devices[minor].bdev; |
|---|
| 108 | 117 | if (--raw_devices[minor].inuse == 0) |
|---|
| 109 | 118 | /* Here inode->i_mapping == bdev->bd_inode->i_mapping */ |
|---|
| 110 | 119 | inode->i_mapping = &inode->i_data; |
|---|
| .. | .. |
|---|
| 127 | 136 | static int bind_set(int number, u64 major, u64 minor) |
|---|
| 128 | 137 | { |
|---|
| 129 | 138 | dev_t dev = MKDEV(major, minor); |
|---|
| 139 | + dev_t raw = MKDEV(RAW_MAJOR, number); |
|---|
| 130 | 140 | struct raw_device_data *rawdev; |
|---|
| 131 | 141 | int err = 0; |
|---|
| 132 | 142 | |
|---|
| .. | .. |
|---|
| 160 | 170 | mutex_unlock(&raw_mutex); |
|---|
| 161 | 171 | return -EBUSY; |
|---|
| 162 | 172 | } |
|---|
| 163 | | - if (rawdev->binding) { |
|---|
| 164 | | - bdput(rawdev->binding); |
|---|
| 173 | + if (rawdev->binding) |
|---|
| 165 | 174 | module_put(THIS_MODULE); |
|---|
| 166 | | - } |
|---|
| 175 | + |
|---|
| 176 | + rawdev->binding = dev; |
|---|
| 167 | 177 | if (!dev) { |
|---|
| 168 | 178 | /* unbind */ |
|---|
| 169 | | - rawdev->binding = NULL; |
|---|
| 170 | | - device_destroy(raw_class, MKDEV(RAW_MAJOR, number)); |
|---|
| 179 | + device_destroy(raw_class, raw); |
|---|
| 171 | 180 | } else { |
|---|
| 172 | | - rawdev->binding = bdget(dev); |
|---|
| 173 | | - if (rawdev->binding == NULL) { |
|---|
| 174 | | - err = -ENOMEM; |
|---|
| 175 | | - } else { |
|---|
| 176 | | - dev_t raw = MKDEV(RAW_MAJOR, number); |
|---|
| 177 | | - __module_get(THIS_MODULE); |
|---|
| 178 | | - device_destroy(raw_class, raw); |
|---|
| 179 | | - device_create(raw_class, NULL, raw, NULL, |
|---|
| 180 | | - "raw%d", number); |
|---|
| 181 | | - } |
|---|
| 181 | + __module_get(THIS_MODULE); |
|---|
| 182 | + device_destroy(raw_class, raw); |
|---|
| 183 | + device_create(raw_class, NULL, raw, NULL, "raw%d", number); |
|---|
| 182 | 184 | } |
|---|
| 183 | 185 | mutex_unlock(&raw_mutex); |
|---|
| 184 | 186 | return err; |
|---|
| .. | .. |
|---|
| 186 | 188 | |
|---|
| 187 | 189 | static int bind_get(int number, dev_t *dev) |
|---|
| 188 | 190 | { |
|---|
| 189 | | - struct raw_device_data *rawdev; |
|---|
| 190 | | - struct block_device *bdev; |
|---|
| 191 | | - |
|---|
| 192 | 191 | if (number <= 0 || number >= max_raw_minors) |
|---|
| 193 | 192 | return -EINVAL; |
|---|
| 194 | | - |
|---|
| 195 | | - rawdev = &raw_devices[number]; |
|---|
| 196 | | - |
|---|
| 197 | | - mutex_lock(&raw_mutex); |
|---|
| 198 | | - bdev = rawdev->binding; |
|---|
| 199 | | - *dev = bdev ? bdev->bd_dev : 0; |
|---|
| 200 | | - mutex_unlock(&raw_mutex); |
|---|
| 193 | + *dev = raw_devices[number].binding; |
|---|
| 201 | 194 | return 0; |
|---|
| 202 | 195 | } |
|---|
| 203 | 196 | |
|---|
| .. | .. |
|---|
| 316 | 309 | int ret; |
|---|
| 317 | 310 | |
|---|
| 318 | 311 | if (max_raw_minors < 1 || max_raw_minors > 65536) { |
|---|
| 319 | | - printk(KERN_WARNING "raw: invalid max_raw_minors (must be" |
|---|
| 320 | | - " between 1 and 65536), using %d\n", MAX_RAW_MINORS); |
|---|
| 321 | | - max_raw_minors = MAX_RAW_MINORS; |
|---|
| 312 | + pr_warn("raw: invalid max_raw_minors (must be between 1 and 65536), using %d\n", |
|---|
| 313 | + CONFIG_MAX_RAW_DEVS); |
|---|
| 314 | + max_raw_minors = CONFIG_MAX_RAW_DEVS; |
|---|
| 322 | 315 | } |
|---|
| 323 | 316 | |
|---|
| 324 | 317 | raw_devices = vzalloc(array_size(max_raw_minors, |
|---|