aboutsummaryrefslogtreecommitdiff
path: root/drivers/base/devtmpfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/devtmpfs.c')
-rw-r--r--drivers/base/devtmpfs.c107
1 files changed, 43 insertions, 64 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 765c3a28077..deb4a456cf8 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -156,9 +156,7 @@ static int dev_mkdir(const char *name, umode_t mode)
if (!err)
/* mark as kernel-created inode */
dentry->d_inode->i_private = &thread;
- dput(dentry);
- mutex_unlock(&path.dentry->d_inode->i_mutex);
- path_put(&path);
+ done_path_create(&path, dentry);
return err;
}
@@ -218,42 +216,30 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
/* mark as kernel-created inode */
dentry->d_inode->i_private = &thread;
}
- dput(dentry);
-
- mutex_unlock(&path.dentry->d_inode->i_mutex);
- path_put(&path);
+ done_path_create(&path, dentry);
return err;
}
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 +291,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;