sunrpc: translate -EAGAIN to -ENOBUFS when socket is writable.
[firefly-linux-kernel-4.4.55.git] / net / unix / af_unix.c
index 433f287ee548391183c63d80b4db3736454a7f28..06430598cf512fdaff480671620e8fa69c259bb5 100644 (file)
@@ -305,7 +305,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
                    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
                struct dentry *dentry = unix_sk(s)->path.dentry;
 
-               if (dentry && dentry->d_inode == i) {
+               if (dentry && d_backing_inode(dentry) == i) {
                        sock_hold(s);
                        goto found;
                }
@@ -778,7 +778,7 @@ static struct sock *unix_find_other(struct net *net,
                err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
                if (err)
                        goto fail;
-               inode = path.dentry->d_inode;
+               inode = d_backing_inode(path.dentry);
                err = inode_permission(inode, MAY_WRITE);
                if (err)
                        goto put_fail;
@@ -839,7 +839,7 @@ static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
         */
        err = security_path_mknod(&path, dentry, mode, 0);
        if (!err) {
-               err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
+               err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
                if (!err) {
                        res->mnt = mntget(path.mnt);
                        res->dentry = dget(dentry);
@@ -905,7 +905,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                        goto out_up;
                }
                addr->hash = UNIX_HASH_SIZE;
-               hash = path.dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1);
+               hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE-1);
                spin_lock(&unix_table_lock);
                u->path = path;
                list = &unix_socket_table[hash];
@@ -1880,6 +1880,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
                unix_state_unlock(sk);
                timeo = freezable_schedule_timeout(timeo);
                unix_state_lock(sk);
+
+               if (sock_flag(sk, SOCK_DEAD))
+                       break;
+
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
        }
 
@@ -1939,6 +1943,10 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
                struct sk_buff *skb, *last;
 
                unix_state_lock(sk);
+               if (sock_flag(sk, SOCK_DEAD)) {
+                       err = -ECONNRESET;
+                       goto unlock;
+               }
                last = skb = skb_peek(&sk->sk_receive_queue);
 again:
                if (skb == NULL) {