forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
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 }
....@@ -281,7 +277,7 @@
281277 dasd_put_device(base);
282278 return -EFAULT;
283279 }
284
- if (bdev != bdev->bd_contains) {
280
+ if (bdev_is_partition(bdev)) {
285281 pr_warn("%s: The specified DASD is a partition and cannot be formatted\n",
286282 dev_name(&base->cdev->dev));
287283 dasd_put_device(base);
....@@ -308,7 +304,7 @@
308304 base = dasd_device_from_gendisk(bdev->bd_disk);
309305 if (!base)
310306 return -ENODEV;
311
- if (bdev != bdev->bd_contains) {
307
+ if (bdev_is_partition(bdev)) {
312308 pr_warn("%s: The specified DASD is a partition and cannot be checked\n",
313309 dev_name(&base->cdev->dev));
314310 rc = -EINVAL;
....@@ -326,6 +322,59 @@
326322
327323 if (copy_to_user(argp, &cdata, sizeof(cdata)))
328324 rc = -EFAULT;
325
+
326
+out_err:
327
+ dasd_put_device(base);
328
+
329
+ return rc;
330
+}
331
+
332
+static int dasd_release_space(struct dasd_device *device,
333
+ struct format_data_t *rdata)
334
+{
335
+ if (!device->discipline->is_ese && !device->discipline->is_ese(device))
336
+ return -ENOTSUPP;
337
+ if (!device->discipline->release_space)
338
+ return -ENOTSUPP;
339
+
340
+ return device->discipline->release_space(device, rdata);
341
+}
342
+
343
+/*
344
+ * Release allocated space
345
+ */
346
+static int dasd_ioctl_release_space(struct block_device *bdev, void __user *argp)
347
+{
348
+ struct format_data_t rdata;
349
+ struct dasd_device *base;
350
+ int rc = 0;
351
+
352
+ if (!capable(CAP_SYS_ADMIN))
353
+ return -EACCES;
354
+ if (!argp)
355
+ return -EINVAL;
356
+
357
+ base = dasd_device_from_gendisk(bdev->bd_disk);
358
+ if (!base)
359
+ return -ENODEV;
360
+ if (base->features & DASD_FEATURE_READONLY ||
361
+ test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
362
+ rc = -EROFS;
363
+ goto out_err;
364
+ }
365
+ if (bdev_is_partition(bdev)) {
366
+ pr_warn("%s: The specified DASD is a partition and tracks cannot be released\n",
367
+ dev_name(&base->cdev->dev));
368
+ rc = -EINVAL;
369
+ goto out_err;
370
+ }
371
+
372
+ if (copy_from_user(&rdata, argp, sizeof(rdata))) {
373
+ rc = -EFAULT;
374
+ goto out_err;
375
+ }
376
+
377
+ rc = dasd_release_space(base, &rdata);
329378
330379 out_err:
331380 dasd_put_device(base);
....@@ -404,14 +453,14 @@
404453 /*
405454 * Return dasd information. Used for BIODASDINFO and BIODASDINFO2.
406455 */
407
-static int dasd_ioctl_information(struct dasd_block *block,
408
- unsigned int cmd, void __user *argp)
456
+static int __dasd_ioctl_information(struct dasd_block *block,
457
+ struct dasd_information2_t *dasd_info)
409458 {
410
- struct dasd_information2_t *dasd_info;
411459 struct subchannel_id sch_id;
412460 struct ccw_dev_id dev_id;
413461 struct dasd_device *base;
414462 struct ccw_device *cdev;
463
+ struct list_head *l;
415464 unsigned long flags;
416465 int rc;
417466
....@@ -419,15 +468,9 @@
419468 if (!base->discipline || !base->discipline->fill_info)
420469 return -EINVAL;
421470
422
- dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
423
- if (dasd_info == NULL)
424
- return -ENOMEM;
425
-
426471 rc = base->discipline->fill_info(base, dasd_info);
427
- if (rc) {
428
- kfree(dasd_info);
472
+ if (rc)
429473 return rc;
430
- }
431474
432475 cdev = base->cdev;
433476 ccw_device_get_id(cdev, &dev_id);
....@@ -462,32 +505,28 @@
462505
463506 memcpy(dasd_info->type, base->discipline->name, 4);
464507
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
- }
508
+ spin_lock_irqsave(&block->queue_lock, flags);
509
+ list_for_each(l, &base->ccw_queue)
510
+ dasd_info->chanq_len++;
511
+ spin_unlock_irqrestore(&block->queue_lock, flags);
512
+ return 0;
513
+}
482514
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;
515
+static int dasd_ioctl_information(struct dasd_block *block, void __user *argp,
516
+ size_t copy_size)
517
+{
518
+ struct dasd_information2_t *dasd_info;
519
+ int error;
520
+
521
+ dasd_info = kzalloc(sizeof(*dasd_info), GFP_KERNEL);
522
+ if (!dasd_info)
523
+ return -ENOMEM;
524
+
525
+ error = __dasd_ioctl_information(block, dasd_info);
526
+ if (!error && copy_to_user(argp, dasd_info, copy_size))
527
+ error = -EFAULT;
489528 kfree(dasd_info);
490
- return rc;
529
+ return error;
491530 }
492531
493532 /*
....@@ -501,7 +540,7 @@
501540
502541 if (!capable(CAP_SYS_ADMIN))
503542 return -EACCES;
504
- if (bdev != bdev->bd_contains)
543
+ if (bdev_is_partition(bdev))
505544 // ro setting is not allowed for partitions
506545 return -EINVAL;
507546 if (get_user(intval, (int __user *)argp))
....@@ -581,10 +620,12 @@
581620 rc = dasd_ioctl_check_format(bdev, argp);
582621 break;
583622 case BIODASDINFO:
584
- rc = dasd_ioctl_information(block, cmd, argp);
623
+ rc = dasd_ioctl_information(block, argp,
624
+ sizeof(struct dasd_information_t));
585625 break;
586626 case BIODASDINFO2:
587
- rc = dasd_ioctl_information(block, cmd, argp);
627
+ rc = dasd_ioctl_information(block, argp,
628
+ sizeof(struct dasd_information2_t));
588629 break;
589630 case BIODASDPRRD:
590631 rc = dasd_ioctl_read_profile(block, argp);
....@@ -607,6 +648,9 @@
607648 case BIODASDREADALLCMB:
608649 rc = dasd_ioctl_readall_cmb(block, cmd, argp);
609650 break;
651
+ case BIODASDRAS:
652
+ rc = dasd_ioctl_release_space(bdev, argp);
653
+ break;
610654 default:
611655 /* if the discipline has an ioctl method try it. */
612656 rc = -ENOTTY;
....@@ -616,3 +660,36 @@
616660 dasd_put_device(base);
617661 return rc;
618662 }
663
+
664
+
665
+/**
666
+ * dasd_biodasdinfo() - fill out the dasd information structure
667
+ * @disk [in]: pointer to gendisk structure that references a DASD
668
+ * @info [out]: pointer to the dasd_information2_t structure
669
+ *
670
+ * Provide access to DASD specific information.
671
+ * The gendisk structure is checked if it belongs to the DASD driver by
672
+ * comparing the gendisk->fops pointer.
673
+ * If it does not belong to the DASD driver -EINVAL is returned.
674
+ * Otherwise the provided dasd_information2_t structure is filled out.
675
+ *
676
+ * Returns:
677
+ * %0 on success and a negative error value on failure.
678
+ */
679
+int dasd_biodasdinfo(struct gendisk *disk, struct dasd_information2_t *info)
680
+{
681
+ struct dasd_device *base;
682
+ int error;
683
+
684
+ if (disk->fops != &dasd_device_operations)
685
+ return -EINVAL;
686
+
687
+ base = dasd_device_from_gendisk(disk);
688
+ if (!base)
689
+ return -ENODEV;
690
+ error = __dasd_ioctl_information(base->block, info);
691
+ dasd_put_device(base);
692
+ return error;
693
+}
694
+/* export that symbol_get in partition detection is possible */
695
+EXPORT_SYMBOL_GPL(dasd_biodasdinfo);