Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit faf02010 authored by Al Viro's avatar Al Viro
Browse files

clean unix_bind() up a bit



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a8104a9f
Loading
Loading
Loading
Loading
+43 −45
Original line number Original line Diff line number Diff line
@@ -814,6 +814,34 @@ static struct sock *unix_find_other(struct net *net,
	return NULL;
	return NULL;
}
}


static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
{
	struct dentry *dentry;
	struct path path;
	int err = 0;
	/*
	 * Get the parent directory, calculate the hash for last
	 * component.
	 */
	dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
	err = PTR_ERR(dentry);
	if (IS_ERR(dentry))
		return err;

	/*
	 * All right, let's create it.
	 */
	err = security_path_mknod(&path, dentry, mode, 0);
	if (!err) {
		err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
		if (!err) {
			res->mnt = mntget(path.mnt);
			res->dentry = dget(dentry);
		}
	}
	done_path_create(&path, dentry);
	return err;
}


static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
{
@@ -822,8 +850,6 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
	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;
	char *sun_path = sunaddr->sun_path;
	struct dentry *dentry = NULL;
	struct path path;
	int err;
	int err;
	unsigned int hash;
	unsigned int hash;
	struct unix_address *addr;
	struct unix_address *addr;
@@ -860,40 +886,23 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
	atomic_set(&addr->refcnt, 1);
	atomic_set(&addr->refcnt, 1);


	if (sun_path[0]) {
	if (sun_path[0]) {
		umode_t mode;
		struct path path;
		err = 0;
		umode_t mode = S_IFSOCK |
		/*
		 * Get the parent directory, calculate the hash for last
		 * component.
		 */
		dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
		err = PTR_ERR(dentry);
		if (IS_ERR(dentry))
			goto out_mknod_parent;

		/*
		 * All right, let's create it.
		 */
		mode = S_IFSOCK |
		       (SOCK_INODE(sock)->i_mode & ~current_umask());
		       (SOCK_INODE(sock)->i_mode & ~current_umask());
		err = security_path_mknod(&path, dentry, mode, 0);
		err = unix_mknod(sun_path, mode, &path);
		if (err)
		if (err) {
			goto out_mknod_drop_write;
			if (err == -EEXIST)
		err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
				err = -EADDRINUSE;
out_mknod_drop_write:
			unix_release_addr(addr);
		if (err)
			goto out_up;
			goto out_mknod_dput;
		mntget(path.mnt);
		dget(dentry);
		done_path_create(&path, dentry);
		path.dentry = dentry;

		addr->hash = UNIX_HASH_SIZE;
		}
		}

		addr->hash = UNIX_HASH_SIZE;
		hash = path.dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1);
		spin_lock(&unix_table_lock);
		u->path = path;
		list = &unix_socket_table[hash];
	} else {
		spin_lock(&unix_table_lock);
		spin_lock(&unix_table_lock);

	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)) {
@@ -902,9 +911,6 @@ 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 {
		list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
		u->path = path;
	}
	}


	err = 0;
	err = 0;
@@ -918,14 +924,6 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
	mutex_unlock(&u->readlock);
	mutex_unlock(&u->readlock);
out:
out:
	return err;
	return err;

out_mknod_dput:
	done_path_create(&path, dentry);
out_mknod_parent:
	if (err == -EEXIST)
		err = -EADDRINUSE;
	unix_release_addr(addr);
	goto out_up;
}
}


static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)