2727#include <media/tuner.h>
2828
2929static DEFINE_MUTEX (dvbdev_mutex );
30+ static LIST_HEAD (dvbdevfops_list );
3031static int dvbdev_debug ;
3132
3233module_param (dvbdev_debug , int , 0644 );
@@ -453,33 +454,61 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
453454 enum dvb_device_type type , int demux_sink_pads )
454455{
455456 struct dvb_device * dvbdev ;
456- struct file_operations * dvbdevfops ;
457+ struct file_operations * dvbdevfops = NULL ;
458+ struct dvbdevfops_node * node = NULL , * new_node = NULL ;
457459 struct device * clsdev ;
458460 int minor ;
459461 int id , ret ;
460462
461463 mutex_lock (& dvbdev_register_lock );
462464
463- if ((id = dvbdev_get_free_id (adap , type )) < 0 ){
465+ if ((id = dvbdev_get_free_id (adap , type )) < 0 ) {
464466 mutex_unlock (& dvbdev_register_lock );
465467 * pdvbdev = NULL ;
466468 pr_err ("%s: couldn't find free device id\n" , __func__ );
467469 return - ENFILE ;
468470 }
469471
470472 * pdvbdev = dvbdev = kzalloc (sizeof (* dvbdev ), GFP_KERNEL );
471-
472473 if (!dvbdev ){
473474 mutex_unlock (& dvbdev_register_lock );
474475 return - ENOMEM ;
475476 }
476477
477- dvbdevfops = kmemdup (template -> fops , sizeof (* dvbdevfops ), GFP_KERNEL );
478+ /*
479+ * When a device of the same type is probe()d more than once,
480+ * the first allocated fops are used. This prevents memory leaks
481+ * that can occur when the same device is probe()d repeatedly.
482+ */
483+ list_for_each_entry (node , & dvbdevfops_list , list_head ) {
484+ if (node -> fops -> owner == adap -> module &&
485+ node -> type == type &&
486+ node -> template == template ) {
487+ dvbdevfops = node -> fops ;
488+ break ;
489+ }
490+ }
478491
479- if (!dvbdevfops ){
480- kfree (dvbdev );
481- mutex_unlock (& dvbdev_register_lock );
482- return - ENOMEM ;
492+ if (dvbdevfops == NULL ) {
493+ dvbdevfops = kmemdup (template -> fops , sizeof (* dvbdevfops ), GFP_KERNEL );
494+ if (!dvbdevfops ) {
495+ kfree (dvbdev );
496+ mutex_unlock (& dvbdev_register_lock );
497+ return - ENOMEM ;
498+ }
499+
500+ new_node = kzalloc (sizeof (struct dvbdevfops_node ), GFP_KERNEL );
501+ if (!new_node ) {
502+ kfree (dvbdevfops );
503+ kfree (dvbdev );
504+ mutex_unlock (& dvbdev_register_lock );
505+ return - ENOMEM ;
506+ }
507+
508+ new_node -> fops = dvbdevfops ;
509+ new_node -> type = type ;
510+ new_node -> template = template ;
511+ list_add_tail (& new_node -> list_head , & dvbdevfops_list );
483512 }
484513
485514 memcpy (dvbdev , template , sizeof (struct dvb_device ));
@@ -490,20 +519,20 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
490519 dvbdev -> priv = priv ;
491520 dvbdev -> fops = dvbdevfops ;
492521 init_waitqueue_head (& dvbdev -> wait_queue );
493-
494522 dvbdevfops -> owner = adap -> module ;
495-
496523 list_add_tail (& dvbdev -> list_head , & adap -> device_list );
497-
498524 down_write (& minor_rwsem );
499525#ifdef CONFIG_DVB_DYNAMIC_MINORS
500526 for (minor = 0 ; minor < MAX_DVB_MINORS ; minor ++ )
501527 if (dvb_minors [minor ] == NULL )
502528 break ;
503-
504529 if (minor == MAX_DVB_MINORS ) {
530+ if (new_node ) {
531+ list_del (& new_node -> list_head );
532+ kfree (dvbdevfops );
533+ kfree (new_node );
534+ }
505535 list_del (& dvbdev -> list_head );
506- kfree (dvbdevfops );
507536 kfree (dvbdev );
508537 up_write (& minor_rwsem );
509538 mutex_unlock (& dvbdev_register_lock );
@@ -512,41 +541,47 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
512541#else
513542 minor = nums2minor (adap -> num , type , id );
514543#endif
515-
516544 dvbdev -> minor = minor ;
517545 dvb_minors [minor ] = dvb_device_get (dvbdev );
518546 up_write (& minor_rwsem );
519-
520547 ret = dvb_register_media_device (dvbdev , type , minor , demux_sink_pads );
521548 if (ret ) {
522549 pr_err ("%s: dvb_register_media_device failed to create the mediagraph\n" ,
523550 __func__ );
524-
551+ if (new_node ) {
552+ list_del (& new_node -> list_head );
553+ kfree (dvbdevfops );
554+ kfree (new_node );
555+ }
525556 dvb_media_device_free (dvbdev );
526557 list_del (& dvbdev -> list_head );
527- kfree (dvbdevfops );
528558 kfree (dvbdev );
529559 mutex_unlock (& dvbdev_register_lock );
530560 return ret ;
531561 }
532562
533- mutex_unlock (& dvbdev_register_lock );
534-
535563 clsdev = device_create (dvb_class , adap -> device ,
536564 MKDEV (DVB_MAJOR , minor ),
537565 dvbdev , "dvb%d.%s%d" , adap -> num , dnames [type ], id );
538566 if (IS_ERR (clsdev )) {
539567 pr_err ("%s: failed to create device dvb%d.%s%d (%ld)\n" ,
540568 __func__ , adap -> num , dnames [type ], id , PTR_ERR (clsdev ));
569+ if (new_node ) {
570+ list_del (& new_node -> list_head );
571+ kfree (dvbdevfops );
572+ kfree (new_node );
573+ }
541574 dvb_media_device_free (dvbdev );
542575 list_del (& dvbdev -> list_head );
543- kfree (dvbdevfops );
544576 kfree (dvbdev );
577+ mutex_unlock (& dvbdev_register_lock );
545578 return PTR_ERR (clsdev );
546579 }
580+
547581 dprintk ("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n" ,
548582 adap -> num , dnames [type ], id , minor , minor );
549583
584+ mutex_unlock (& dvbdev_register_lock );
550585 return 0 ;
551586}
552587EXPORT_SYMBOL (dvb_register_device );
@@ -575,7 +610,6 @@ static void dvb_free_device(struct kref *ref)
575610{
576611 struct dvb_device * dvbdev = container_of (ref , struct dvb_device , ref );
577612
578- kfree (dvbdev -> fops );
579613 kfree (dvbdev );
580614}
581615
@@ -1081,9 +1115,17 @@ static int __init init_dvbdev(void)
10811115
10821116static void __exit exit_dvbdev (void )
10831117{
1118+ struct dvbdevfops_node * node , * next ;
1119+
10841120 class_destroy (dvb_class );
10851121 cdev_del (& dvb_device_cdev );
10861122 unregister_chrdev_region (MKDEV (DVB_MAJOR , 0 ), MAX_DVB_MINORS );
1123+
1124+ list_for_each_entry_safe (node , next , & dvbdevfops_list , list_head ) {
1125+ list_del (& node -> list_head );
1126+ kfree (node -> fops );
1127+ kfree (node );
1128+ }
10871129}
10881130
10891131subsys_initcall (init_dvbdev );
0 commit comments