diff options
Diffstat (limited to 'drivers/base/devtmpfs.c')
| -rw-r--r-- | drivers/base/devtmpfs.c | 98 | 
1 files changed, 41 insertions, 57 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 765c3a28077..d91a3a0b232 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -227,33 +227,24 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)  static int dev_rmdir(const char *name)  { -	struct nameidata nd; +	struct path parent;  	struct dentry *dentry;  	int err; -	err = kern_path_parent(name, &nd); -	if (err) -		return err; - -	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); -	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); -	if (!IS_ERR(dentry)) { -		if (dentry->d_inode) { -			if (dentry->d_inode->i_private == &thread) -				err = vfs_rmdir(nd.path.dentry->d_inode, -						dentry); -			else -				err = -EPERM; -		} else { -			err = -ENOENT; -		} -		dput(dentry); +	dentry = kern_path_locked(name, &parent); +	if (IS_ERR(dentry)) +		return PTR_ERR(dentry); +	if (dentry->d_inode) { +		if (dentry->d_inode->i_private == &thread) +			err = vfs_rmdir(parent.dentry->d_inode, dentry); +		else +			err = -EPERM;  	} else { -		err = PTR_ERR(dentry); +		err = -ENOENT;  	} - -	mutex_unlock(&nd.path.dentry->d_inode->i_mutex); -	path_put(&nd.path); +	dput(dentry); +	mutex_unlock(&parent.dentry->d_inode->i_mutex); +	path_put(&parent);  	return err;  } @@ -305,50 +296,43 @@ static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *sta  static int handle_remove(const char *nodename, struct device *dev)  { -	struct nameidata nd; +	struct path parent;  	struct dentry *dentry; -	struct kstat stat;  	int deleted = 1;  	int err; -	err = kern_path_parent(nodename, &nd); -	if (err) -		return err; +	dentry = kern_path_locked(nodename, &parent); +	if (IS_ERR(dentry)) +		return PTR_ERR(dentry); -	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); -	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); -	if (!IS_ERR(dentry)) { -		if (dentry->d_inode) { -			err = vfs_getattr(nd.path.mnt, dentry, &stat); -			if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { -				struct iattr newattrs; -				/* -				 * before unlinking this node, reset permissions -				 * of possible references like hardlinks -				 */ -				newattrs.ia_uid = 0; -				newattrs.ia_gid = 0; -				newattrs.ia_mode = stat.mode & ~0777; -				newattrs.ia_valid = -					ATTR_UID|ATTR_GID|ATTR_MODE; -				mutex_lock(&dentry->d_inode->i_mutex); -				notify_change(dentry, &newattrs); -				mutex_unlock(&dentry->d_inode->i_mutex); -				err = vfs_unlink(nd.path.dentry->d_inode, -						 dentry); -				if (!err || err == -ENOENT) -					deleted = 1; -			} -		} else { -			err = -ENOENT; +	if (dentry->d_inode) { +		struct kstat stat; +		err = vfs_getattr(parent.mnt, dentry, &stat); +		if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { +			struct iattr newattrs; +			/* +			 * before unlinking this node, reset permissions +			 * of possible references like hardlinks +			 */ +			newattrs.ia_uid = 0; +			newattrs.ia_gid = 0; +			newattrs.ia_mode = stat.mode & ~0777; +			newattrs.ia_valid = +				ATTR_UID|ATTR_GID|ATTR_MODE; +			mutex_lock(&dentry->d_inode->i_mutex); +			notify_change(dentry, &newattrs); +			mutex_unlock(&dentry->d_inode->i_mutex); +			err = vfs_unlink(parent.dentry->d_inode, dentry); +			if (!err || err == -ENOENT) +				deleted = 1;  		} -		dput(dentry);  	} else { -		err = PTR_ERR(dentry); +		err = -ENOENT;  	} -	mutex_unlock(&nd.path.dentry->d_inode->i_mutex); +	dput(dentry); +	mutex_unlock(&parent.dentry->d_inode->i_mutex); -	path_put(&nd.path); +	path_put(&parent);  	if (deleted && strchr(nodename, '/'))  		delete_path(nodename);  	return err;  |