hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/media/dvb-core/dvbdev.c
....@@ -37,6 +37,7 @@
3737 #include <media/tuner.h>
3838
3939 static DEFINE_MUTEX(dvbdev_mutex);
40
+static LIST_HEAD(dvbdevfops_list);
4041 static int dvbdev_debug;
4142
4243 module_param(dvbdev_debug, int, 0644);
....@@ -107,7 +108,7 @@
107108 new_fops = fops_get(dvbdev->fops);
108109 if (!new_fops)
109110 goto fail;
110
- file->private_data = dvbdev;
111
+ file->private_data = dvb_device_get(dvbdev);
111112 replace_fops(file, new_fops);
112113 if (file->f_op->open)
113114 err = file->f_op->open(inode, file);
....@@ -171,6 +172,9 @@
171172 }
172173
173174 dvbdev->users++;
175
+
176
+ dvb_device_put(dvbdev);
177
+
174178 return 0;
175179 }
176180 EXPORT_SYMBOL(dvb_generic_release);
....@@ -342,6 +346,7 @@
342346 GFP_KERNEL);
343347 if (!dvbdev->pads) {
344348 kfree(dvbdev->entity);
349
+ dvbdev->entity = NULL;
345350 return -ENOMEM;
346351 }
347352 }
....@@ -458,14 +463,15 @@
458463 enum dvb_device_type type, int demux_sink_pads)
459464 {
460465 struct dvb_device *dvbdev;
461
- struct file_operations *dvbdevfops;
466
+ struct file_operations *dvbdevfops = NULL;
467
+ struct dvbdevfops_node *node = NULL, *new_node = NULL;
462468 struct device *clsdev;
463469 int minor;
464470 int id, ret;
465471
466472 mutex_lock(&dvbdev_register_lock);
467473
468
- if ((id = dvbdev_get_free_id (adap, type)) < 0){
474
+ if ((id = dvbdev_get_free_id (adap, type)) < 0) {
469475 mutex_unlock(&dvbdev_register_lock);
470476 *pdvbdev = NULL;
471477 pr_err("%s: couldn't find free device id\n", __func__);
....@@ -473,40 +479,69 @@
473479 }
474480
475481 *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
476
-
477482 if (!dvbdev){
478483 mutex_unlock(&dvbdev_register_lock);
479484 return -ENOMEM;
480485 }
481486
482
- dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
487
+ /*
488
+ * When a device of the same type is probe()d more than once,
489
+ * the first allocated fops are used. This prevents memory leaks
490
+ * that can occur when the same device is probe()d repeatedly.
491
+ */
492
+ list_for_each_entry(node, &dvbdevfops_list, list_head) {
493
+ if (node->fops->owner == adap->module &&
494
+ node->type == type &&
495
+ node->template == template) {
496
+ dvbdevfops = node->fops;
497
+ break;
498
+ }
499
+ }
483500
484
- if (!dvbdevfops){
485
- kfree (dvbdev);
486
- mutex_unlock(&dvbdev_register_lock);
487
- return -ENOMEM;
501
+ if (dvbdevfops == NULL) {
502
+ dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
503
+ if (!dvbdevfops) {
504
+ kfree(dvbdev);
505
+ mutex_unlock(&dvbdev_register_lock);
506
+ return -ENOMEM;
507
+ }
508
+
509
+ new_node = kzalloc(sizeof(struct dvbdevfops_node), GFP_KERNEL);
510
+ if (!new_node) {
511
+ kfree(dvbdevfops);
512
+ kfree(dvbdev);
513
+ mutex_unlock(&dvbdev_register_lock);
514
+ return -ENOMEM;
515
+ }
516
+
517
+ new_node->fops = dvbdevfops;
518
+ new_node->type = type;
519
+ new_node->template = template;
520
+ list_add_tail (&new_node->list_head, &dvbdevfops_list);
488521 }
489522
490523 memcpy(dvbdev, template, sizeof(struct dvb_device));
524
+ kref_init(&dvbdev->ref);
491525 dvbdev->type = type;
492526 dvbdev->id = id;
493527 dvbdev->adapter = adap;
494528 dvbdev->priv = priv;
495529 dvbdev->fops = dvbdevfops;
496530 init_waitqueue_head (&dvbdev->wait_queue);
497
-
498531 dvbdevfops->owner = adap->module;
499
-
500532 list_add_tail (&dvbdev->list_head, &adap->device_list);
501
-
502533 down_write(&minor_rwsem);
503534 #ifdef CONFIG_DVB_DYNAMIC_MINORS
504535 for (minor = 0; minor < MAX_DVB_MINORS; minor++)
505536 if (dvb_minors[minor] == NULL)
506537 break;
507
-
508538 if (minor == MAX_DVB_MINORS) {
509
- kfree(dvbdevfops);
539
+ if (new_node) {
540
+ list_del (&new_node->list_head);
541
+ kfree(dvbdevfops);
542
+ kfree(new_node);
543
+ }
544
+ list_del (&dvbdev->list_head);
510545 kfree(dvbdev);
511546 up_write(&minor_rwsem);
512547 mutex_unlock(&dvbdev_register_lock);
....@@ -515,24 +550,24 @@
515550 #else
516551 minor = nums2minor(adap->num, type, id);
517552 #endif
518
-
519553 dvbdev->minor = minor;
520
- dvb_minors[minor] = dvbdev;
554
+ dvb_minors[minor] = dvb_device_get(dvbdev);
521555 up_write(&minor_rwsem);
522
-
523556 ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
524557 if (ret) {
525558 pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
526559 __func__);
527
-
560
+ if (new_node) {
561
+ list_del (&new_node->list_head);
562
+ kfree(dvbdevfops);
563
+ kfree(new_node);
564
+ }
528565 dvb_media_device_free(dvbdev);
529
- kfree(dvbdevfops);
566
+ list_del (&dvbdev->list_head);
530567 kfree(dvbdev);
531568 mutex_unlock(&dvbdev_register_lock);
532569 return ret;
533570 }
534
-
535
- mutex_unlock(&dvbdev_register_lock);
536571
537572 clsdev = device_create(dvb_class, adap->device,
538573 MKDEV(DVB_MAJOR, minor),
....@@ -540,11 +575,22 @@
540575 if (IS_ERR(clsdev)) {
541576 pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
542577 __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
578
+ if (new_node) {
579
+ list_del (&new_node->list_head);
580
+ kfree(dvbdevfops);
581
+ kfree(new_node);
582
+ }
583
+ dvb_media_device_free(dvbdev);
584
+ list_del (&dvbdev->list_head);
585
+ kfree(dvbdev);
586
+ mutex_unlock(&dvbdev_register_lock);
543587 return PTR_ERR(clsdev);
544588 }
589
+
545590 dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
546591 adap->num, dnames[type], id, minor, minor);
547592
593
+ mutex_unlock(&dvbdev_register_lock);
548594 return 0;
549595 }
550596 EXPORT_SYMBOL(dvb_register_device);
....@@ -557,6 +603,7 @@
557603
558604 down_write(&minor_rwsem);
559605 dvb_minors[dvbdev->minor] = NULL;
606
+ dvb_device_put(dvbdev);
560607 up_write(&minor_rwsem);
561608
562609 dvb_media_device_free(dvbdev);
....@@ -568,21 +615,33 @@
568615 EXPORT_SYMBOL(dvb_remove_device);
569616
570617
571
-void dvb_free_device(struct dvb_device *dvbdev)
618
+static void dvb_free_device(struct kref *ref)
572619 {
573
- if (!dvbdev)
574
- return;
620
+ struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
575621
576
- kfree (dvbdev->fops);
577622 kfree (dvbdev);
578623 }
579
-EXPORT_SYMBOL(dvb_free_device);
624
+
625
+
626
+struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
627
+{
628
+ kref_get(&dvbdev->ref);
629
+ return dvbdev;
630
+}
631
+EXPORT_SYMBOL(dvb_device_get);
632
+
633
+
634
+void dvb_device_put(struct dvb_device *dvbdev)
635
+{
636
+ if (dvbdev)
637
+ kref_put(&dvbdev->ref, dvb_free_device);
638
+}
580639
581640
582641 void dvb_unregister_device(struct dvb_device *dvbdev)
583642 {
584643 dvb_remove_device(dvbdev);
585
- dvb_free_device(dvbdev);
644
+ dvb_device_put(dvbdev);
586645 }
587646 EXPORT_SYMBOL(dvb_unregister_device);
588647
....@@ -1065,9 +1124,17 @@
10651124
10661125 static void __exit exit_dvbdev(void)
10671126 {
1127
+ struct dvbdevfops_node *node, *next;
1128
+
10681129 class_destroy(dvb_class);
10691130 cdev_del(&dvb_device_cdev);
10701131 unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
1132
+
1133
+ list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) {
1134
+ list_del (&node->list_head);
1135
+ kfree(node->fops);
1136
+ kfree(node);
1137
+ }
10711138 }
10721139
10731140 subsys_initcall(init_dvbdev);