[RFC PATCH 2.6.18-rc4-mm1] hwmon: unchecked return status fixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,

> Attached is a patch for 2.6.18-rc4 as well as the complete driver
> (w83627ehf.c). It tests the return value when device_create_file() is
> called. I would like to add sysfs_create_group() calls with another
> patch. Anyone who would like to test the patch, please do.

I see very little benefit if making two separate patches for error
checking and grouping. Both will touch the very same code. Let's get it
right at once.

Also, when sending patches to the list, please set the attachement type
to text/plain rather than application/octet-stream. It will make it way
easier for people to read it.

> Sylvain, if you are running a 2.4-series kernel, take a look at
> i2c-isa_return_attach_adapter.patch as well (in this thread). I do not
> know if this will backport to the 2.4 kernel successfully.

No, it will not. Back in 2.4 i2c-isa was considered almost as a regular
i2c adapter, and you can't prevent a chip driver from loading just
because it failed to register a client on one of the many i2c adapters
of a system. So the best we could do was to issue a warning message in
the logs.

> I have also
> attached a regression test script (w83627ehf_regression.sh) which
> matches this driver. There is not a way to script a test for the
> changes made to correctly handle device_create_file() errors, so this
> regression test is the same as previous tests.

As discussed with Jim Cromie earlier, the only thing to check is that
the list of created files is unchanged before and after the patch.

You can also simulate an error at the last file creation, to make sure
the error path is tested at least once. I did that when updating
i2c-core, i2c-dev and i2c-isa, and found a bug thanks to this. Ideally
you should even test every possible error case, if you have more time.

To the code:

> diff -ur linux-2.6.18-rc4/drivers/hwmon/w83627ehf.c linux-2.6.18-rc4/drivers/hwmon/w83627ehf.c
> --- linux-2.6.18-rc4/drivers/hwmon/w83627ehf.c	2006-08-16 15:56:34.000000000 -0700
> +++ linux-2.6.18-rc4/drivers/hwmon/w83627ehf.c	2006-08-21 23:02:59.000000000 -0700
> @@ -621,14 +621,6 @@
>        SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
>  };
>  
> -static void device_create_file_in(struct device *dev, int i)
> -{
> -	device_create_file(dev, &sda_in_input[i].dev_attr);
> -	device_create_file(dev, &sda_in_alarm[i].dev_attr);
> -	device_create_file(dev, &sda_in_min[i].dev_attr);
> -	device_create_file(dev, &sda_in_max[i].dev_attr);
> -}

You don't actually need to get rid of these functions if you are happy
with them. You could do something like:

static int device_create_file_in(struct device *dev, int i)
{
	int err;

	if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
	 || (err = device_create_file(dev, &sda_in_alarm[i].dev_attr))
	 || (err = device_create_file(dev, &sda_in_min[i].dev_attr))
	 || (err = device_create_file(dev, &sda_in_max[i].dev_attr)))
		return err;

	return 0;
}

> @@ -1223,30 +1198,92 @@
>  		goto exit_detach;
>  	}
>  
> -  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
> -  		device_create_file(dev, &sda_sf3_arrays[i].dev_attr);
> +  	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) {
> +		err = device_create_file(dev, &sda_sf3_arrays[i].dev_attr);
> +		if (err) goto exit_remove;
> +	}

Coding style: "goto exit_remove" should be on its own line.

> -	for (i = 0; i < 10; i++)
> -		device_create_file_in(dev, i);
> +	for (i = 0; i < 10; i++) {
> +		err = device_create_file(dev, &sda_in_input[i].dev_attr);
> +		if (err) goto exit_remove;
> +		err = device_create_file(dev, &sda_in_alarm[i].dev_attr);
> +		if (err) goto exit_remove;
> +		err = device_create_file(dev, &sda_in_min[i].dev_attr);
> +		if (err) goto exit_remove;
> +		err = device_create_file(dev, &sda_in_max[i].dev_attr);
> +		if (err) goto exit_remove;
> +	}

You can group the tests with || so you have a single "goto exit_remove"
for the whole block (see my proposed device_create_file_in above.)

> +exit_remove:
> +	/* some entries in the following arrays may not have been used in
> +	 * device_create_file(), but device_remove_file() will ignore them */
> +	for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
> +		device_remove_file(dev, &sda_temp[i].dev_attr);
> +	for (i = 5; --i; ) {

Please, don't try to be smart. It doesn't even work (you exit at i == 0
before removing the [0] files.) Use a regular for loop, thanks.

> +		if (i < 4) { /* w83627ehf only has 4 pwm */
> +			device_remove_file(dev, &sda_tolerance[i].dev_attr);
> +			device_remove_file(dev, &sda_target_temp[i].dev_attr);
> +			device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
> +			device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
> +			device_remove_file(dev, &sda_pwm[i].dev_attr);
> +		}
> +		device_remove_file(dev, &sda_fan_min[i].dev_attr);
> +		device_remove_file(dev, &sda_fan_div[i].dev_attr);
> +		device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
> +		device_remove_file(dev, &sda_fan_input[i].dev_attr);
> +	}
> +	for (i = 10; --i; ) {
> +		device_remove_file(dev, &sda_in_max[i].dev_attr);
> +		device_remove_file(dev, &sda_in_min[i].dev_attr);
> +		device_remove_file(dev, &sda_in_alarm[i].dev_attr);
> +		device_remove_file(dev, &sda_in_input[i].dev_attr);
> +	}
> +	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
> +		device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
> +	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
> +		device_remove_file(dev, &sda_sf3_arrays[i].dev_attr);
> +	hwmon_device_unregister(data->class_dev);
>  exit_detach:
>  	i2c_detach_client(client);
>  exit_free:

Your patch does remove the files if creation failed, however it fails
to remove them if the device is removed later.

Please provide an updated patch.

Thanks,
-- 
Jean Delvare




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux