hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/s390/block/dasd_ioctl.c
....@@ -22,6 +22,7 @@
2222 #include <asm/schid.h>
2323 #include <asm/cmb.h>
2424 #include <linux/uaccess.h>
25
+#include <linux/dasd_mod.h>
2526
2627 /* This is ugly... */
2728 #define PRINTK_HEADER "dasd_ioctl:"
....@@ -54,10 +55,7 @@
5455
5556 dasd_enable_device(base);
5657 /* Formatting the dasd device can change the capacity. */
57
- mutex_lock(&bdev->bd_mutex);
58
- i_size_write(bdev->bd_inode,
59
- (loff_t)get_capacity(base->block->gdp) << 9);
60
- mutex_unlock(&bdev->bd_mutex);
58
+ bd_set_nr_sectors(bdev, get_capacity(base->block->gdp));
6159 dasd_put_device(base);
6260 return 0;
6361 }
....@@ -90,9 +88,7 @@
9088 * Set i_size to zero, since read, write, etc. check against this
9189 * value.
9290 */
93
- mutex_lock(&bdev->bd_mutex);
94
- i_size_write(bdev->bd_inode, 0);
95
- mutex_unlock(&bdev->bd_mutex);
91
+ bd_set_nr_sectors(bdev, 0);
9692 dasd_put_device(base);
9793 return 0;
9894 }
....@@ -137,6 +133,7 @@
137133 spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
138134
139135 dasd_schedule_block_bh(block);
136
+ dasd_schedule_device_bh(base);
140137 return 0;
141138 }
142139
....@@ -281,7 +278,7 @@
281278 dasd_put_device(base);
282279 return -EFAULT;
283280 }
284
- if (bdev != bdev->bd_contains) {
281
+ if (bdev_is_partition(bdev)) {
285282 pr_warn("%s: The specified DASD is a partition and cannot be formatted\n",
286283 dev_name(&base->cdev->dev));
287284 dasd_put_device(base);
....@@ -308,7 +305,7 @@
308305 base = dasd_device_from_gendisk(bdev->bd_disk);
309306 if (!base)
310307 return -ENODEV;
311
- if (bdev != bdev->bd_contains) {
308
+ if (bdev_is_partition(bdev)) {
312309 pr_warn("%s: The specified DASD is a partition and cannot be checked\n",
313310 dev_name(&base->cdev->dev));
314311 rc = -EINVAL;
....@@ -326,6 +323,59 @@
326323
327324 if (copy_to_user(argp, &cdata, sizeof(cdata)))
328325 rc = -EFAULT;
326
+
327
+out_err:
328
+ dasd_put_device(base);
329
+
330
+ return rc;
331
+}
332
+
333
+static int dasd_release_space(struct dasd_device *device,
334
+ struct format_data_t *rdata)
335
+{
336
+ if (!device->discipline->is_ese && !device->discipline->is_ese(device))
337
+ return -ENOTSUPP;
338
+ if (!device->discipline->release_space)
339
+ return -ENOTSUPP;
340
+
341
+ return device->discipline->release_space(device, rdata);
342
+}
343
+
344
+/*
345
+ * Release allocated space
346
+ */
347
+static int dasd_ioctl_release_space(struct block_device *bdev, void __user *argp)
348
+{
349
+ struct format_data_t rdata;
350
+ struct dasd_device *base;
351
+ int rc = 0;
352
+
353
+ if (!capable(CAP_SYS_ADMIN))
354
+ return -EACCES;
355
+ if (!argp)
356
+ return -EINVAL;
357
+
358
+ base = dasd_device_from_gendisk(bdev->bd_disk);
359
+ if (!base)
360
+ return -ENODEV;
361
+ if (base->features & DASD_FEATURE_READONLY ||
362
+ test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
363
+ rc = -EROFS;
364
+ goto out_err;
365
+ }
366
+ if (bdev_is_partition(bdev)) {
367
+ pr_warn("%s: The specified DASD is a partition and tracks cannot be released\n",
368
+ dev_name(&base->cdev->dev));
369
+ rc = -EINVAL;
370
+ goto out_err;
371
+ }
372
+
373
+ if (copy_from_user(&rdata, argp, sizeof(rdata))) {
374
+ rc = -EFAULT;
375
+ goto out_err;
376
+ }
377
+
378
+ rc = dasd_release_space(base, &rdata);
329379
330380 out_err:
331381 dasd_put_device(base);
....@@ -404,14 +454,14 @@
404454 /*
405455 * Return dasd information. Used for BIODASDINFO and BIODASDINFO2.
406456 */
407
-static int dasd_ioctl_information(struct dasd_block *block,
408
- unsigned int cmd, void __user *argp)
457
+static int __dasd_ioctl_information(struct dasd_block *block,
458
+ struct dasd_information2_t *dasd_info)
409459 {
410
- struct dasd_information2_t *dasd_info;
411460 struct subchannel_id sch_id;
412461 struct ccw_dev_id dev_id;
413462 struct dasd_device *base;
414463 struct ccw_device *cdev;
464
+ struct list_head *l;
415465 unsigned long flags;
416466 int rc;
417467
....@@ -419,15 +469,9 @@
419469 if (!base->discipline || !base->discipline->fill_info)
420470 return -EINVAL;
421471
422
- dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
423
- if (dasd_info == NULL)
424
- return -ENOMEM;
425
-
426472 rc = base->discipline->fill_info(base, dasd_info);
427
- if (rc) {
428
- kfree(dasd_info);
473
+ if (rc)
429474 return rc;
430
- }
431475
432476 cdev = base->cdev;
433477 ccw_device_get_id(cdev, &dev_id);
....@@ -462,32 +506,28 @@
462506
463507 memcpy(dasd_info->type, base->discipline->name, 4);
464508
465
- if (block->request_queue->request_fn) {
466
- struct list_head *l;
467
-#ifdef DASD_EXTENDED_PROFILING
468
- {
469
- struct list_head *l;
470
- spin_lock_irqsave(&block->lock, flags);
471
- list_for_each(l, &block->request_queue->queue_head)
472
- dasd_info->req_queue_len++;
473
- spin_unlock_irqrestore(&block->lock, flags);
474
- }
475
-#endif /* DASD_EXTENDED_PROFILING */
476
- spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
477
- list_for_each(l, &base->ccw_queue)
478
- dasd_info->chanq_len++;
479
- spin_unlock_irqrestore(get_ccwdev_lock(base->cdev),
480
- flags);
481
- }
509
+ spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
510
+ list_for_each(l, &base->ccw_queue)
511
+ dasd_info->chanq_len++;
512
+ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
513
+ return 0;
514
+}
482515
483
- rc = 0;
484
- if (copy_to_user(argp, dasd_info,
485
- ((cmd == (unsigned int) BIODASDINFO2) ?
486
- sizeof(struct dasd_information2_t) :
487
- sizeof(struct dasd_information_t))))
488
- rc = -EFAULT;
516
+static int dasd_ioctl_information(struct dasd_block *block, void __user *argp,
517
+ size_t copy_size)
518
+{
519
+ struct dasd_information2_t *dasd_info;
520
+ int error;
521
+
522
+ dasd_info = kzalloc(sizeof(*dasd_info), GFP_KERNEL);
523
+ if (!dasd_info)
524
+ return -ENOMEM;
525
+
526
+ error = __dasd_ioctl_information(block, dasd_info);
527
+ if (!error && copy_to_user(argp, dasd_info, copy_size))
528
+ error = -EFAULT;
489529 kfree(dasd_info);
490
- return rc;
530
+ return error;
491531 }
492532
493533 /*
....@@ -501,7 +541,7 @@
501541
502542 if (!capable(CAP_SYS_ADMIN))
503543 return -EACCES;
504
- if (bdev != bdev->bd_contains)
544
+ if (bdev_is_partition(bdev))
505545 // ro setting is not allowed for partitions
506546 return -EINVAL;
507547 if (get_user(intval, (int __user *)argp))
....@@ -581,10 +621,12 @@
581621 rc = dasd_ioctl_check_format(bdev, argp);
582622 break;
583623 case BIODASDINFO:
584
- rc = dasd_ioctl_information(block, cmd, argp);
624
+ rc = dasd_ioctl_information(block, argp,
625
+ sizeof(struct dasd_information_t));
585626 break;
586627 case BIODASDINFO2:
587
- rc = dasd_ioctl_information(block, cmd, argp);
628
+ rc = dasd_ioctl_information(block, argp,
629
+ sizeof(struct dasd_information2_t));
588630 break;
589631 case BIODASDPRRD:
590632 rc = dasd_ioctl_read_profile(block, argp);
....@@ -607,6 +649,9 @@
607649 case BIODASDREADALLCMB:
608650 rc = dasd_ioctl_readall_cmb(block, cmd, argp);
609651 break;
652
+ case BIODASDRAS:
653
+ rc = dasd_ioctl_release_space(bdev, argp);
654
+ break;
610655 default:
611656 /* if the discipline has an ioctl method try it. */
612657 rc = -ENOTTY;
....@@ -616,3 +661,36 @@
616661 dasd_put_device(base);
617662 return rc;
618663 }
664
+
665
+
666
+/**
667
+ * dasd_biodasdinfo() - fill out the dasd information structure
668
+ * @disk [in]: pointer to gendisk structure that references a DASD
669
+ * @info [out]: pointer to the dasd_information2_t structure
670
+ *
671
+ * Provide access to DASD specific information.
672
+ * The gendisk structure is checked if it belongs to the DASD driver by
673
+ * comparing the gendisk->fops pointer.
674
+ * If it does not belong to the DASD driver -EINVAL is returned.
675
+ * Otherwise the provided dasd_information2_t structure is filled out.
676
+ *
677
+ * Returns:
678
+ * %0 on success and a negative error value on failure.
679
+ */
680
+int dasd_biodasdinfo(struct gendisk *disk, struct dasd_information2_t *info)
681
+{
682
+ struct dasd_device *base;
683
+ int error;
684
+
685
+ if (disk->fops != &dasd_device_operations)
686
+ return -EINVAL;
687
+
688
+ base = dasd_device_from_gendisk(disk);
689
+ if (!base)
690
+ return -ENODEV;
691
+ error = __dasd_ioctl_information(base->block, info);
692
+ dasd_put_device(base);
693
+ return error;
694
+}
695
+/* export that symbol_get in partition detection is possible */
696
+EXPORT_SYMBOL_GPL(dasd_biodasdinfo);