]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/sysfs/dir.c
[PATCH] splice: page stealing needs to wait_on_page_writeback()
[linux-2.6-omap-h63xx.git] / fs / sysfs / dir.c
index 49bd219275db30d6616a05ff8509045f88a39ec5..f26880a4785eec127e80ce736144624c3016098c 100644 (file)
@@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
        return sd;
 }
 
+/**
+ *
+ * Return -EEXIST if there is already a sysfs element with the same name for
+ * the same parent.
+ *
+ * called with parent inode's i_mutex held
+ */
+int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
+                         const unsigned char *new)
+{
+       struct sysfs_dirent * sd;
+
+       list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+               if (sd->s_element) {
+                       const unsigned char *existing = sysfs_get_name(sd);
+                       if (strcmp(existing, new))
+                               continue;
+                       else
+                               return -EEXIST;
+               }
+       }
+
+       return 0;
+}
+
+
 int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
                        void * element, umode_t mode, int type)
 {
@@ -102,7 +128,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
        mutex_lock(&p->d_inode->i_mutex);
        *d = lookup_one_len(n, p, strlen(n));
        if (!IS_ERR(*d)) {
-               error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
+               if (sysfs_dirent_exist(p->d_fsdata, n))
+                       error = -EEXIST;
+               else
+                       error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
+                                                               SYSFS_DIR);
                if (!error) {
                        error = sysfs_create(*d, mode, init_dir);
                        if (!error) {
@@ -302,6 +332,7 @@ void sysfs_remove_dir(struct kobject * kobj)
         * Drop reference from dget() on entrance.
         */
        dput(dentry);
+       kobj->dentry = NULL;
 }
 
 int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
@@ -472,14 +503,10 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
        return offset;
 }
 
-struct file_operations sysfs_dir_operations = {
+const struct file_operations sysfs_dir_operations = {
        .open           = sysfs_dir_open,
        .release        = sysfs_dir_close,
        .llseek         = sysfs_dir_lseek,
        .read           = generic_read_dir,
        .readdir        = sysfs_readdir,
 };
-
-EXPORT_SYMBOL_GPL(sysfs_create_dir);
-EXPORT_SYMBOL_GPL(sysfs_remove_dir);
-EXPORT_SYMBOL_GPL(sysfs_rename_dir);