]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/sysfs/dir.c
Merge branch 'sh/stable-updates' into sh/for-2.6.30
[karo-tx-linux.git] / fs / sysfs / dir.c
index 3a05a596e3b4de91dcb522401441b8dc8d959aa9..d88d0fac9fa5f185afd13b1f36b11f58baec672d 100644 (file)
@@ -302,7 +302,7 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
        iput(inode);
 }
 
-static struct dentry_operations sysfs_dentry_ops = {
+static const struct dentry_operations sysfs_dentry_ops = {
        .d_iput         = sysfs_d_iput,
 };
 
@@ -433,6 +433,26 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        return 0;
 }
 
+/**
+ *     sysfs_pathname - return full path to sysfs dirent
+ *     @sd: sysfs_dirent whose path we want
+ *     @path: caller allocated buffer
+ *
+ *     Gives the name "/" to the sysfs_root entry; any path returned
+ *     is relative to wherever sysfs is mounted.
+ *
+ *     XXX: does no error checking on @path size
+ */
+static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
+{
+       if (sd->s_parent) {
+               sysfs_pathname(sd->s_parent, path);
+               strcat(path, "/");
+       }
+       strcat(path, sd->s_name);
+       return path;
+}
+
 /**
  *     sysfs_add_one - add sysfs_dirent to parent
  *     @acxt: addrm context to use
@@ -458,8 +478,16 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        int ret;
 
        ret = __sysfs_add_one(acxt, sd);
-       WARN(ret == -EEXIST, KERN_WARNING "sysfs: duplicate filename '%s' "
-                      "can not be created\n", sd->s_name);
+       if (ret == -EEXIST) {
+               char *path = kzalloc(PATH_MAX, GFP_KERNEL);
+               WARN(1, KERN_WARNING
+                    "sysfs: cannot create duplicate filename '%s'\n",
+                    (path == NULL) ? sd->s_name :
+                    strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"),
+                           sd->s_name));
+               kfree(path);
+       }
+
        return ret;
 }
 
@@ -581,6 +609,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
 
                sysfs_drop_dentry(sd);
                sysfs_deactivate(sd);
+               unmap_bin_file(sd);
                sysfs_put(sd);
        }
 }
@@ -983,4 +1012,5 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 const struct file_operations sysfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = sysfs_readdir,
+       .llseek         = generic_file_llseek,
 };