linux-yocto/include/linux/sunrpc/xprtsock.h
Benjamin Coddington af84537dbd SUNRPC: fix race to sk_err after xs_error_report
Since commit 4f8943f808 ("SUNRPC: Replace direct task wakeups from
softirq context") there has been a race to the value of the sk_err if both
XPRT_SOCK_WAKE_ERROR and XPRT_SOCK_WAKE_DISCONNECT are set.  In that case,
we may end up losing the sk_err value that existed when xs_error_report was
called.

Fix this by reverting to the previous behavior: instead of using SO_ERROR
to retrieve the value at a later time (which might also return sk_err_soft),
copy the sk_err value onto struct sock_xprt, and use that value to wake
pending tasks.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Fixes: 4f8943f808 ("SUNRPC: Replace direct task wakeups from softirq context")
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2019-10-10 16:14:28 -04:00

97 lines
1.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/include/linux/sunrpc/xprtsock.h
*
* Declarations for the RPC transport socket provider.
*/
#ifndef _LINUX_SUNRPC_XPRTSOCK_H
#define _LINUX_SUNRPC_XPRTSOCK_H
#ifdef __KERNEL__
int init_socket_xprt(void);
void cleanup_socket_xprt(void);
#define RPC_MIN_RESVPORT (1U)
#define RPC_MAX_RESVPORT (65535U)
#define RPC_DEF_MIN_RESVPORT (665U)
#define RPC_DEF_MAX_RESVPORT (1023U)
struct sock_xprt {
struct rpc_xprt xprt;
/*
* Network layer
*/
struct socket * sock;
struct sock * inet;
struct file * file;
/*
* State of TCP reply receive
*/
struct {
struct {
__be32 fraghdr,
xid,
calldir;
} __attribute__((packed));
u32 offset,
len;
unsigned long copied;
} recv;
/*
* State of TCP transmit queue
*/
struct {
u32 offset;
} xmit;
/*
* Connection of transports
*/
unsigned long sock_state;
struct delayed_work connect_worker;
struct work_struct error_worker;
struct work_struct recv_worker;
struct mutex recv_mutex;
struct sockaddr_storage srcaddr;
unsigned short srcport;
int xprt_err;
/*
* UDP socket buffer size parameters
*/
size_t rcvsize,
sndsize;
struct rpc_timeout tcp_timeout;
/*
* Saved socket callback addresses
*/
void (*old_data_ready)(struct sock *);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
void (*old_error_report)(struct sock *);
};
/*
* TCP RPC flags
*/
#define XPRT_SOCK_CONNECTING 1U
#define XPRT_SOCK_DATA_READY (2)
#define XPRT_SOCK_UPD_TIMEOUT (3)
#define XPRT_SOCK_WAKE_ERROR (4)
#define XPRT_SOCK_WAKE_WRITE (5)
#define XPRT_SOCK_WAKE_PENDING (6)
#define XPRT_SOCK_WAKE_DISCONNECT (7)
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_XPRTSOCK_H */