diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 5d21718afb05..4056d96cf627 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -49,6 +49,8 @@ static ssize_t field##_show(struct device *dev, \ usb_actconfig_attr(bNumInterfaces, "%2d\n"); usb_actconfig_attr(bmAttributes, "%2x\n"); +static DEFINE_MUTEX(sysfs_mutex); + static ssize_t bMaxPower_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1015,6 +1017,8 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) struct device *dev = &udev->dev; int retval; + /* Protect against simultaneous remove */ + mutex_lock(&sysfs_mutex); retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); if (retval) goto error; @@ -1032,9 +1036,11 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) if (retval) goto error; } + mutex_unlock(&sysfs_mutex); return retval; error: + mutex_unlock(&sysfs_mutex); usb_remove_sysfs_dev_files(udev); return retval; } @@ -1043,12 +1049,15 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) { struct device *dev = &udev->dev; + /* Protect against simultaneous create */ + mutex_lock(&sysfs_mutex); if (is_root_hub(udev)) remove_default_authorized_attributes(dev); remove_power_attributes(dev); remove_persist_attributes(dev); device_remove_bin_file(dev, &dev_bin_attr_descriptors); + mutex_unlock(&sysfs_mutex); } /* Interface Association Descriptor fields */