Commit 08d41808362a3663c0856c9720ad940a61156fb5

Authored by Mike Isely
Committed by Mauro Carvalho Chehab
1 parent d94fc9a08e

V4L/DVB (4373): Correctly handle sysfs error leg file removal in pvrusb2

Take note of which sysfs files / groups that the pvrusb2 successfully
creates and only delete those specific items when tearing things
down.  (Previously we just blindly tore everything down every time.)

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

Showing 1 changed file with 50 additions and 12 deletions Side-by-side Diff

drivers/media/video/pvrusb2/pvrusb2-sysfs.c
... ... @@ -44,12 +44,16 @@
44 44 struct kobj_type ktype;
45 45 struct class_device_attribute attr_v4l_minor_number;
46 46 struct class_device_attribute attr_unit_number;
  47 + int v4l_minor_number_created_ok;
  48 + int unit_number_created_ok;
47 49 };
48 50  
49 51 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
50 52 struct pvr2_sysfs_debugifc {
51 53 struct class_device_attribute attr_debugcmd;
52 54 struct class_device_attribute attr_debuginfo;
  55 + int debugcmd_created_ok;
  56 + int debuginfo_created_ok;
53 57 };
54 58 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
55 59  
... ... @@ -67,6 +71,7 @@
67 71 struct pvr2_sysfs_ctl_item *item_next;
68 72 struct attribute *attr_gen[7];
69 73 struct attribute_group grp;
  74 + int created_ok;
70 75 char name[80];
71 76 };
72 77  
... ... @@ -487,6 +492,7 @@
487 492 struct pvr2_sysfs_func_set *fp;
488 493 struct pvr2_ctrl *cptr;
489 494 unsigned int cnt,acnt;
  495 + int ret;
490 496  
491 497 if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
492 498 return;
... ... @@ -589,7 +595,13 @@
589 595 cip->grp.name = cip->name;
590 596 cip->grp.attrs = cip->attr_gen;
591 597  
592   - sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
  598 + ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
  599 + if (ret) {
  600 + printk(KERN_WARNING "%s: sysfs_create_group error: %d\n",
  601 + __FUNCTION__, ret);
  602 + return;
  603 + }
  604 + cip->created_ok = !0;
593 605 }
594 606  
595 607 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
596 608  
597 609  
598 610  
599 611  
... ... @@ -616,22 +628,33 @@
616 628 dip->attr_debuginfo.show = debuginfo_show;
617 629 sfp->debugifc = dip;
618 630 ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
619   - if (ret < 0)
  631 + if (ret < 0) {
620 632 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
621 633 __FUNCTION__, ret);
  634 + } else {
  635 + dip->debugcmd_created_ok = !0;
  636 + }
622 637 ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
623   - if (ret < 0)
  638 + if (ret < 0) {
624 639 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
625 640 __FUNCTION__, ret);
  641 + } else {
  642 + dip->debuginfo_created_ok = !0;
  643 + }
626 644 }
627 645  
628 646  
629 647 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
630 648 {
631 649 if (!sfp->debugifc) return;
632   - class_device_remove_file(sfp->class_dev,
633   - &sfp->debugifc->attr_debuginfo);
634   - class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd);
  650 + if (sfp->debugifc->debuginfo_created_ok) {
  651 + class_device_remove_file(sfp->class_dev,
  652 + &sfp->debugifc->attr_debuginfo);
  653 + }
  654 + if (sfp->debugifc->debugcmd_created_ok) {
  655 + class_device_remove_file(sfp->class_dev,
  656 + &sfp->debugifc->attr_debugcmd);
  657 + }
635 658 kfree(sfp->debugifc);
636 659 sfp->debugifc = NULL;
637 660 }
... ... @@ -653,7 +676,9 @@
653 676 struct pvr2_sysfs_ctl_item *cip1,*cip2;
654 677 for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
655 678 cip2 = cip1->item_next;
656   - sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
  679 + if (cip1->created_ok) {
  680 + sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
  681 + }
657 682 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
658 683 kfree(cip1);
659 684 }
... ... @@ -683,8 +708,14 @@
683 708 pvr2_sysfs_tear_down_debugifc(sfp);
684 709 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
685 710 pvr2_sysfs_tear_down_controls(sfp);
686   - class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
687   - class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
  711 + if (sfp->v4l_minor_number_created_ok) {
  712 + class_device_remove_file(sfp->class_dev,
  713 + &sfp->attr_v4l_minor_number);
  714 + }
  715 + if (sfp->unit_number_created_ok) {
  716 + class_device_remove_file(sfp->class_dev,
  717 + &sfp->attr_unit_number);
  718 + }
688 719 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
689 720 sfp->class_dev->class_data = NULL;
690 721 class_device_unregister(sfp->class_dev);
691 722  
... ... @@ -756,10 +787,14 @@
756 787 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
757 788 sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
758 789 sfp->attr_v4l_minor_number.store = NULL;
759   - ret = class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
760   - if (ret < 0)
  790 + ret = class_device_create_file(sfp->class_dev,
  791 + &sfp->attr_v4l_minor_number);
  792 + if (ret < 0) {
761 793 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
762 794 __FUNCTION__, ret);
  795 + } else {
  796 + sfp->v4l_minor_number_created_ok = !0;
  797 + }
763 798  
764 799 sfp->attr_unit_number.attr.owner = THIS_MODULE;
765 800 sfp->attr_unit_number.attr.name = "unit_number";
766 801  
... ... @@ -767,9 +802,12 @@
767 802 sfp->attr_unit_number.show = unit_number_show;
768 803 sfp->attr_unit_number.store = NULL;
769 804 ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
770   - if (ret < 0)
  805 + if (ret < 0) {
771 806 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
772 807 __FUNCTION__, ret);
  808 + } else {
  809 + sfp->unit_number_created_ok = !0;
  810 + }
773 811  
774 812 pvr2_sysfs_add_controls(sfp);
775 813 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC