#include <linux/pagemap.h>
#include <linux/namei.h>
#include <linux/backing-dev.h>
+#include <linux/capability.h>
#include "sysfs.h"
extern struct super_block * sysfs_sb;
if (!sd_iattr) {
/* setting attributes for the first time, allocate now */
- sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+ sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
if (!sd_iattr)
return -ENOMEM;
/* assign default attributes */
- memset(sd_iattr, 0, sizeof(struct iattr));
sd_iattr->ia_mode = sd->s_mode;
sd_iattr->ia_uid = 0;
sd_iattr->ia_gid = 0;
/*
* Unhashes the dentry corresponding to given sysfs_dirent
- * Called with parent inode's i_sem held.
+ * Called with parent inode's i_mutex held.
*/
void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
{
void sysfs_hash_and_remove(struct dentry * dir, const char * name)
{
struct sysfs_dirent * sd;
- struct sysfs_dirent * parent_sd = dir->d_fsdata;
+ struct sysfs_dirent * parent_sd;
- down(&dir->d_inode->i_sem);
+ if (!dir)
+ return;
+
+ if (dir->d_inode == NULL)
+ /* no inode means this hasn't been made visible yet */
+ return;
+
+ parent_sd = dir->d_fsdata;
+ mutex_lock(&dir->d_inode->i_mutex);
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (!sd->s_element)
continue;
break;
}
}
- up(&dir->d_inode->i_sem);
+ mutex_unlock(&dir->d_inode->i_mutex);
}
-
-