tunnels: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / fs / sysfs / file.c
index b1606e0..dc30d9e 100644 (file)
@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
        struct sysfs_open_dirent *od, *new_od = NULL;
 
  retry:
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irq(&sysfs_open_dirent_lock);
 
        if (!sd->s_attr.open && new_od) {
                sd->s_attr.open = new_od;
@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
                list_add_tail(&buffer->list, &od->buffers);
        }
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irq(&sysfs_open_dirent_lock);
 
        if (od) {
                kfree(new_od);
@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
                                  struct sysfs_buffer *buffer)
 {
        struct sysfs_open_dirent *od = sd->s_attr.open;
+       unsigned long flags;
 
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
 
        list_del(&buffer->list);
        if (atomic_dec_and_test(&od->refcnt))
@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
        else
                od = NULL;
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
 
        kfree(od);
 }
@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 void sysfs_notify_dirent(struct sysfs_dirent *sd)
 {
        struct sysfs_open_dirent *od;
+       unsigned long flags;
 
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
 
        od = sd->s_attr.open;
        if (od) {
@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
                wake_up_interruptible(&od->poll);
        }
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
 }
 EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
 
@@ -577,46 +579,23 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
  */
 int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 {
-       struct sysfs_dirent *victim_sd = NULL;
-       struct dentry *victim = NULL;
-       struct inode * inode;
+       struct sysfs_dirent *sd;
        struct iattr newattrs;
        int rc;
 
-       rc = -ENOENT;
-       victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
-       if (!victim_sd)
-               goto out;
+       mutex_lock(&sysfs_mutex);
 
-       mutex_lock(&sysfs_rename_mutex);
-       victim = sysfs_get_dentry(victim_sd);
-       mutex_unlock(&sysfs_rename_mutex);
-       if (IS_ERR(victim)) {
-               rc = PTR_ERR(victim);
-               victim = NULL;
+       rc = -ENOENT;
+       sd = sysfs_find_dirent(kobj->sd, attr->name);
+       if (!sd)
                goto out;
-       }
-
-       inode = victim->d_inode;
-
-       mutex_lock(&inode->i_mutex);
 
-       newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
-       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-       newattrs.ia_ctime = current_fs_time(inode->i_sb);
-       rc = sysfs_setattr(victim, &newattrs);
+       newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
+       newattrs.ia_valid = ATTR_MODE;
+       rc = sysfs_sd_setattr(sd, &newattrs);
 
-       if (rc == 0) {
-               fsnotify_change(victim, newattrs.ia_valid);
-               mutex_lock(&sysfs_mutex);
-               victim_sd->s_mode = newattrs.ia_mode;
-               mutex_unlock(&sysfs_mutex);
-       }
-
-       mutex_unlock(&inode->i_mutex);
  out:
-       dput(victim);
-       sysfs_put(victim_sd);
+       mutex_unlock(&sysfs_mutex);
        return rc;
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
@@ -723,7 +702,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
        mutex_unlock(&sysfs_workq_mutex);
 
        if (sysfs_workqueue == NULL) {
-               sysfs_workqueue = create_workqueue("sysfsd");
+               sysfs_workqueue = create_singlethread_workqueue("sysfsd");
                if (sysfs_workqueue == NULL) {
                        module_put(owner);
                        return -ENOMEM;