Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

raw: don't keep unopened block device around

Turn binding into a normal dev_t as the struct block device doesn't
buy us anything and use blkdev_open_by_dev to actually open it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
5a56ad78 0fc66c9d

+19 -32
+19 -32
drivers/char/raw.c
··· 28 28 #include <linux/uaccess.h> 29 29 30 30 struct raw_device_data { 31 - struct block_device *binding; 31 + dev_t binding; 32 + struct block_device *bdev; 32 33 int inuse; 33 34 }; 34 35 ··· 74 73 /* 75 74 * All we need to do on open is check that the device is bound. 76 75 */ 77 - bdev = raw_devices[minor].binding; 78 76 err = -ENODEV; 79 - if (!bdev) 77 + if (!raw_devices[minor].binding) 80 78 goto out; 81 - bdgrab(bdev); 82 - err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open); 83 - if (err) 79 + bdev = blkdev_get_by_dev(raw_devices[minor].binding, 80 + filp->f_mode | FMODE_EXCL, raw_open); 81 + if (IS_ERR(bdev)) { 82 + err = PTR_ERR(bdev); 84 83 goto out; 84 + } 85 85 err = set_blocksize(bdev, bdev_logical_block_size(bdev)); 86 86 if (err) 87 87 goto out1; ··· 92 90 file_inode(filp)->i_mapping = 93 91 bdev->bd_inode->i_mapping; 94 92 filp->private_data = bdev; 93 + raw_devices[minor].bdev = bdev; 95 94 mutex_unlock(&raw_mutex); 96 95 return 0; 97 96 ··· 113 110 struct block_device *bdev; 114 111 115 112 mutex_lock(&raw_mutex); 116 - bdev = raw_devices[minor].binding; 113 + bdev = raw_devices[minor].bdev; 117 114 if (--raw_devices[minor].inuse == 0) 118 115 /* Here inode->i_mapping == bdev->bd_inode->i_mapping */ 119 116 inode->i_mapping = &inode->i_data; ··· 136 133 static int bind_set(int number, u64 major, u64 minor) 137 134 { 138 135 dev_t dev = MKDEV(major, minor); 136 + dev_t raw = MKDEV(RAW_MAJOR, number); 139 137 struct raw_device_data *rawdev; 140 138 int err = 0; 141 139 ··· 170 166 mutex_unlock(&raw_mutex); 171 167 return -EBUSY; 172 168 } 173 - if (rawdev->binding) { 174 - bdput(rawdev->binding); 169 + if (rawdev->binding) 175 170 module_put(THIS_MODULE); 176 - } 171 + 172 + rawdev->binding = dev; 177 173 if (!dev) { 178 174 /* unbind */ 179 - rawdev->binding = NULL; 180 - device_destroy(raw_class, MKDEV(RAW_MAJOR, number)); 175 + device_destroy(raw_class, raw); 181 176 } else { 182 - rawdev->binding = bdget(dev); 183 - if (rawdev->binding == NULL) { 184 - err = -ENOMEM; 185 - } else { 186 - dev_t raw = MKDEV(RAW_MAJOR, number); 187 - __module_get(THIS_MODULE); 188 - device_destroy(raw_class, raw); 189 - device_create(raw_class, NULL, raw, NULL, 190 - "raw%d", number); 191 - } 177 + __module_get(THIS_MODULE); 178 + device_destroy(raw_class, raw); 179 + device_create(raw_class, NULL, raw, NULL, "raw%d", number); 192 180 } 193 181 mutex_unlock(&raw_mutex); 194 182 return err; ··· 188 192 189 193 static int bind_get(int number, dev_t *dev) 190 194 { 191 - struct raw_device_data *rawdev; 192 - struct block_device *bdev; 193 - 194 195 if (number <= 0 || number >= max_raw_minors) 195 196 return -EINVAL; 196 - 197 - rawdev = &raw_devices[number]; 198 - 199 - mutex_lock(&raw_mutex); 200 - bdev = rawdev->binding; 201 - *dev = bdev ? bdev->bd_dev : 0; 202 - mutex_unlock(&raw_mutex); 197 + *dev = raw_devices[number].binding; 203 198 return 0; 204 199 } 205 200