diff options
author | Steve French <sfrench@us.ibm.com> | 2006-03-31 03:35:56 +0000 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-03-31 03:35:56 +0000 |
commit | d62e54abca1146981fc9f98f85ff398a113a22c2 (patch) | |
tree | 870420dbc4c65e716dcef8a802aafdc0ef97a8b4 /fs/sysfs/dir.c | |
parent | fd4a0b92db6a57cba8d03efbe1cebf91f9124ce0 (diff) | |
parent | ce362c009250340358a7221f3cdb7954cbf19c01 (diff) | |
download | linux-next-d62e54abca1146981fc9f98f85ff398a113a22c2.tar.gz |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 49bd219275db..f26880a4785e 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -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); |