mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-06 05:13:18 +00:00
new helpers: kern_path_create/user_path_create
combination of kern_path_parent() and lookup_create(). Does *not* expose struct nameidata to caller. Syscalls converted to that... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
49084c3bb2
commit
dae6ad8f37
154
fs/namei.c
154
fs/namei.c
@ -2311,6 +2311,35 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(lookup_create);
|
EXPORT_SYMBOL_GPL(lookup_create);
|
||||||
|
|
||||||
|
struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir)
|
||||||
|
{
|
||||||
|
struct nameidata nd;
|
||||||
|
struct dentry *res;
|
||||||
|
int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
|
||||||
|
if (error)
|
||||||
|
return ERR_PTR(error);
|
||||||
|
res = lookup_create(&nd, is_dir);
|
||||||
|
if (IS_ERR(res)) {
|
||||||
|
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
||||||
|
path_put(&nd.path);
|
||||||
|
}
|
||||||
|
*path = nd.path;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(kern_path_create);
|
||||||
|
|
||||||
|
struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
|
||||||
|
{
|
||||||
|
char *tmp = getname(pathname);
|
||||||
|
struct dentry *res;
|
||||||
|
if (IS_ERR(tmp))
|
||||||
|
return ERR_CAST(tmp);
|
||||||
|
res = kern_path_create(dfd, tmp, path, is_dir);
|
||||||
|
putname(tmp);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(user_path_create);
|
||||||
|
|
||||||
int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
||||||
{
|
{
|
||||||
int error = may_create(dir, dentry);
|
int error = may_create(dir, dentry);
|
||||||
@ -2359,54 +2388,46 @@ static int may_mknod(mode_t mode)
|
|||||||
SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
|
SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
|
||||||
unsigned, dev)
|
unsigned, dev)
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
char *tmp;
|
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct nameidata nd;
|
struct path path;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR(mode))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
error = user_path_parent(dfd, filename, &nd, &tmp);
|
dentry = user_path_create(dfd, filename, &path, 0);
|
||||||
if (error)
|
if (IS_ERR(dentry))
|
||||||
return error;
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
dentry = lookup_create(&nd, 0);
|
if (!IS_POSIXACL(path.dentry->d_inode))
|
||||||
if (IS_ERR(dentry)) {
|
|
||||||
error = PTR_ERR(dentry);
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
if (!IS_POSIXACL(nd.path.dentry->d_inode))
|
|
||||||
mode &= ~current_umask();
|
mode &= ~current_umask();
|
||||||
error = may_mknod(mode);
|
error = may_mknod(mode);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
error = mnt_want_write(nd.path.mnt);
|
error = mnt_want_write(path.mnt);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
error = security_path_mknod(&nd.path, dentry, mode, dev);
|
error = security_path_mknod(&path, dentry, mode, dev);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_drop_write;
|
goto out_drop_write;
|
||||||
switch (mode & S_IFMT) {
|
switch (mode & S_IFMT) {
|
||||||
case 0: case S_IFREG:
|
case 0: case S_IFREG:
|
||||||
error = vfs_create(nd.path.dentry->d_inode,dentry,mode,NULL);
|
error = vfs_create(path.dentry->d_inode,dentry,mode,NULL);
|
||||||
break;
|
break;
|
||||||
case S_IFCHR: case S_IFBLK:
|
case S_IFCHR: case S_IFBLK:
|
||||||
error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
|
error = vfs_mknod(path.dentry->d_inode,dentry,mode,
|
||||||
new_decode_dev(dev));
|
new_decode_dev(dev));
|
||||||
break;
|
break;
|
||||||
case S_IFIFO: case S_IFSOCK:
|
case S_IFIFO: case S_IFSOCK:
|
||||||
error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
|
error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out_drop_write:
|
out_drop_write:
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(path.mnt);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_unlock:
|
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&path);
|
||||||
path_put(&nd.path);
|
|
||||||
putname(tmp);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -2439,38 +2460,29 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||||||
|
|
||||||
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
|
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
|
||||||
{
|
{
|
||||||
int error = 0;
|
|
||||||
char * tmp;
|
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct nameidata nd;
|
struct path path;
|
||||||
|
int error;
|
||||||
|
|
||||||
error = user_path_parent(dfd, pathname, &nd, &tmp);
|
dentry = user_path_create(dfd, pathname, &path, 1);
|
||||||
if (error)
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
dentry = lookup_create(&nd, 1);
|
|
||||||
error = PTR_ERR(dentry);
|
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
goto out_unlock;
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
if (!IS_POSIXACL(nd.path.dentry->d_inode))
|
if (!IS_POSIXACL(path.dentry->d_inode))
|
||||||
mode &= ~current_umask();
|
mode &= ~current_umask();
|
||||||
error = mnt_want_write(nd.path.mnt);
|
error = mnt_want_write(path.mnt);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
error = security_path_mkdir(&nd.path, dentry, mode);
|
error = security_path_mkdir(&path, dentry, mode);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_drop_write;
|
goto out_drop_write;
|
||||||
error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
|
error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
|
||||||
out_drop_write:
|
out_drop_write:
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(path.mnt);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_unlock:
|
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&path);
|
||||||
path_put(&nd.path);
|
|
||||||
putname(tmp);
|
|
||||||
out_err:
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2730,38 +2742,31 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
char *from;
|
char *from;
|
||||||
char *to;
|
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct nameidata nd;
|
struct path path;
|
||||||
|
|
||||||
from = getname(oldname);
|
from = getname(oldname);
|
||||||
if (IS_ERR(from))
|
if (IS_ERR(from))
|
||||||
return PTR_ERR(from);
|
return PTR_ERR(from);
|
||||||
|
|
||||||
error = user_path_parent(newdfd, newname, &nd, &to);
|
dentry = user_path_create(newdfd, newname, &path, 0);
|
||||||
if (error)
|
|
||||||
goto out_putname;
|
|
||||||
|
|
||||||
dentry = lookup_create(&nd, 0);
|
|
||||||
error = PTR_ERR(dentry);
|
error = PTR_ERR(dentry);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
goto out_unlock;
|
goto out_putname;
|
||||||
|
|
||||||
error = mnt_want_write(nd.path.mnt);
|
error = mnt_want_write(path.mnt);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
error = security_path_symlink(&nd.path, dentry, from);
|
error = security_path_symlink(&path, dentry, from);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_drop_write;
|
goto out_drop_write;
|
||||||
error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
|
error = vfs_symlink(path.dentry->d_inode, dentry, from);
|
||||||
out_drop_write:
|
out_drop_write:
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(path.mnt);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_unlock:
|
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&path);
|
||||||
path_put(&nd.path);
|
|
||||||
putname(to);
|
|
||||||
out_putname:
|
out_putname:
|
||||||
putname(from);
|
putname(from);
|
||||||
return error;
|
return error;
|
||||||
@ -2826,11 +2831,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
|
|||||||
int, newdfd, const char __user *, newname, int, flags)
|
int, newdfd, const char __user *, newname, int, flags)
|
||||||
{
|
{
|
||||||
struct dentry *new_dentry;
|
struct dentry *new_dentry;
|
||||||
struct nameidata nd;
|
struct path old_path, new_path;
|
||||||
struct path old_path;
|
|
||||||
int how = 0;
|
int how = 0;
|
||||||
int error;
|
int error;
|
||||||
char *to;
|
|
||||||
|
|
||||||
if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
|
if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -2852,32 +2855,27 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
|
|||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = user_path_parent(newdfd, newname, &nd, &to);
|
new_dentry = user_path_create(newdfd, newname, &new_path, 0);
|
||||||
if (error)
|
|
||||||
goto out;
|
|
||||||
error = -EXDEV;
|
|
||||||
if (old_path.mnt != nd.path.mnt)
|
|
||||||
goto out_release;
|
|
||||||
new_dentry = lookup_create(&nd, 0);
|
|
||||||
error = PTR_ERR(new_dentry);
|
error = PTR_ERR(new_dentry);
|
||||||
if (IS_ERR(new_dentry))
|
if (IS_ERR(new_dentry))
|
||||||
goto out_unlock;
|
goto out;
|
||||||
error = mnt_want_write(nd.path.mnt);
|
|
||||||
|
error = -EXDEV;
|
||||||
|
if (old_path.mnt != new_path.mnt)
|
||||||
|
goto out_dput;
|
||||||
|
error = mnt_want_write(new_path.mnt);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
error = security_path_link(old_path.dentry, &nd.path, new_dentry);
|
error = security_path_link(old_path.dentry, &new_path, new_dentry);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_drop_write;
|
goto out_drop_write;
|
||||||
error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
|
error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
|
||||||
out_drop_write:
|
out_drop_write:
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(new_path.mnt);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(new_dentry);
|
dput(new_dentry);
|
||||||
out_unlock:
|
mutex_unlock(&new_path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&new_path);
|
||||||
out_release:
|
|
||||||
path_put(&nd.path);
|
|
||||||
putname(to);
|
|
||||||
out:
|
out:
|
||||||
path_put(&old_path);
|
path_put(&old_path);
|
||||||
|
|
||||||
|
@ -4368,25 +4368,6 @@ static inline int ocfs2_may_create(struct inode *dir, struct dentry *child)
|
|||||||
return inode_permission(dir, MAY_WRITE | MAY_EXEC);
|
return inode_permission(dir, MAY_WRITE | MAY_EXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copied from user_path_parent. */
|
|
||||||
static int ocfs2_user_path_parent(const char __user *path,
|
|
||||||
struct nameidata *nd, char **name)
|
|
||||||
{
|
|
||||||
char *s = getname(path);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if (IS_ERR(s))
|
|
||||||
return PTR_ERR(s);
|
|
||||||
|
|
||||||
error = kern_path_parent(s, nd);
|
|
||||||
if (error)
|
|
||||||
putname(s);
|
|
||||||
else
|
|
||||||
*name = s;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ocfs2_vfs_reflink - Create a reference-counted link
|
* ocfs2_vfs_reflink - Create a reference-counted link
|
||||||
*
|
*
|
||||||
@ -4460,10 +4441,8 @@ int ocfs2_reflink_ioctl(struct inode *inode,
|
|||||||
bool preserve)
|
bool preserve)
|
||||||
{
|
{
|
||||||
struct dentry *new_dentry;
|
struct dentry *new_dentry;
|
||||||
struct nameidata nd;
|
struct path old_path, new_path;
|
||||||
struct path old_path;
|
|
||||||
int error;
|
int error;
|
||||||
char *to = NULL;
|
|
||||||
|
|
||||||
if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
|
if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@ -4474,39 +4453,33 @@ int ocfs2_reflink_ioctl(struct inode *inode,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ocfs2_user_path_parent(newname, &nd, &to);
|
new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
|
||||||
if (error) {
|
error = PTR_ERR(new_dentry);
|
||||||
|
if (IS_ERR(new_dentry)) {
|
||||||
mlog_errno(error);
|
mlog_errno(error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = -EXDEV;
|
error = -EXDEV;
|
||||||
if (old_path.mnt != nd.path.mnt)
|
if (old_path.mnt != new_path.mnt) {
|
||||||
goto out_release;
|
|
||||||
new_dentry = lookup_create(&nd, 0);
|
|
||||||
error = PTR_ERR(new_dentry);
|
|
||||||
if (IS_ERR(new_dentry)) {
|
|
||||||
mlog_errno(error);
|
mlog_errno(error);
|
||||||
goto out_unlock;
|
goto out_dput;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = mnt_want_write(nd.path.mnt);
|
error = mnt_want_write(new_path.mnt);
|
||||||
if (error) {
|
if (error) {
|
||||||
mlog_errno(error);
|
mlog_errno(error);
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ocfs2_vfs_reflink(old_path.dentry,
|
error = ocfs2_vfs_reflink(old_path.dentry,
|
||||||
nd.path.dentry->d_inode,
|
new_path.dentry->d_inode,
|
||||||
new_dentry, preserve);
|
new_dentry, preserve);
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(new_path.mnt);
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(new_dentry);
|
dput(new_dentry);
|
||||||
out_unlock:
|
mutex_unlock(&new_path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&new_path);
|
||||||
out_release:
|
|
||||||
path_put(&nd.path);
|
|
||||||
putname(to);
|
|
||||||
out:
|
out:
|
||||||
path_put(&old_path);
|
path_put(&old_path);
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ extern int user_path_at(int, const char __user *, unsigned, struct path *);
|
|||||||
|
|
||||||
extern int kern_path(const char *, unsigned, struct path *);
|
extern int kern_path(const char *, unsigned, struct path *);
|
||||||
|
|
||||||
|
extern struct dentry *kern_path_create(int, const char *, struct path *, int);
|
||||||
|
extern struct dentry *user_path_create(int, const char __user *, struct path *, int);
|
||||||
extern int kern_path_parent(const char *, struct nameidata *);
|
extern int kern_path_parent(const char *, struct nameidata *);
|
||||||
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
|
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
|
||||||
const char *, unsigned int, struct nameidata *);
|
const char *, unsigned int, struct nameidata *);
|
||||||
|
@ -808,8 +808,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
struct net *net = sock_net(sk);
|
struct net *net = sock_net(sk);
|
||||||
struct unix_sock *u = unix_sk(sk);
|
struct unix_sock *u = unix_sk(sk);
|
||||||
struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
|
struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
|
||||||
|
char *sun_path = sunaddr->sun_path;
|
||||||
struct dentry *dentry = NULL;
|
struct dentry *dentry = NULL;
|
||||||
struct nameidata nd;
|
struct path path;
|
||||||
int err;
|
int err;
|
||||||
unsigned hash;
|
unsigned hash;
|
||||||
struct unix_address *addr;
|
struct unix_address *addr;
|
||||||
@ -845,48 +846,44 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
addr->hash = hash ^ sk->sk_type;
|
addr->hash = hash ^ sk->sk_type;
|
||||||
atomic_set(&addr->refcnt, 1);
|
atomic_set(&addr->refcnt, 1);
|
||||||
|
|
||||||
if (sunaddr->sun_path[0]) {
|
if (sun_path[0]) {
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
err = 0;
|
err = 0;
|
||||||
/*
|
/*
|
||||||
* Get the parent directory, calculate the hash for last
|
* Get the parent directory, calculate the hash for last
|
||||||
* component.
|
* component.
|
||||||
*/
|
*/
|
||||||
err = kern_path_parent(sunaddr->sun_path, &nd);
|
dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
|
||||||
if (err)
|
|
||||||
goto out_mknod_parent;
|
|
||||||
|
|
||||||
dentry = lookup_create(&nd, 0);
|
|
||||||
err = PTR_ERR(dentry);
|
err = PTR_ERR(dentry);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
goto out_mknod_unlock;
|
goto out_mknod_parent;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All right, let's create it.
|
* All right, let's create it.
|
||||||
*/
|
*/
|
||||||
mode = S_IFSOCK |
|
mode = S_IFSOCK |
|
||||||
(SOCK_INODE(sock)->i_mode & ~current_umask());
|
(SOCK_INODE(sock)->i_mode & ~current_umask());
|
||||||
err = mnt_want_write(nd.path.mnt);
|
err = mnt_want_write(path.mnt);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_mknod_dput;
|
goto out_mknod_dput;
|
||||||
err = security_path_mknod(&nd.path, dentry, mode, 0);
|
err = security_path_mknod(&path, dentry, mode, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_mknod_drop_write;
|
goto out_mknod_drop_write;
|
||||||
err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
|
err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
|
||||||
out_mknod_drop_write:
|
out_mknod_drop_write:
|
||||||
mnt_drop_write(nd.path.mnt);
|
mnt_drop_write(path.mnt);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_mknod_dput;
|
goto out_mknod_dput;
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||||
dput(nd.path.dentry);
|
dput(path.dentry);
|
||||||
nd.path.dentry = dentry;
|
path.dentry = dentry;
|
||||||
|
|
||||||
addr->hash = UNIX_HASH_SIZE;
|
addr->hash = UNIX_HASH_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&unix_table_lock);
|
spin_lock(&unix_table_lock);
|
||||||
|
|
||||||
if (!sunaddr->sun_path[0]) {
|
if (!sun_path[0]) {
|
||||||
err = -EADDRINUSE;
|
err = -EADDRINUSE;
|
||||||
if (__unix_find_socket_byname(net, sunaddr, addr_len,
|
if (__unix_find_socket_byname(net, sunaddr, addr_len,
|
||||||
sk->sk_type, hash)) {
|
sk->sk_type, hash)) {
|
||||||
@ -897,8 +894,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
list = &unix_socket_table[addr->hash];
|
list = &unix_socket_table[addr->hash];
|
||||||
} else {
|
} else {
|
||||||
list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
|
list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
|
||||||
u->dentry = nd.path.dentry;
|
u->dentry = path.dentry;
|
||||||
u->mnt = nd.path.mnt;
|
u->mnt = path.mnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
@ -915,9 +912,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
|
|
||||||
out_mknod_dput:
|
out_mknod_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_mknod_unlock:
|
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
path_put(&path);
|
||||||
path_put(&nd.path);
|
|
||||||
out_mknod_parent:
|
out_mknod_parent:
|
||||||
if (err == -EEXIST)
|
if (err == -EEXIST)
|
||||||
err = -EADDRINUSE;
|
err = -EADDRINUSE;
|
||||||
|
Loading…
Reference in New Issue
Block a user