diff options
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/dir.c | 37 | ||||
| -rw-r--r-- | fs/sysfs/inode.c | 4 | 
2 files changed, 30 insertions, 11 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 35a36d39fa2..e6bb9b2a4cb 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -132,6 +132,24 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)  	rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);  } +#ifdef CONFIG_DEBUG_LOCK_ALLOC + +/* Test for attributes that want to ignore lockdep for read-locking */ +static bool ignore_lockdep(struct sysfs_dirent *sd) +{ +	return sysfs_type(sd) == SYSFS_KOBJ_ATTR && +			sd->s_attr.attr->ignore_lockdep; +} + +#else + +static inline bool ignore_lockdep(struct sysfs_dirent *sd) +{ +	return true; +} + +#endif +  /**   *	sysfs_get_active - get an active reference to sysfs_dirent   *	@sd: sysfs_dirent to get an active reference to @@ -155,15 +173,17 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)  			return NULL;  		t = atomic_cmpxchg(&sd->s_active, v, v + 1); -		if (likely(t == v)) { -			rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); -			return sd; -		} +		if (likely(t == v)) +			break;  		if (t < 0)  			return NULL;  		cpu_relax();  	} + +	if (likely(!ignore_lockdep(sd))) +		rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); +	return sd;  }  /** @@ -180,7 +200,8 @@ void sysfs_put_active(struct sysfs_dirent *sd)  	if (unlikely(!sd))  		return; -	rwsem_release(&sd->dep_map, 1, _RET_IP_); +	if (likely(!ignore_lockdep(sd))) +		rwsem_release(&sd->dep_map, 1, _RET_IP_);  	v = atomic_dec_return(&sd->s_active);  	if (likely(v != SD_DEACTIVATED_BIAS))  		return; @@ -858,7 +879,6 @@ int sysfs_rename(struct sysfs_dirent *sd,  	struct sysfs_dirent *new_parent_sd, const void *new_ns,  	const char *new_name)  { -	const char *dup_name = NULL;  	int error;  	mutex_lock(&sysfs_mutex); @@ -875,11 +895,11 @@ int sysfs_rename(struct sysfs_dirent *sd,  	/* rename sysfs_dirent */  	if (strcmp(sd->s_name, new_name) != 0) {  		error = -ENOMEM; -		new_name = dup_name = kstrdup(new_name, GFP_KERNEL); +		new_name = kstrdup(new_name, GFP_KERNEL);  		if (!new_name)  			goto out; -		dup_name = sd->s_name; +		kfree(sd->s_name);  		sd->s_name = new_name;  	} @@ -895,7 +915,6 @@ int sysfs_rename(struct sysfs_dirent *sd,  	error = 0;   out:  	mutex_unlock(&sysfs_mutex); -	kfree(dup_name);  	return error;  } diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index feb2d69396c..907c2b3af75 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -62,8 +62,8 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)  	/* assign default attributes */  	iattrs->ia_mode = sd->s_mode; -	iattrs->ia_uid = 0; -	iattrs->ia_gid = 0; +	iattrs->ia_uid = GLOBAL_ROOT_UID; +	iattrs->ia_gid = GLOBAL_ROOT_GID;  	iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;  	return attrs;  |