Blame view

net/9p/trans_fd.c 23.9 KB
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1
2
3
4
5
6
7
  /*
   * linux/fs/9p/trans_fd.c
   *
   * Fd transport layer.  Includes deprecated socket layer.
   *
   *  Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
   *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
8
   *  Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   *  Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License version 2
   *  as published by the Free Software Foundation.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to:
   *  Free Software Foundation
   *  51 Franklin Street, Fifth Floor
   *  Boston, MA  02111-1301  USA
   *
   */
5d3851530   Joe Perches   9p: Reduce object...
27
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
28
29
30
31
  #include <linux/in.h>
  #include <linux/module.h>
  #include <linux/net.h>
  #include <linux/ipv6.h>
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
32
  #include <linux/kthread.h>
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
33
34
35
36
37
38
39
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/un.h>
  #include <linux/uaccess.h>
  #include <linux/inet.h>
  #include <linux/idr.h>
  #include <linux/file.h>
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
40
  #include <linux/parser.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
41
  #include <linux/slab.h>
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
42
  #include <net/9p/9p.h>
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
43
  #include <net/9p/client.h>
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
44
  #include <net/9p/transport.h>
6b18662e2   Al Viro   9p connect fixes
45
  #include <linux/syscalls.h> /* killme */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
46
  #define P9_PORT 564
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
47
  #define MAX_SOCK_BUF (64*1024)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
48
  #define MAXPOLLWADDR	2
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
49

ee443996a   Eric Van Hensbergen   9p: Documentation...
50
51
52
53
54
55
56
  /**
   * struct p9_fd_opts - per-transport options
   * @rfd: file descriptor for reading (trans=fd)
   * @wfd: file descriptor for writing (trans=fd)
   * @port: port to connect to (trans=tcp)
   *
   */
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
57
58
59
60
61
  struct p9_fd_opts {
  	int rfd;
  	int wfd;
  	u16 port;
  };
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
62

ee443996a   Eric Van Hensbergen   9p: Documentation...
63
64
65
66
67
68
69
  /**
   * struct p9_trans_fd - transport state
   * @rd: reference to file to read from
   * @wr: reference of file to write to
   * @conn: connection state reference
   *
   */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
70
71
72
  struct p9_trans_fd {
  	struct file *rd;
  	struct file *wr;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
73
  	struct p9_conn *conn;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
74
  };
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
75
76
77
78
  /*
    * Option Parsing (code inspired by NFS code)
    *  - a little lazy - parse all fd-transport options
    */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
79

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
80
81
  enum {
  	/* Options that take integer arguments */
55762690e   Latchesar Ionkov   9p: add missing e...
82
  	Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
83
  };
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
84

a447c0932   Steven Whitehouse   vfs: Use const fo...
85
  static const match_table_t tokens = {
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
86
87
88
  	{Opt_port, "port=%u"},
  	{Opt_rfdno, "rfdno=%u"},
  	{Opt_wfdno, "wfdno=%u"},
55762690e   Latchesar Ionkov   9p: add missing e...
89
  	{Opt_err, NULL},
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
90
  };
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
91

8a0dc95fd   Eric Van Hensbergen   9p: transport API...
92
93
94
95
96
97
  enum {
  	Rworksched = 1,		/* read work scheduled or running */
  	Rpending = 2,		/* can read */
  	Wworksched = 4,		/* write work scheduled or running */
  	Wpending = 8,		/* can write */
  };
992b3f1db   Tejun Heo   9p-trans_fd: use ...
98
99
100
101
  struct p9_poll_wait {
  	struct p9_conn *conn;
  	wait_queue_t wait;
  	wait_queue_head_t *wait_addr;
ee443996a   Eric Van Hensbergen   9p: Documentation...
102
103
104
105
  };
  
  /**
   * struct p9_conn - fd mux connection state information
ee443996a   Eric Van Hensbergen   9p: Documentation...
106
   * @mux_list: list link for mux to manage multiple connections (?)
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
107
   * @client: reference to client instance for this connection
ee443996a   Eric Van Hensbergen   9p: Documentation...
108
   * @err: error state
ee443996a   Eric Van Hensbergen   9p: Documentation...
109
110
   * @req_list: accounting for requests which have been sent
   * @unsent_req_list: accounting for requests that haven't been sent
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
111
112
113
   * @req: current request being processed (if any)
   * @tmp_buf: temporary buffer to read in header
   * @rsize: amount to read for current frame
ee443996a   Eric Van Hensbergen   9p: Documentation...
114
115
116
117
118
   * @rpos: read position in current frame
   * @rbuf: current read buffer
   * @wpos: write position for current frame
   * @wsize: amount of data to write for current frame
   * @wbuf: current write buffer
0e15597eb   Abhishek Kulkarni   9p: minor comment...
119
   * @poll_pending_link: pending links to be polled per conn
ee443996a   Eric Van Hensbergen   9p: Documentation...
120
   * @poll_wait: array of wait_q's for various worker threads
ee443996a   Eric Van Hensbergen   9p: Documentation...
121
122
123
124
125
126
   * @pt: poll state
   * @rq: current read work
   * @wq: current write work
   * @wsched: ????
   *
   */
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
127
128
  
  struct p9_conn {
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
129
  	struct list_head mux_list;
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
130
  	struct p9_client *client;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
131
  	int err;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
132
133
  	struct list_head req_list;
  	struct list_head unsent_req_list;
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
134
135
136
  	struct p9_req_t *req;
  	char tmp_buf[7];
  	int rsize;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
137
138
139
140
141
  	int rpos;
  	char *rbuf;
  	int wpos;
  	int wsize;
  	char *wbuf;
992b3f1db   Tejun Heo   9p-trans_fd: use ...
142
143
  	struct list_head poll_pending_link;
  	struct p9_poll_wait poll_wait[MAXPOLLWADDR];
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
144
145
146
147
148
  	poll_table pt;
  	struct work_struct rq;
  	struct work_struct wq;
  	unsigned long wsched;
  };
aa70c585b   Tejun Heo   net/9p: replace p...
149
  static void p9_poll_workfn(struct work_struct *work);
992b3f1db   Tejun Heo   9p-trans_fd: use ...
150
151
  static DEFINE_SPINLOCK(p9_poll_lock);
  static LIST_HEAD(p9_poll_pending_list);
aa70c585b   Tejun Heo   net/9p: replace p...
152
  static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
153

992b3f1db   Tejun Heo   9p-trans_fd: use ...
154
  static void p9_mux_poll_stop(struct p9_conn *m)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
155
  {
992b3f1db   Tejun Heo   9p-trans_fd: use ...
156
157
  	unsigned long flags;
  	int i;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
158

992b3f1db   Tejun Heo   9p-trans_fd: use ...
159
160
  	for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
  		struct p9_poll_wait *pwait = &m->poll_wait[i];
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
161

992b3f1db   Tejun Heo   9p-trans_fd: use ...
162
163
164
  		if (pwait->wait_addr) {
  			remove_wait_queue(pwait->wait_addr, &pwait->wait);
  			pwait->wait_addr = NULL;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
165
  		}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
166
  	}
992b3f1db   Tejun Heo   9p-trans_fd: use ...
167
168
169
  	spin_lock_irqsave(&p9_poll_lock, flags);
  	list_del_init(&m->poll_pending_link);
  	spin_unlock_irqrestore(&p9_poll_lock, flags);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
170
171
172
  }
  
  /**
5503ac565   Eric Van Hensbergen   9p: remove unnece...
173
174
175
   * p9_conn_cancel - cancel all pending requests with error
   * @m: mux data
   * @err: error code
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
176
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
177
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
178

51a87c552   Eric Van Hensbergen   9p: rework client...
179
  static void p9_conn_cancel(struct p9_conn *m, int err)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
180
  {
673d62cda   Eric Van Hensbergen   9p: apply common ...
181
  	struct p9_req_t *req, *rtmp;
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
182
  	unsigned long flags;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
183
  	LIST_HEAD(cancel_list);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
184

5d3851530   Joe Perches   9p: Reduce object...
185
186
  	p9_debug(P9_DEBUG_ERROR, "mux %p err %d
  ", m, err);
7eb923b80   Eric Van Hensbergen   9p: add more cons...
187

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
188
  	spin_lock_irqsave(&m->client->lock, flags);
7eb923b80   Eric Van Hensbergen   9p: add more cons...
189
190
191
192
193
194
195
  
  	if (m->err) {
  		spin_unlock_irqrestore(&m->client->lock, flags);
  		return;
  	}
  
  	m->err = err;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
196
  	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
673d62cda   Eric Van Hensbergen   9p: apply common ...
197
198
199
  		req->status = REQ_STATUS_ERROR;
  		if (!req->t_err)
  			req->t_err = err;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
200
201
202
  		list_move(&req->req_list, &cancel_list);
  	}
  	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
673d62cda   Eric Van Hensbergen   9p: apply common ...
203
204
205
  		req->status = REQ_STATUS_ERROR;
  		if (!req->t_err)
  			req->t_err = err;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
206
  		list_move(&req->req_list, &cancel_list);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
207
  	}
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
208
  	spin_unlock_irqrestore(&m->client->lock, flags);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
209

5503ac565   Eric Van Hensbergen   9p: remove unnece...
210
  	list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
5d3851530   Joe Perches   9p: Reduce object...
211
212
  		p9_debug(P9_DEBUG_ERROR, "call back req %p
  ", req);
1bab88b23   Latchesar Ionkov   net/9p: handle co...
213
  		list_del(&req->req_list);
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
214
  		p9_client_cb(m->client, req);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
215
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
216
  }
29af9309d   Julia Lawall   net/9p/trans_fd.c...
217
  static int
5503ac565   Eric Van Hensbergen   9p: remove unnece...
218
  p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
219
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
220
221
  	int ret, n;
  	struct p9_trans_fd *ts = NULL;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
222

5503ac565   Eric Van Hensbergen   9p: remove unnece...
223
224
  	if (client && client->status == Connected)
  		ts = client->trans;
7dc5d24be   Tejun Heo   9p-trans_fd: fix ...
225

5503ac565   Eric Van Hensbergen   9p: remove unnece...
226
227
  	if (!ts)
  		return -EREMOTEIO;
7dc5d24be   Tejun Heo   9p-trans_fd: fix ...
228

5503ac565   Eric Van Hensbergen   9p: remove unnece...
229
230
  	if (!ts->rd->f_op || !ts->rd->f_op->poll)
  		return -EIO;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
231

5503ac565   Eric Van Hensbergen   9p: remove unnece...
232
233
  	if (!ts->wr->f_op || !ts->wr->f_op->poll)
  		return -EIO;
992b3f1db   Tejun Heo   9p-trans_fd: use ...
234

5503ac565   Eric Van Hensbergen   9p: remove unnece...
235
236
237
  	ret = ts->rd->f_op->poll(ts->rd, pt);
  	if (ret < 0)
  		return ret;
992b3f1db   Tejun Heo   9p-trans_fd: use ...
238

5503ac565   Eric Van Hensbergen   9p: remove unnece...
239
240
241
242
243
244
245
246
  	if (ts->rd != ts->wr) {
  		n = ts->wr->f_op->poll(ts->wr, pt);
  		if (n < 0)
  			return n;
  		ret = (ret & ~POLLOUT) | (n & ~POLLIN);
  	}
  
  	return ret;
992b3f1db   Tejun Heo   9p-trans_fd: use ...
247
  }
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
248
  /**
5503ac565   Eric Van Hensbergen   9p: remove unnece...
249
250
251
252
   * p9_fd_read- read from a fd
   * @client: client instance
   * @v: buffer to receive data into
   * @len: size of receive buffer
ee443996a   Eric Van Hensbergen   9p: Documentation...
253
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
254
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
255

5503ac565   Eric Van Hensbergen   9p: remove unnece...
256
  static int p9_fd_read(struct p9_client *client, void *v, int len)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
257
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
258
259
  	int ret;
  	struct p9_trans_fd *ts = NULL;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
260

5503ac565   Eric Van Hensbergen   9p: remove unnece...
261
262
  	if (client && client->status != Disconnected)
  		ts = client->trans;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
263

5503ac565   Eric Van Hensbergen   9p: remove unnece...
264
265
  	if (!ts)
  		return -EREMOTEIO;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
266

5503ac565   Eric Van Hensbergen   9p: remove unnece...
267
  	if (!(ts->rd->f_flags & O_NONBLOCK))
5d3851530   Joe Perches   9p: Reduce object...
268
269
  		p9_debug(P9_DEBUG_ERROR, "blocking read ...
  ");
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
270

5503ac565   Eric Van Hensbergen   9p: remove unnece...
271
272
273
274
  	ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
  	if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
  		client->status = Disconnected;
  	return ret;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
275
276
277
  }
  
  /**
5503ac565   Eric Van Hensbergen   9p: remove unnece...
278
279
   * p9_read_work - called when there is some data to be read from a transport
   * @work: container of work to be done
ee443996a   Eric Van Hensbergen   9p: Documentation...
280
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
281
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
282

5503ac565   Eric Van Hensbergen   9p: remove unnece...
283
  static void p9_read_work(struct work_struct *work)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
284
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
285
286
  	int n, err;
  	struct p9_conn *m;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
287
288
  
  	m = container_of(work, struct p9_conn, rq);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
289
290
291
  
  	if (m->err < 0)
  		return;
5d3851530   Joe Perches   9p: Reduce object...
292
293
  	p9_debug(P9_DEBUG_TRANS, "start mux %p pos %d
  ", m, m->rpos);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
294

1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
295
296
  	if (!m->rbuf) {
  		m->rbuf = m->tmp_buf;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
297
  		m->rpos = 0;
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
298
  		m->rsize = 7; /* start by reading header */
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
299
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
300
  	clear_bit(Rpending, &m->wsched);
5d3851530   Joe Perches   9p: Reduce object...
301
302
303
  	p9_debug(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d
  ",
  		 m, m->rpos, m->rsize, m->rsize-m->rpos);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
304
  	err = p9_fd_read(m->client, m->rbuf + m->rpos,
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
305
  						m->rsize - m->rpos);
5d3851530   Joe Perches   9p: Reduce object...
306
307
  	p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes
  ", m, err);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
308
  	if (err == -EAGAIN) {
0462194d3   Simon Derr   9P: Fix race in p...
309
  		goto end_clear;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
310
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
311

5503ac565   Eric Van Hensbergen   9p: remove unnece...
312
313
314
315
  	if (err <= 0)
  		goto error;
  
  	m->rpos += err;
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
316
317
318
  
  	if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
  		u16 tag;
5d3851530   Joe Perches   9p: Reduce object...
319
320
  		p9_debug(P9_DEBUG_TRANS, "got new header
  ");
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
321
322
  
  		n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
5503ac565   Eric Van Hensbergen   9p: remove unnece...
323
  		if (n >= m->client->msize) {
5d3851530   Joe Perches   9p: Reduce object...
324
325
326
  			p9_debug(P9_DEBUG_ERROR,
  				 "requested packet size too big: %d
  ", n);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
327
328
329
  			err = -EIO;
  			goto error;
  		}
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
330
  		tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
5d3851530   Joe Perches   9p: Reduce object...
331
332
333
  		p9_debug(P9_DEBUG_TRANS,
  			 "mux %p pkt: size: %d bytes tag: %d
  ", m, n, tag);
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
334
335
  
  		m->req = p9_tag_lookup(m->client, tag);
1bab88b23   Latchesar Ionkov   net/9p: handle co...
336
337
  		if (!m->req || (m->req->status != REQ_STATUS_SENT &&
  					m->req->status != REQ_STATUS_FLSH)) {
5d3851530   Joe Perches   9p: Reduce object...
338
339
340
  			p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d
  ",
  				 tag);
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
341
342
343
344
345
346
  			err = -EIO;
  			goto error;
  		}
  
  		if (m->req->rc == NULL) {
  			m->req->rc = kmalloc(sizeof(struct p9_fcall) +
eeff66ef6   Aneesh Kumar K.V   net/9p: Convert t...
347
  						m->client->msize, GFP_NOFS);
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
348
349
350
351
352
353
354
355
356
357
  			if (!m->req->rc) {
  				m->req = NULL;
  				err = -ENOMEM;
  				goto error;
  			}
  		}
  		m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
  		memcpy(m->rbuf, m->tmp_buf, m->rsize);
  		m->rsize = n;
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
358

1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
359
360
  	/* not an else because some packets (like clunk) have no payload */
  	if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
5d3851530   Joe Perches   9p: Reduce object...
361
362
  		p9_debug(P9_DEBUG_TRANS, "got new packet
  ");
7eb923b80   Eric Van Hensbergen   9p: add more cons...
363
  		spin_lock(&m->client->lock);
1bab88b23   Latchesar Ionkov   net/9p: handle co...
364
365
  		if (m->req->status != REQ_STATUS_ERROR)
  			m->req->status = REQ_STATUS_RCVD;
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
366
  		list_del(&m->req->req_list);
7eb923b80   Eric Van Hensbergen   9p: add more cons...
367
  		spin_unlock(&m->client->lock);
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
368
  		p9_client_cb(m->client, m->req);
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
369
370
371
  		m->rbuf = NULL;
  		m->rpos = 0;
  		m->rsize = 0;
1b0a763bd   Eric Van Hensbergen   9p: use the rcall...
372
  		m->req = NULL;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
373
  	}
0462194d3   Simon Derr   9P: Fix race in p...
374
375
  end_clear:
  	clear_bit(Rworksched, &m->wsched);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
376
377
378
379
380
  	if (!list_empty(&m->req_list)) {
  		if (test_and_clear_bit(Rpending, &m->wsched))
  			n = POLLIN;
  		else
  			n = p9_fd_poll(m->client, NULL);
0462194d3   Simon Derr   9P: Fix race in p...
381
  		if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
5d3851530   Joe Perches   9p: Reduce object...
382
383
  			p9_debug(P9_DEBUG_TRANS, "sched read work %p
  ", m);
61edeeed9   Tejun Heo   net/9p: use syste...
384
  			schedule_work(&m->rq);
0462194d3   Simon Derr   9P: Fix race in p...
385
386
  		}
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
387
388
  
  	return;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
389
390
391
392
393
394
395
396
397
398
  error:
  	p9_conn_cancel(m, err);
  	clear_bit(Rworksched, &m->wsched);
  }
  
  /**
   * p9_fd_write - write to a socket
   * @client: client instance
   * @v: buffer to send data from
   * @len: size of send buffer
ee443996a   Eric Van Hensbergen   9p: Documentation...
399
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
400
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
401

5503ac565   Eric Van Hensbergen   9p: remove unnece...
402
  static int p9_fd_write(struct p9_client *client, void *v, int len)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
403
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
404
405
406
  	int ret;
  	mm_segment_t oldfs;
  	struct p9_trans_fd *ts = NULL;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
407

5503ac565   Eric Van Hensbergen   9p: remove unnece...
408
409
  	if (client && client->status != Disconnected)
  		ts = client->trans;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
410

5503ac565   Eric Van Hensbergen   9p: remove unnece...
411
412
  	if (!ts)
  		return -EREMOTEIO;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
413

5503ac565   Eric Van Hensbergen   9p: remove unnece...
414
  	if (!(ts->wr->f_flags & O_NONBLOCK))
5d3851530   Joe Perches   9p: Reduce object...
415
416
  		p9_debug(P9_DEBUG_ERROR, "blocking write ...
  ");
992b3f1db   Tejun Heo   9p-trans_fd: use ...
417

5503ac565   Eric Van Hensbergen   9p: remove unnece...
418
419
420
  	oldfs = get_fs();
  	set_fs(get_ds());
  	/* The cast to a user pointer is valid due to the set_fs() */
e3db6cb42   Hannes Eder   9p: fix sparse wa...
421
  	ret = vfs_write(ts->wr, (__force void __user *)v, len, &ts->wr->f_pos);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
422
  	set_fs(oldfs);
992b3f1db   Tejun Heo   9p-trans_fd: use ...
423

5503ac565   Eric Van Hensbergen   9p: remove unnece...
424
425
426
  	if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
  		client->status = Disconnected;
  	return ret;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
427
428
429
430
  }
  
  /**
   * p9_write_work - called when a transport can send some data
ee443996a   Eric Van Hensbergen   9p: Documentation...
431
432
   * @work: container for work to be done
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
433
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
434

8a0dc95fd   Eric Van Hensbergen   9p: transport API...
435
436
437
438
  static void p9_write_work(struct work_struct *work)
  {
  	int n, err;
  	struct p9_conn *m;
673d62cda   Eric Van Hensbergen   9p: apply common ...
439
  	struct p9_req_t *req;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
440
441
442
443
444
445
446
447
448
  
  	m = container_of(work, struct p9_conn, wq);
  
  	if (m->err < 0) {
  		clear_bit(Wworksched, &m->wsched);
  		return;
  	}
  
  	if (!m->wsize) {
759f42987   Simon Derr   9P: Fix race betw...
449
  		spin_lock(&m->client->lock);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
450
451
  		if (list_empty(&m->unsent_req_list)) {
  			clear_bit(Wworksched, &m->wsched);
759f42987   Simon Derr   9P: Fix race betw...
452
  			spin_unlock(&m->client->lock);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
453
454
  			return;
  		}
673d62cda   Eric Van Hensbergen   9p: apply common ...
455
  		req = list_entry(m->unsent_req_list.next, struct p9_req_t,
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
456
  			       req_list);
673d62cda   Eric Van Hensbergen   9p: apply common ...
457
  		req->status = REQ_STATUS_SENT;
5d3851530   Joe Perches   9p: Reduce object...
458
459
  		p9_debug(P9_DEBUG_TRANS, "move req %p
  ", req);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
460
  		list_move_tail(&req->req_list, &m->req_list);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
461

673d62cda   Eric Van Hensbergen   9p: apply common ...
462
463
  		m->wbuf = req->tc->sdata;
  		m->wsize = req->tc->size;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
464
  		m->wpos = 0;
673d62cda   Eric Van Hensbergen   9p: apply common ...
465
  		spin_unlock(&m->client->lock);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
466
  	}
5d3851530   Joe Perches   9p: Reduce object...
467
468
469
  	p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d
  ",
  		 m, m->wpos, m->wsize);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
470
  	clear_bit(Wpending, &m->wsched);
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
471
  	err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
5d3851530   Joe Perches   9p: Reduce object...
472
473
  	p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes
  ", m, err);
584a8c13d   Simon Derr   9P: Fix race in p...
474
475
  	if (err == -EAGAIN)
  		goto end_clear;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
476
477
478
479
480
481
482
483
484
485
486
  
  	if (err < 0)
  		goto error;
  	else if (err == 0) {
  		err = -EREMOTEIO;
  		goto error;
  	}
  
  	m->wpos += err;
  	if (m->wpos == m->wsize)
  		m->wpos = m->wsize = 0;
584a8c13d   Simon Derr   9P: Fix race in p...
487
488
  end_clear:
  	clear_bit(Wworksched, &m->wsched);
1957b3a86   Simon Derr   9P: fix test at t...
489
  	if (m->wsize || !list_empty(&m->unsent_req_list)) {
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
490
491
492
  		if (test_and_clear_bit(Wpending, &m->wsched))
  			n = POLLOUT;
  		else
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
493
  			n = p9_fd_poll(m->client, NULL);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
494

584a8c13d   Simon Derr   9P: Fix race in p...
495
496
  		if ((n & POLLOUT) &&
  		   !test_and_set_bit(Wworksched, &m->wsched)) {
5d3851530   Joe Perches   9p: Reduce object...
497
498
  			p9_debug(P9_DEBUG_TRANS, "sched write work %p
  ", m);
61edeeed9   Tejun Heo   net/9p: use syste...
499
  			schedule_work(&m->wq);
584a8c13d   Simon Derr   9P: Fix race in p...
500
501
  		}
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
502
503
504
505
506
507
508
  
  	return;
  
  error:
  	p9_conn_cancel(m, err);
  	clear_bit(Wworksched, &m->wsched);
  }
95c961747   Eric Dumazet   net: cleanup unsi...
509
  static int p9_pollwake(wait_queue_t *wait, unsigned int mode, int sync, void *key)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
510
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
511
512
513
514
  	struct p9_poll_wait *pwait =
  		container_of(wait, struct p9_poll_wait, wait);
  	struct p9_conn *m = pwait->conn;
  	unsigned long flags;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
515

5503ac565   Eric Van Hensbergen   9p: remove unnece...
516
517
518
519
  	spin_lock_irqsave(&p9_poll_lock, flags);
  	if (list_empty(&m->poll_pending_link))
  		list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
  	spin_unlock_irqrestore(&p9_poll_lock, flags);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
520

aa70c585b   Tejun Heo   net/9p: replace p...
521
522
  	schedule_work(&p9_poll_work);
  	return 1;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
523
524
525
  }
  
  /**
5503ac565   Eric Van Hensbergen   9p: remove unnece...
526
527
528
529
   * p9_pollwait - add poll task to the wait queue
   * @filp: file pointer being polled
   * @wait_address: wait_q to block on
   * @p: poll state
ee443996a   Eric Van Hensbergen   9p: Documentation...
530
   *
5503ac565   Eric Van Hensbergen   9p: remove unnece...
531
   * called by files poll operation to add v9fs-poll task to files wait queue
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
532
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
533

5503ac565   Eric Van Hensbergen   9p: remove unnece...
534
535
  static void
  p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
536
  {
5503ac565   Eric Van Hensbergen   9p: remove unnece...
537
538
539
  	struct p9_conn *m = container_of(p, struct p9_conn, pt);
  	struct p9_poll_wait *pwait = NULL;
  	int i;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
540

5503ac565   Eric Van Hensbergen   9p: remove unnece...
541
542
543
544
  	for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
  		if (m->poll_wait[i].wait_addr == NULL) {
  			pwait = &m->poll_wait[i];
  			break;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
545
  		}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
546
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
547
  	if (!pwait) {
5d3851530   Joe Perches   9p: Reduce object...
548
549
  		p9_debug(P9_DEBUG_ERROR, "not enough wait_address slots
  ");
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
550
551
  		return;
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
552
553
554
555
556
  	pwait->conn = m;
  	pwait->wait_addr = wait_address;
  	init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
  	add_wait_queue(wait_address, &pwait->wait);
  }
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
557

5503ac565   Eric Van Hensbergen   9p: remove unnece...
558
559
560
561
562
563
  /**
   * p9_conn_create - allocate and initialize the per-session mux data
   * @client: client instance
   *
   * Note: Creates the polling task if this is the first session.
   */
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
564

5503ac565   Eric Van Hensbergen   9p: remove unnece...
565
566
  static struct p9_conn *p9_conn_create(struct p9_client *client)
  {
95820a365   Tejun Heo   9p: drop broken u...
567
  	int n;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
568
  	struct p9_conn *m;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
569

5d3851530   Joe Perches   9p: Reduce object...
570
571
  	p9_debug(P9_DEBUG_TRANS, "client %p msize %d
  ", client, client->msize);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
572
573
574
  	m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
  	if (!m)
  		return ERR_PTR(-ENOMEM);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
575

5503ac565   Eric Van Hensbergen   9p: remove unnece...
576
577
  	INIT_LIST_HEAD(&m->mux_list);
  	m->client = client;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
578

5503ac565   Eric Van Hensbergen   9p: remove unnece...
579
580
581
582
583
584
  	INIT_LIST_HEAD(&m->req_list);
  	INIT_LIST_HEAD(&m->unsent_req_list);
  	INIT_WORK(&m->rq, p9_read_work);
  	INIT_WORK(&m->wq, p9_write_work);
  	INIT_LIST_HEAD(&m->poll_pending_link);
  	init_poll_funcptr(&m->pt, p9_pollwait);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
585

5503ac565   Eric Van Hensbergen   9p: remove unnece...
586
587
  	n = p9_fd_poll(client, &m->pt);
  	if (n & POLLIN) {
5d3851530   Joe Perches   9p: Reduce object...
588
589
  		p9_debug(P9_DEBUG_TRANS, "mux %p can read
  ", m);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
590
591
  		set_bit(Rpending, &m->wsched);
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
592

5503ac565   Eric Van Hensbergen   9p: remove unnece...
593
  	if (n & POLLOUT) {
5d3851530   Joe Perches   9p: Reduce object...
594
595
  		p9_debug(P9_DEBUG_TRANS, "mux %p can write
  ", m);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
596
597
  		set_bit(Wpending, &m->wsched);
  	}
5503ac565   Eric Van Hensbergen   9p: remove unnece...
598
599
  	return m;
  }
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
600

5503ac565   Eric Van Hensbergen   9p: remove unnece...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
  /**
   * p9_poll_mux - polls a mux and schedules read or write works if necessary
   * @m: connection to poll
   *
   */
  
  static void p9_poll_mux(struct p9_conn *m)
  {
  	int n;
  
  	if (m->err < 0)
  		return;
  
  	n = p9_fd_poll(m->client, NULL);
  	if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
5d3851530   Joe Perches   9p: Reduce object...
616
617
  		p9_debug(P9_DEBUG_TRANS, "error mux %p err %d
  ", m, n);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
618
619
620
621
622
623
624
  		if (n >= 0)
  			n = -ECONNRESET;
  		p9_conn_cancel(m, n);
  	}
  
  	if (n & POLLIN) {
  		set_bit(Rpending, &m->wsched);
5d3851530   Joe Perches   9p: Reduce object...
625
626
  		p9_debug(P9_DEBUG_TRANS, "mux %p can read
  ", m);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
627
  		if (!test_and_set_bit(Rworksched, &m->wsched)) {
5d3851530   Joe Perches   9p: Reduce object...
628
629
  			p9_debug(P9_DEBUG_TRANS, "sched read work %p
  ", m);
61edeeed9   Tejun Heo   net/9p: use syste...
630
  			schedule_work(&m->rq);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
631
632
  		}
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
633

5503ac565   Eric Van Hensbergen   9p: remove unnece...
634
635
  	if (n & POLLOUT) {
  		set_bit(Wpending, &m->wsched);
5d3851530   Joe Perches   9p: Reduce object...
636
637
  		p9_debug(P9_DEBUG_TRANS, "mux %p can write
  ", m);
f64f9e719   Joe Perches   net: Move && and ...
638
639
  		if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
  		    !test_and_set_bit(Wworksched, &m->wsched)) {
5d3851530   Joe Perches   9p: Reduce object...
640
641
  			p9_debug(P9_DEBUG_TRANS, "sched write work %p
  ", m);
61edeeed9   Tejun Heo   net/9p: use syste...
642
  			schedule_work(&m->wq);
5503ac565   Eric Van Hensbergen   9p: remove unnece...
643
644
  		}
  	}
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
645
646
647
  }
  
  /**
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
648
   * p9_fd_request - send 9P request
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
649
650
   * The function can sleep until the request is scheduled for sending.
   * The function can be interrupted. Return from the function is not
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
651
   * a guarantee that the request is sent successfully.
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
652
   *
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
653
654
   * @client: client instance
   * @req: request to be sent
ee443996a   Eric Van Hensbergen   9p: Documentation...
655
   *
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
656
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
657

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
658
  static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
659
660
  {
  	int n;
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
661
662
  	struct p9_trans_fd *ts = client->trans;
  	struct p9_conn *m = ts->conn;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
663

5d3851530   Joe Perches   9p: Reduce object...
664
665
666
  	p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d
  ",
  		 m, current, req->tc, req->tc->id);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
667
  	if (m->err < 0)
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
668
  		return m->err;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
669

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
670
  	spin_lock(&client->lock);
7eb923b80   Eric Van Hensbergen   9p: add more cons...
671
  	req->status = REQ_STATUS_UNSENT;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
672
  	list_add_tail(&req->req_list, &m->unsent_req_list);
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
673
  	spin_unlock(&client->lock);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
674
675
676
677
  
  	if (test_and_clear_bit(Wpending, &m->wsched))
  		n = POLLOUT;
  	else
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
678
  		n = p9_fd_poll(m->client, NULL);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
679
680
  
  	if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
61edeeed9   Tejun Heo   net/9p: use syste...
681
  		schedule_work(&m->wq);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
682

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
683
  	return 0;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
684
  }
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
685
  static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
686
  {
7eb923b80   Eric Van Hensbergen   9p: add more cons...
687
  	int ret = 1;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
688

5d3851530   Joe Perches   9p: Reduce object...
689
690
  	p9_debug(P9_DEBUG_TRANS, "client %p req %p
  ", client, req);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
691

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
692
  	spin_lock(&client->lock);
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
693

91b8534fa   Eric Van Hensbergen   9p: make rpc code...
694
  	if (req->status == REQ_STATUS_UNSENT) {
1bab88b23   Latchesar Ionkov   net/9p: handle co...
695
  		list_del(&req->req_list);
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
696
  		req->status = REQ_STATUS_FLSHD;
7eb923b80   Eric Van Hensbergen   9p: add more cons...
697
  		ret = 0;
1bab88b23   Latchesar Ionkov   net/9p: handle co...
698
699
  	} else if (req->status == REQ_STATUS_SENT)
  		req->status = REQ_STATUS_FLSH;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
700

7eb923b80   Eric Van Hensbergen   9p: add more cons...
701
702
703
  	spin_unlock(&client->lock);
  
  	return ret;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
704
  }
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
705
  /**
0e15597eb   Abhishek Kulkarni   9p: minor comment...
706
707
708
   * parse_opts - parse mount options into p9_fd_opts structure
   * @params: options string passed from mount
   * @opts: fd transport-specific structure to parse options into
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
709
   *
bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
710
   * Returns 0 upon success, -ERRNO upon failure
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
711
   */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
712

bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
713
  static int parse_opts(char *params, struct p9_fd_opts *opts)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
714
  {
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
715
716
717
  	char *p;
  	substring_t args[MAX_OPT_ARGS];
  	int option;
d8c8a9e36   Eric Van Hensbergen   9p: fix option pa...
718
  	char *options, *tmp_options;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
719

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
720
721
722
  	opts->port = P9_PORT;
  	opts->rfd = ~0;
  	opts->wfd = ~0;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
723

bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
724
725
  	if (!params)
  		return 0;
d8c8a9e36   Eric Van Hensbergen   9p: fix option pa...
726
727
  	tmp_options = kstrdup(params, GFP_KERNEL);
  	if (!tmp_options) {
5d3851530   Joe Perches   9p: Reduce object...
728
729
730
  		p9_debug(P9_DEBUG_ERROR,
  			 "failed to allocate copy of option string
  ");
bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
731
732
  		return -ENOMEM;
  	}
d8c8a9e36   Eric Van Hensbergen   9p: fix option pa...
733
  	options = tmp_options;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
734

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
735
736
  	while ((p = strsep(&options, ",")) != NULL) {
  		int token;
bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
737
  		int r;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
738
739
740
  		if (!*p)
  			continue;
  		token = match_token(p, tokens, args);
15da4b161   Abhishek Kulkarni   net/9p: Fix crash...
741
742
743
  		if (token != Opt_err) {
  			r = match_int(&args[0], &option);
  			if (r < 0) {
5d3851530   Joe Perches   9p: Reduce object...
744
745
746
  				p9_debug(P9_DEBUG_ERROR,
  					 "integer field, but no integer?
  ");
15da4b161   Abhishek Kulkarni   net/9p: Fix crash...
747
748
  				continue;
  			}
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  		}
  		switch (token) {
  		case Opt_port:
  			opts->port = option;
  			break;
  		case Opt_rfdno:
  			opts->rfd = option;
  			break;
  		case Opt_wfdno:
  			opts->wfd = option;
  			break;
  		default:
  			continue;
  		}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
763
  	}
d8c8a9e36   Eric Van Hensbergen   9p: fix option pa...
764
765
  
  	kfree(tmp_options);
bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
766
  	return 0;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
767
  }
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
768

8b81ef589   Eric Van Hensbergen   9p: consolidate t...
769
  static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
770
  {
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
771
772
773
774
  	struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
  					   GFP_KERNEL);
  	if (!ts)
  		return -ENOMEM;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
775

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
776
777
778
779
780
781
782
783
784
  	ts->rd = fget(rfd);
  	ts->wr = fget(wfd);
  	if (!ts->rd || !ts->wr) {
  		if (ts->rd)
  			fput(ts->rd);
  		if (ts->wr)
  			fput(ts->wr);
  		kfree(ts);
  		return -EIO;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
785
  	}
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
786
787
  	client->trans = ts;
  	client->status = Connected;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
788

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
789
  	return 0;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
790
  }
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
791

8b81ef589   Eric Van Hensbergen   9p: consolidate t...
792
  static int p9_socket_open(struct p9_client *client, struct socket *csocket)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
793
  {
6b18662e2   Al Viro   9p connect fixes
794
  	struct p9_trans_fd *p;
56b31d1c9   Al Viro   unexport sock_map...
795
796
  	struct file *file;
  	int ret;
6b18662e2   Al Viro   9p connect fixes
797
798
799
800
  
  	p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
  	if (!p)
  		return -ENOMEM;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
801
802
  
  	csocket->sk->sk_allocation = GFP_NOIO;
aab174f0d   Linus Torvalds   Merge branch 'for...
803
  	file = sock_alloc_file(csocket, 0, NULL);
56b31d1c9   Al Viro   unexport sock_map...
804
  	if (IS_ERR(file)) {
5d3851530   Joe Perches   9p: Reduce object...
805
806
807
  		pr_err("%s (%d): failed to map fd
  ",
  		       __func__, task_pid_nr(current));
6b18662e2   Al Viro   9p connect fixes
808
809
  		sock_release(csocket);
  		kfree(p);
56b31d1c9   Al Viro   unexport sock_map...
810
  		return PTR_ERR(file);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
811
  	}
56b31d1c9   Al Viro   unexport sock_map...
812
813
  	get_file(file);
  	p->wr = p->rd = file;
6b18662e2   Al Viro   9p connect fixes
814
815
  	client->trans = p;
  	client->status = Connected;
6b18662e2   Al Viro   9p connect fixes
816
817
818
819
820
821
822
823
  	p->rd->f_flags |= O_NONBLOCK;
  
  	p->conn = p9_conn_create(client);
  	if (IS_ERR(p->conn)) {
  		ret = PTR_ERR(p->conn);
  		p->conn = NULL;
  		kfree(p);
  		sockfd_put(csocket);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
824
825
826
  		sockfd_put(csocket);
  		return ret;
  	}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
827
828
  	return 0;
  }
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
829
  /**
5503ac565   Eric Van Hensbergen   9p: remove unnece...
830
831
   * p9_mux_destroy - cancels all pending requests and frees mux resources
   * @m: mux to destroy
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
832
833
   *
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
834

5503ac565   Eric Van Hensbergen   9p: remove unnece...
835
  static void p9_conn_destroy(struct p9_conn *m)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
836
  {
5d3851530   Joe Perches   9p: Reduce object...
837
838
839
  	p9_debug(P9_DEBUG_TRANS, "mux %p prev %p next %p
  ",
  		 m, m->mux_list.prev, m->mux_list.next);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
840

5503ac565   Eric Van Hensbergen   9p: remove unnece...
841
842
843
  	p9_mux_poll_stop(m);
  	cancel_work_sync(&m->rq);
  	cancel_work_sync(&m->wq);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
844

5503ac565   Eric Van Hensbergen   9p: remove unnece...
845
  	p9_conn_cancel(m, -ECONNRESET);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
846

5503ac565   Eric Van Hensbergen   9p: remove unnece...
847
  	m->client = NULL;
5503ac565   Eric Van Hensbergen   9p: remove unnece...
848
  	kfree(m);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
849
850
851
  }
  
  /**
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
852
853
   * p9_fd_close - shutdown file descriptor transport
   * @client: client instance
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
854
855
   *
   */
ee443996a   Eric Van Hensbergen   9p: Documentation...
856

8b81ef589   Eric Van Hensbergen   9p: consolidate t...
857
  static void p9_fd_close(struct p9_client *client)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
858
859
  {
  	struct p9_trans_fd *ts;
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
860
  	if (!client)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
861
  		return;
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
862
  	ts = client->trans;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
863
864
  	if (!ts)
  		return;
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
865
  	client->status = Disconnected;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
866
  	p9_conn_destroy(ts->conn);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
867
868
869
870
  	if (ts->rd)
  		fput(ts->rd);
  	if (ts->wr)
  		fput(ts->wr);
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
871

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
872
873
  	kfree(ts);
  }
887b3ece6   Eric Van Hensbergen   9p: fix error pat...
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
  /*
   * stolen from NFS - maybe should be made a generic function?
   */
  static inline int valid_ipaddr4(const char *buf)
  {
  	int rc, count, in[4];
  
  	rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
  	if (rc != 4)
  		return -EINVAL;
  	for (count = 0; count < 4; count++) {
  		if (in[count] > 255)
  			return -EINVAL;
  	}
  	return 0;
  }
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
890
891
  static int
  p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
892
893
  {
  	int err;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
894
895
896
  	struct socket *csocket;
  	struct sockaddr_in sin_server;
  	struct p9_fd_opts opts;
bb8ffdfc3   Eric Van Hensbergen   9p: propagate par...
897
898
  	err = parse_opts(args, &opts);
  	if (err < 0)
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
899
  		return err;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
900

887b3ece6   Eric Van Hensbergen   9p: fix error pat...
901
  	if (valid_ipaddr4(addr) < 0)
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
902
  		return -EINVAL;
887b3ece6   Eric Van Hensbergen   9p: fix error pat...
903

a80d923e1   Eric Van Hensbergen   9p: Make transpor...
904
  	csocket = NULL;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
905
906
907
908
  
  	sin_server.sin_family = AF_INET;
  	sin_server.sin_addr.s_addr = in_aton(addr);
  	sin_server.sin_port = htons(opts.port);
e75762fdc   Rob Landley   net/9p: enable 9p...
909
910
  	err = __sock_create(read_pnet(&current->nsproxy->net_ns), PF_INET,
  			    SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
6b18662e2   Al Viro   9p connect fixes
911
  	if (err) {
5d3851530   Joe Perches   9p: Reduce object...
912
913
914
  		pr_err("%s (%d): problem creating socket
  ",
  		       __func__, task_pid_nr(current));
6b18662e2   Al Viro   9p connect fixes
915
  		return err;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
916
917
918
919
920
921
  	}
  
  	err = csocket->ops->connect(csocket,
  				    (struct sockaddr *)&sin_server,
  				    sizeof(struct sockaddr_in), 0);
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
922
923
924
  		pr_err("%s (%d): problem connecting socket to %s
  ",
  		       __func__, task_pid_nr(current), addr);
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
925
  		sock_release(csocket);
6b18662e2   Al Viro   9p connect fixes
926
927
  		return err;
  	}
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
928

6b18662e2   Al Viro   9p connect fixes
929
  	return p9_socket_open(client, csocket);
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
930
  }
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
931
932
  static int
  p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
933
934
935
936
  {
  	int err;
  	struct socket *csocket;
  	struct sockaddr_un sun_server;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
937
938
  
  	csocket = NULL;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
939

cff6b8a9b   Dan Carpenter   9p: strlen() does...
940
  	if (strlen(addr) >= UNIX_PATH_MAX) {
5d3851530   Joe Perches   9p: Reduce object...
941
942
943
  		pr_err("%s (%d): address too long: %s
  ",
  		       __func__, task_pid_nr(current), addr);
6b18662e2   Al Viro   9p connect fixes
944
  		return -ENAMETOOLONG;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
945
946
947
948
  	}
  
  	sun_server.sun_family = PF_UNIX;
  	strcpy(sun_server.sun_path, addr);
e75762fdc   Rob Landley   net/9p: enable 9p...
949
950
  	err = __sock_create(read_pnet(&current->nsproxy->net_ns), PF_UNIX,
  			    SOCK_STREAM, 0, &csocket, 1);
6b18662e2   Al Viro   9p connect fixes
951
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
952
953
954
  		pr_err("%s (%d): problem creating socket
  ",
  		       __func__, task_pid_nr(current));
6b18662e2   Al Viro   9p connect fixes
955
956
  		return err;
  	}
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
957
958
959
  	err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
  			sizeof(struct sockaddr_un) - 1, 0);
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
960
961
962
  		pr_err("%s (%d): problem connecting socket: %s: %d
  ",
  		       __func__, task_pid_nr(current), addr, err);
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
963
  		sock_release(csocket);
6b18662e2   Al Viro   9p connect fixes
964
965
  		return err;
  	}
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
966

6b18662e2   Al Viro   9p connect fixes
967
  	return p9_socket_open(client, csocket);
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
968
  }
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
969
970
  static int
  p9_fd_create(struct p9_client *client, const char *addr, char *args)
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
971
972
  {
  	int err;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
973
  	struct p9_fd_opts opts;
6b18662e2   Al Viro   9p connect fixes
974
  	struct p9_trans_fd *p;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
975
976
977
978
  
  	parse_opts(args, &opts);
  
  	if (opts.rfd == ~0 || opts.wfd == ~0) {
5d3851530   Joe Perches   9p: Reduce object...
979
980
  		pr_err("Insufficient options for proto=fd
  ");
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
981
  		return -ENOPROTOOPT;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
982
  	}
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
983
  	err = p9_fd_open(client, opts.rfd, opts.wfd);
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
984
  	if (err < 0)
6b18662e2   Al Viro   9p connect fixes
985
  		return err;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
986

8b81ef589   Eric Van Hensbergen   9p: consolidate t...
987
988
  	p = (struct p9_trans_fd *) client->trans;
  	p->conn = p9_conn_create(client);
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
989
990
991
  	if (IS_ERR(p->conn)) {
  		err = PTR_ERR(p->conn);
  		p->conn = NULL;
6b18662e2   Al Viro   9p connect fixes
992
993
994
  		fput(p->rd);
  		fput(p->wr);
  		return err;
8a0dc95fd   Eric Van Hensbergen   9p: transport API...
995
  	}
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
996
  	return 0;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
997
998
999
1000
1001
1002
  }
  
  static struct p9_trans_module p9_tcp_trans = {
  	.name = "tcp",
  	.maxsize = MAX_SOCK_BUF,
  	.def = 1,
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
1003
1004
  	.create = p9_fd_create_tcp,
  	.close = p9_fd_close,
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
1005
1006
  	.request = p9_fd_request,
  	.cancel = p9_fd_cancel,
72029fe85   Tejun Heo   9p: implement pro...
1007
  	.owner = THIS_MODULE,
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
1008
1009
1010
1011
1012
1013
  };
  
  static struct p9_trans_module p9_unix_trans = {
  	.name = "unix",
  	.maxsize = MAX_SOCK_BUF,
  	.def = 0,
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
1014
1015
  	.create = p9_fd_create_unix,
  	.close = p9_fd_close,
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
1016
1017
  	.request = p9_fd_request,
  	.cancel = p9_fd_cancel,
72029fe85   Tejun Heo   9p: implement pro...
1018
  	.owner = THIS_MODULE,
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
1019
1020
1021
1022
1023
1024
  };
  
  static struct p9_trans_module p9_fd_trans = {
  	.name = "fd",
  	.maxsize = MAX_SOCK_BUF,
  	.def = 0,
8b81ef589   Eric Van Hensbergen   9p: consolidate t...
1025
1026
  	.create = p9_fd_create,
  	.close = p9_fd_close,
91b8534fa   Eric Van Hensbergen   9p: make rpc code...
1027
1028
  	.request = p9_fd_request,
  	.cancel = p9_fd_cancel,
72029fe85   Tejun Heo   9p: implement pro...
1029
  	.owner = THIS_MODULE,
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
1030
  };
5503ac565   Eric Van Hensbergen   9p: remove unnece...
1031
1032
1033
1034
1035
1036
1037
1038
  /**
   * p9_poll_proc - poll worker thread
   * @a: thread state and arguments
   *
   * polls all v9fs transports for new events and queues the appropriate
   * work to the work queue
   *
   */
aa70c585b   Tejun Heo   net/9p: replace p...
1039
  static void p9_poll_workfn(struct work_struct *work)
5503ac565   Eric Van Hensbergen   9p: remove unnece...
1040
1041
  {
  	unsigned long flags;
5d3851530   Joe Perches   9p: Reduce object...
1042
1043
  	p9_debug(P9_DEBUG_TRANS, "start %p
  ", current);
aa70c585b   Tejun Heo   net/9p: replace p...
1044

5503ac565   Eric Van Hensbergen   9p: remove unnece...
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
  	spin_lock_irqsave(&p9_poll_lock, flags);
  	while (!list_empty(&p9_poll_pending_list)) {
  		struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
  							struct p9_conn,
  							poll_pending_link);
  		list_del_init(&conn->poll_pending_link);
  		spin_unlock_irqrestore(&p9_poll_lock, flags);
  
  		p9_poll_mux(conn);
  
  		spin_lock_irqsave(&p9_poll_lock, flags);
  	}
  	spin_unlock_irqrestore(&p9_poll_lock, flags);
5d3851530   Joe Perches   9p: Reduce object...
1058
1059
  	p9_debug(P9_DEBUG_TRANS, "finish
  ");
5503ac565   Eric Van Hensbergen   9p: remove unnece...
1060
  }
887b3ece6   Eric Van Hensbergen   9p: fix error pat...
1061
  int p9_trans_fd_init(void)
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
1062
1063
1064
1065
  {
  	v9fs_register_trans(&p9_tcp_trans);
  	v9fs_register_trans(&p9_unix_trans);
  	v9fs_register_trans(&p9_fd_trans);
3387b804d   Andrew Morton   net/9p/trans_fd.c...
1066
  	return 0;
a80d923e1   Eric Van Hensbergen   9p: Make transpor...
1067
  }
72029fe85   Tejun Heo   9p: implement pro...
1068
1069
1070
  
  void p9_trans_fd_exit(void)
  {
43829731d   Tejun Heo   workqueue: deprec...
1071
  	flush_work(&p9_poll_work);
72029fe85   Tejun Heo   9p: implement pro...
1072
1073
1074
1075
  	v9fs_unregister_trans(&p9_tcp_trans);
  	v9fs_unregister_trans(&p9_unix_trans);
  	v9fs_unregister_trans(&p9_fd_trans);
  }