param: simple locking for sysfs-writable charp parameters
authorRusty Russell <rusty@rustcorp.com.au>
Thu, 12 Aug 2010 05:04:27 +0000 (23:04 -0600)
committerRusty Russell <rusty@rustcorp.com.au>
Wed, 11 Aug 2010 13:34:31 +0000 (23:04 +0930)
Since the writing to sysfs can free the old one, we need to block that
when we access the charp variables.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Phil Carmody <ext-phil.2.carmody@nokia.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Dan Williams <dcbw@redhat.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Jing Huang <huangj@brocade.com>
Cc: James E.J. Bottomley <James.Bottomley@suse.de>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: libertas-dev@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-scsi@vger.kernel.org
Cc: linux-usb@vger.kernel.org
arch/um/drivers/hostaudio_kern.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas_tf/if_usb.c
drivers/scsi/bfa/bfad.c
drivers/usb/atm/ueagle-atm.c
drivers/video/vt8623fb.c
net/mac80211/rate.c

index 68142df76608319a666bf455713e54c9c683bb88..0c46e398cd8f313d89a3ff07187916aa6021b93f 100644 (file)
@@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
        int ret;
 
 #ifdef DEBUG
+       kparam_block_sysfs_write(dsp);
        printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
+       kparam_unblock_sysfs_write(dsp);
 #endif
 
        state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
@@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file)
        if (file->f_mode & FMODE_WRITE)
                w = 1;
 
+       kparam_block_sysfs_write(dsp);
        lock_kernel();
        ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
        unlock_kernel();
+       kparam_unblock_sysfs_write(dsp);
 
        if (ret < 0) {
                kfree(state);
@@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
        if (file->f_mode & FMODE_WRITE)
                w = 1;
 
+       kparam_block_sysfs_write(mixer);
        lock_kernel();
        ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
        unlock_kernel();
+       kparam_unblock_sysfs_write(mixer);
 
        if (ret < 0) {
+               kparam_block_sysfs_write(dsp);
                printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
                       "err = %d\n", dsp, -ret);
+               kparam_unblock_sysfs_write(dsp);
                kfree(state);
                return ret;
        }
@@ -320,8 +328,10 @@ MODULE_LICENSE("GPL");
 
 static int __init hostaudio_init_module(void)
 {
+       __kernel_param_lock();
        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
               dsp, mixer);
+       __kernel_param_unlock();
 
        module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
        if (module_data.dev_audio < 0) {
index 07ece9d26c63c373eb26e71ddb7ac7b832c17c1b..3ff61063671a099a944fd4fd840e62c582d9a7c6 100644 (file)
@@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf,
        }
 
        /* Upload firmware */
+       kparam_block_sysfs_write(fw_name);
        if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
+               kparam_unblock_sysfs_write(fw_name);
                lbs_deb_usbd(&udev->dev, "FW upload failed\n");
                goto err_prog_firmware;
        }
+       kparam_unblock_sysfs_write(fw_name);
 
        if (!(priv = lbs_add_card(cardp, &udev->dev)))
                goto err_prog_firmware;
index b172f5d87a3b4e279bced500cc9c81942e8aaaf5..41a4f214ade1271e66b526cc4c936daf2059736a 100644 (file)
@@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
 
        lbtf_deb_enter(LBTF_DEB_USB);
 
+       kparam_block_sysfs_write(fw_name);
        ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
        if (ret < 0) {
                pr_err("request_firmware() failed with %#x\n", ret);
                pr_err("firmware %s not found\n", lbtf_fw_name);
+               kparam_unblock_sysfs_write(fw_name);
                goto done;
        }
+       kparam_unblock_sysfs_write(fw_name);
 
        if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
                goto release_fw;
index 915a29d6c7ad586c9f36e0399354498d51fa240d..ca04cc9d332f07e4a8e41244d1af26cfa8f2263e 100644 (file)
@@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad)
        memset(&driver_info, 0, sizeof(driver_info));
        strncpy(driver_info.version, BFAD_DRIVER_VERSION,
                sizeof(driver_info.version) - 1);
+       __kernel_param_lock();
        if (host_name)
                strncpy(driver_info.host_machine_name, host_name,
                        sizeof(driver_info.host_machine_name) - 1);
@@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad)
        if (os_patch)
                strncpy(driver_info.host_os_patch, os_patch,
                        sizeof(driver_info.host_os_patch) - 1);
+       __kernel_param_unlock();
 
        strncpy(driver_info.os_device_name, bfad->pci_name,
                sizeof(driver_info.os_device_name - 1));
index 5b3f555e01c9ace8474fda0f3a5137b99002b185..ea071a5b6eee6aa929827851966dec80dfe070a0 100644 (file)
@@ -1577,6 +1577,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
        char file_arr[] = "CMVxy.bin";
        char *file;
 
+       kparam_block_sysfs_write(cmv_file);
        /* set proper name corresponding modem version and line type */
        if (cmv_file[sc->modem_index] == NULL) {
                if (UEA_CHIP_VERSION(sc) == ADI930)
@@ -1595,6 +1596,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
        strlcat(cmv_name, file, UEA_FW_NAME_MAX);
        if (ver == 2)
                strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
+       kparam_unblock_sysfs_write(cmv_file);
 }
 
 static int request_cmvs_old(struct uea_softc *sc,
index d31dc96f838a29576d1c11a0cbd6857d266475ac..85d76ec4c63e0c7ea2f65f10d072749256f9aeee 100644 (file)
@@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
 
        /* Prepare startup mode */
 
+       kparam_block_sysfs_write(mode_option);
        rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
+       kparam_unblock_sysfs_write(mode_option);
        if (! ((rc == 1) || (rc == 2))) {
                rc = -EINVAL;
                dev_err(info->device, "mode %s not found\n", mode_option);
index 6d0bd198af19d949841eaa94489c301e75f4cfa8..be04d46110fe8cdccc5e07eb810b67ee39c5c20f 100644 (file)
@@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name)
        struct rate_control_ops *ops;
        const char *alg_name;
 
+       kparam_block_sysfs_write(ieee80211_default_rc_algo);
        if (!name)
                alg_name = ieee80211_default_rc_algo;
        else
@@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name)
        /* try built-in one if specific alg requested but not found */
        if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
                ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
+       kparam_unblock_sysfs_write(ieee80211_default_rc_algo);
 
        return ops;
 }