fix setattr error handling in sysfs, configfs
[safe/jmp/linux-2.6] / fs / sysfs / inode.c
index 0d09f6c..0835a3b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include "sysfs.h"
@@ -116,13 +117,13 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
        if (error)
                goto out;
 
-       iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
-
-       error = inode_setattr(inode, iattr);
+       error = sysfs_sd_setattr(sd, iattr);
        if (error)
                goto out;
 
-       error = sysfs_sd_setattr(sd, iattr);
+       /* this ignores size changes */
+       generic_setattr(inode, iattr);
+
 out:
        mutex_unlock(&sysfs_mutex);
        return error;
@@ -283,6 +284,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 
 /**
  *     sysfs_get_inode - get inode for sysfs_dirent
+ *     @sb: super block
  *     @sd: sysfs_dirent to allocate inode for
  *
  *     Get inode for @sd.  If such inode doesn't exist, a new inode
@@ -295,11 +297,11 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
  *     RETURNS:
  *     Pointer to allocated inode on success, NULL on failure.
  */
-struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
+struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
 {
        struct inode *inode;
 
-       inode = iget_locked(sysfs_sb, sd->s_ino);
+       inode = iget_locked(sb, sd->s_ino);
        if (inode && (inode->i_state & I_NEW))
                sysfs_init_inode(sd, inode);
 
@@ -322,7 +324,7 @@ void sysfs_delete_inode(struct inode *inode)
        sysfs_put(sd);
 }
 
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name)
 {
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
@@ -332,7 +334,9 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
 
        sysfs_addrm_start(&acxt, dir_sd);
 
-       sd = sysfs_find_dirent(dir_sd, name);
+       sd = sysfs_find_dirent(dir_sd, ns, name);
+       if (sd && (sd->s_ns != ns))
+               sd = NULL;
        if (sd)
                sysfs_remove_one(&acxt, sd);