1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
/*
* linux/include/linux/sunrpc/clnt_xprt.h
*
* Declarations for the RPC transport interface.
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
#ifndef _LINUX_SUNRPC_XPRT_H
#define _LINUX_SUNRPC_XPRT_H
#include <linux/uio.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/sunrpc/sched.h>
/*
* Maximum number of iov's we use.
*/
#define MAX_IOVEC 10
/*
* The transport code maintains an estimate on the maximum number of out-
* standing RPC requests, using a smoothed version of the congestion
* avoidance implemented in 44BSD. This is basically the Van Jacobson
* slow start algorithm: If a retransmit occurs, the congestion window is
* halved; otherwise, it is incremented by 1/cwnd when
*
* - a reply is received and
* - a full number of requests are outstanding and
* - the congestion window hasn't been updated recently.
*
* Upper procedures may check whether a request would block waiting for
* a free RPC slot by using the RPC_CONGESTED() macro.
*
* Note: on machines with low memory we should probably use a smaller
* MAXREQS value: At 32 outstanding reqs with 8 megs of RAM, fragment
* reassembly will frequently run out of memory.
* Come Linux 2.3, we'll handle fragments directly.
*/
#define RPC_MAXCONG 16
#define RPC_MAXREQS (RPC_MAXCONG + 1)
#define RPC_CWNDSCALE 256
#define RPC_MAXCWND (RPC_MAXCONG * RPC_CWNDSCALE)
#define RPC_INITCWND RPC_CWNDSCALE
#define RPCXPRT_CONGESTED(xprt) \
((xprt)->cong >= (xprt)->cwnd)
/* Default timeout values */
#define RPC_MAX_UDP_TIMEOUT (60*HZ)
#define RPC_MAX_TCP_TIMEOUT (600*HZ)
/* RPC call and reply header size as number of 32bit words (verifier
* size computed separately)
*/
#define RPC_CALLHDRSIZE 6
#define RPC_REPHDRSIZE 4
/*
* This describes a timeout strategy
*/
struct rpc_timeout {
unsigned long to_current, /* current timeout */
to_initval, /* initial timeout */
to_maxval, /* max timeout */
to_increment, /* if !exponential */
to_resrvval; /* reserve timeout */
short to_retries; /* max # of retries */
unsigned char to_exponential;
};
/*
* This is the RPC buffer
*/
struct rpc_iov {
struct iovec io_vec[MAX_IOVEC];
unsigned int io_nr;
unsigned int io_len;
};
/*
* This describes a complete RPC request
*/
struct rpc_rqst {
/*
* This is the user-visible part
*/
struct rpc_xprt * rq_xprt; /* RPC client */
struct rpc_timeout rq_timeout; /* timeout parms */
struct rpc_iov rq_snd_buf; /* send buffer */
struct rpc_iov rq_rcv_buf; /* recv buffer */
/*
* This is the private part
*/
struct rpc_task * rq_task; /* RPC task data */
__u32 rq_xid; /* request XID */
struct rpc_rqst * rq_next; /* free list */
unsigned char rq_damaged; /* reply being received */
/*
* For authentication (e.g. auth_des)
*/
u32 rq_creddata[2];
/*
* Partial send handling
*/
u32 rq_bytes_sent; /* Bytes we have sent */
#ifdef RPC_PROFILE
unsigned long rq_xtime; /* when transmitted */
#endif
};
#define rq_svec rq_snd_buf.io_vec
#define rq_snr rq_snd_buf.io_nr
#define rq_slen rq_snd_buf.io_len
#define rq_rvec rq_rcv_buf.io_vec
#define rq_rnr rq_rcv_buf.io_nr
#define rq_rlen rq_rcv_buf.io_len
struct rpc_xprt {
struct socket * sock; /* BSD socket layer */
struct sock * inet; /* INET layer */
struct rpc_timeout timeout; /* timeout parms */
struct sockaddr_in addr; /* server address */
int prot; /* IP protocol */
unsigned long cong; /* current congestion */
unsigned long cwnd; /* congestion window */
unsigned long congtime; /* hold cwnd until then */
struct rpc_wait_queue sending; /* requests waiting to send */
struct rpc_wait_queue pending; /* requests in flight */
struct rpc_wait_queue backlog; /* waiting for slot */
struct rpc_wait_queue reconn; /* waiting for reconnect */
struct rpc_rqst * free; /* free slots */
struct rpc_rqst slot[RPC_MAXREQS];
unsigned int connected : 1, /* TCP: connected */
write_space: 1, /* TCP: can send */
shutdown : 1, /* being shut down */
nocong : 1, /* no congestion control */
stream : 1, /* TCP */
tcp_more : 1, /* more record fragments */
connecting : 1; /* being reconnected */
/*
* State of TCP reply receive stuff
*/
u32 tcp_recm; /* Fragment header */
u32 tcp_xid; /* Current XID */
unsigned int tcp_reclen, /* fragment length */
tcp_offset, /* fragment offset */
tcp_copied; /* copied to request */
struct list_head rx_pending; /* receive pending list */
/*
* Send stuff
*/
struct rpc_task * snd_task; /* Task blocked in send */
void (*old_data_ready)(struct sock *, int);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
wait_queue_head_t cong_wait;
};
#ifdef __KERNEL__
struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr,
struct rpc_timeout *toparms);
int xprt_destroy(struct rpc_xprt *);
void xprt_shutdown(struct rpc_xprt *);
void xprt_default_timeout(struct rpc_timeout *, int);
void xprt_set_timeout(struct rpc_timeout *, unsigned int,
unsigned long);
int xprt_reserve(struct rpc_task *);
void xprt_transmit(struct rpc_task *);
void xprt_receive(struct rpc_task *);
int xprt_adjust_timeout(struct rpc_timeout *);
void xprt_release(struct rpc_task *);
void xprt_reconnect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *);
void __rpciod_tcp_dispatcher(void);
extern struct list_head rpc_xprt_pending;
static inline
int xprt_tcp_pending(void)
{
return !list_empty(&rpc_xprt_pending);
}
static inline
void rpciod_tcp_dispatcher(void)
{
if (xprt_tcp_pending())
__rpciod_tcp_dispatcher();
}
#endif /* __KERNEL__*/
#endif /* _LINUX_SUNRPC_XPRT_H */
|