1 #include <linux/capability.h> 2 #include <linux/blkdev.h> 3 #include <linux/blkpg.h> 4 #include <linux/hdreg.h> 5 #include <linux/backing-dev.h> 6 #include <linux/buffer_head.h> 7 #include <linux/smp_lock.h> 8 #include <linux/blktrace_api.h> 9 #include <asm/uaccess.h> 10 11 static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg) 12 { 13 struct block_device *bdevp; 14 struct gendisk *disk; 15 struct hd_struct *part; 16 struct blkpg_ioctl_arg a; 17 struct blkpg_partition p; 18 struct disk_part_iter piter; 19 long long start, length; 20 int partno; 21 int err; 22 23 if (!capable(CAP_SYS_ADMIN)) 24 return -EACCES; 25 if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) 26 return -EFAULT; 27 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) 28 return -EFAULT; 29 disk = bdev->bd_disk; 30 if (bdev != bdev->bd_contains) 31 return -EINVAL; 32 partno = p.pno; 33 if (partno <= 0) 34 return -EINVAL; 35 switch (a.op) { 36 case BLKPG_ADD_PARTITION: 37 start = p.start >> 9; 38 length = p.length >> 9; 39 /* check for fit in a hd_struct */ 40 if (sizeof(sector_t) == sizeof(long) && 41 sizeof(long long) > sizeof(long)) { 42 long pstart = start, plength = length; 43 if (pstart != start || plength != length 44 || pstart < 0 || plength < 0) 45 return -EINVAL; 46 } 47 48 mutex_lock(&bdev->bd_mutex); 49 50 /* overlap? */ 51 disk_part_iter_init(&piter, disk, 52 DISK_PITER_INCL_EMPTY); 53 while ((part = disk_part_iter_next(&piter))) { 54 if (!(start + length <= part->start_sect || 55 start >= part->start_sect + part->nr_sects)) { 56 disk_part_iter_exit(&piter); 57 mutex_unlock(&bdev->bd_mutex); 58 return -EBUSY; 59 } 60 } 61 disk_part_iter_exit(&piter); 62 63 /* all seems OK */ 64 err = add_partition(disk, partno, start, length, 65 ADDPART_FLAG_NONE); 66 mutex_unlock(&bdev->bd_mutex); 67 return err; 68 case BLKPG_DEL_PARTITION: 69 part = disk_get_part(disk, partno); 70 if (!part) 71 return -ENXIO; 72 73 bdevp = bdget(part_devt(part)); 74 disk_put_part(part); 75 if (!bdevp) 76 return -ENOMEM; 77 78 mutex_lock(&bdevp->bd_mutex); 79 if (bdevp->bd_openers) { 80 mutex_unlock(&bdevp->bd_mutex); 81 bdput(bdevp); 82 return -EBUSY; 83 } 84 /* all seems OK */ 85 fsync_bdev(bdevp); 86 invalidate_bdev(bdevp); 87 88 mutex_lock_nested(&bdev->bd_mutex, 1); 89 delete_partition(disk, partno); 90 mutex_unlock(&bdev->bd_mutex); 91 mutex_unlock(&bdevp->bd_mutex); 92 bdput(bdevp); 93 94 return 0; 95 default: 96 return -EINVAL; 97 } 98 } 99 100 static int blkdev_reread_part(struct block_device *bdev) 101 { 102 struct gendisk *disk = bdev->bd_disk; 103 int res; 104 105 if (!disk_partitionable(disk) || bdev != bdev->bd_contains) 106 return -EINVAL; 107 if (!capable(CAP_SYS_ADMIN)) 108 return -EACCES; 109 if (!mutex_trylock(&bdev->bd_mutex)) 110 return -EBUSY; 111 res = rescan_partitions(disk, bdev); 112 mutex_unlock(&bdev->bd_mutex); 113 return res; 114 } 115 116 static void blk_ioc_discard_endio(struct bio *bio, int err) 117 { 118 if (err) { 119 if (err == -EOPNOTSUPP) 120 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); 121 clear_bit(BIO_UPTODATE, &bio->bi_flags); 122 } 123 complete(bio->bi_private); 124 } 125 126 static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, 127 uint64_t len) 128 { 129 struct request_queue *q = bdev_get_queue(bdev); 130 int ret = 0; 131 132 if (start & 511) 133 return -EINVAL; 134 if (len & 511) 135 return -EINVAL; 136 start >>= 9; 137 len >>= 9; 138 139 if (start + len > (bdev->bd_inode->i_size >> 9)) 140 return -EINVAL; 141 142 if (!q->prepare_discard_fn) 143 return -EOPNOTSUPP; 144 145 while (len && !ret) { 146 DECLARE_COMPLETION_ONSTACK(wait); 147 struct bio *bio; 148 149 bio = bio_alloc(GFP_KERNEL, 0); 150 if (!bio) 151 return -ENOMEM; 152 153 bio->bi_end_io = blk_ioc_discard_endio; 154 bio->bi_bdev = bdev; 155 bio->bi_private = &wait; 156 bio->bi_sector = start; 157 158 if (len > q->max_hw_sectors) { 159 bio->bi_size = q->max_hw_sectors << 9; 160 len -= q->max_hw_sectors; 161 start += q->max_hw_sectors; 162 } else { 163 bio->bi_size = len << 9; 164 len = 0; 165 } 166 submit_bio(DISCARD_NOBARRIER, bio); 167 168 wait_for_completion(&wait); 169 170 if (bio_flagged(bio, BIO_EOPNOTSUPP)) 171 ret = -EOPNOTSUPP; 172 else if (!bio_flagged(bio, BIO_UPTODATE)) 173 ret = -EIO; 174 bio_put(bio); 175 } 176 return ret; 177 } 178 179 static int put_ushort(unsigned long arg, unsigned short val) 180 { 181 return put_user(val, (unsigned short __user *)arg); 182 } 183 184 static int put_int(unsigned long arg, int val) 185 { 186 return put_user(val, (int __user *)arg); 187 } 188 189 static int put_long(unsigned long arg, long val) 190 { 191 return put_user(val, (long __user *)arg); 192 } 193 194 static int put_ulong(unsigned long arg, unsigned long val) 195 { 196 return put_user(val, (unsigned long __user *)arg); 197 } 198 199 static int put_u64(unsigned long arg, u64 val) 200 { 201 return put_user(val, (u64 __user *)arg); 202 } 203 204 int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, 205 unsigned cmd, unsigned long arg) 206 { 207 struct gendisk *disk = bdev->bd_disk; 208 int ret; 209 210 if (disk->fops->ioctl) 211 return disk->fops->ioctl(bdev, mode, cmd, arg); 212 213 if (disk->fops->locked_ioctl) { 214 lock_kernel(); 215 ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg); 216 unlock_kernel(); 217 return ret; 218 } 219 220 return -ENOTTY; 221 } 222 /* 223 * For the record: _GPL here is only because somebody decided to slap it 224 * on the previous export. Sheer idiocy, since it wasn't copyrightable 225 * at all and could be open-coded without any exports by anybody who cares. 226 */ 227 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); 228 229 /* 230 * always keep this in sync with compat_blkdev_ioctl() and 231 * compat_blkdev_locked_ioctl() 232 */ 233 int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, 234 unsigned long arg) 235 { 236 struct gendisk *disk = bdev->bd_disk; 237 struct backing_dev_info *bdi; 238 loff_t size; 239 int ret, n; 240 241 switch(cmd) { 242 case BLKFLSBUF: 243 if (!capable(CAP_SYS_ADMIN)) 244 return -EACCES; 245 246 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 247 /* -EINVAL to handle old uncorrected drivers */ 248 if (ret != -EINVAL && ret != -ENOTTY) 249 return ret; 250 251 lock_kernel(); 252 fsync_bdev(bdev); 253 invalidate_bdev(bdev); 254 unlock_kernel(); 255 return 0; 256 257 case BLKROSET: 258 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 259 /* -EINVAL to handle old uncorrected drivers */ 260 if (ret != -EINVAL && ret != -ENOTTY) 261 return ret; 262 if (!capable(CAP_SYS_ADMIN)) 263 return -EACCES; 264 if (get_user(n, (int __user *)(arg))) 265 return -EFAULT; 266 lock_kernel(); 267 set_device_ro(bdev, n); 268 unlock_kernel(); 269 return 0; 270 271 case BLKDISCARD: { 272 uint64_t range[2]; 273 274 if (!(mode & FMODE_WRITE)) 275 return -EBADF; 276 277 if (copy_from_user(range, (void __user *)arg, sizeof(range))) 278 return -EFAULT; 279 280 return blk_ioctl_discard(bdev, range[0], range[1]); 281 } 282 283 case HDIO_GETGEO: { 284 struct hd_geometry geo; 285 286 if (!arg) 287 return -EINVAL; 288 if (!disk->fops->getgeo) 289 return -ENOTTY; 290 291 /* 292 * We need to set the startsect first, the driver may 293 * want to override it. 294 */ 295 geo.start = get_start_sect(bdev); 296 ret = disk->fops->getgeo(bdev, &geo); 297 if (ret) 298 return ret; 299 if (copy_to_user((struct hd_geometry __user *)arg, &geo, 300 sizeof(geo))) 301 return -EFAULT; 302 return 0; 303 } 304 case BLKRAGET: 305 case BLKFRAGET: 306 if (!arg) 307 return -EINVAL; 308 bdi = blk_get_backing_dev_info(bdev); 309 if (bdi == NULL) 310 return -ENOTTY; 311 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); 312 case BLKROGET: 313 return put_int(arg, bdev_read_only(bdev) != 0); 314 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ 315 return put_int(arg, block_size(bdev)); 316 case BLKSSZGET: /* get block device hardware sector size */ 317 return put_int(arg, bdev_hardsect_size(bdev)); 318 case BLKSECTGET: 319 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors); 320 case BLKRASET: 321 case BLKFRASET: 322 if(!capable(CAP_SYS_ADMIN)) 323 return -EACCES; 324 bdi = blk_get_backing_dev_info(bdev); 325 if (bdi == NULL) 326 return -ENOTTY; 327 lock_kernel(); 328 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 329 unlock_kernel(); 330 return 0; 331 case BLKBSZSET: 332 /* set the logical block size */ 333 if (!capable(CAP_SYS_ADMIN)) 334 return -EACCES; 335 if (!arg) 336 return -EINVAL; 337 if (get_user(n, (int __user *) arg)) 338 return -EFAULT; 339 if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0) 340 return -EBUSY; 341 ret = set_blocksize(bdev, n); 342 if (!(mode & FMODE_EXCL)) 343 bd_release(bdev); 344 return ret; 345 case BLKPG: 346 lock_kernel(); 347 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); 348 unlock_kernel(); 349 break; 350 case BLKRRPART: 351 lock_kernel(); 352 ret = blkdev_reread_part(bdev); 353 unlock_kernel(); 354 break; 355 case BLKGETSIZE: 356 size = bdev->bd_inode->i_size; 357 if ((size >> 9) > ~0UL) 358 return -EFBIG; 359 return put_ulong(arg, size >> 9); 360 case BLKGETSIZE64: 361 return put_u64(arg, bdev->bd_inode->i_size); 362 case BLKTRACESTART: 363 case BLKTRACESTOP: 364 case BLKTRACESETUP: 365 case BLKTRACETEARDOWN: 366 lock_kernel(); 367 ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); 368 unlock_kernel(); 369 break; 370 default: 371 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 372 } 373 return ret; 374 } 375 EXPORT_SYMBOL_GPL(blkdev_ioctl); 376