aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/acl.c2
-rw-r--r--fs/9p/v9fs.c21
-rw-r--r--fs/9p/v9fs.h1
-rw-r--r--fs/9p/vfs_dir.c19
-rw-r--r--fs/9p/vfs_file.c24
-rw-r--r--include/net/9p/9p.h12
-rw-r--r--include/net/9p/client.h71
-rw-r--r--net/9p/Makefile1
-rw-r--r--net/9p/client.c551
-rw-r--r--net/9p/mod.c9
-rw-r--r--net/9p/protocol.c20
-rw-r--r--net/9p/trans_fd.c64
-rw-r--r--net/9p/trans_rdma.c37
-rw-r--r--net/9p/trans_virtio.c44
-rw-r--r--net/9p/trans_xen.c17
-rw-r--r--net/9p/util.c140
16 files changed, 482 insertions, 551 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 082d227fa56b..6261719f6f2a 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -276,7 +276,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
276 switch (handler->flags) { 276 switch (handler->flags) {
277 case ACL_TYPE_ACCESS: 277 case ACL_TYPE_ACCESS:
278 if (acl) { 278 if (acl) {
279 struct iattr iattr; 279 struct iattr iattr = { 0 };
280 struct posix_acl *old_acl = acl; 280 struct posix_acl *old_acl = acl;
281 281
282 retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); 282 retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 89bac3d2f05b..619128b55837 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -61,6 +61,8 @@ enum {
61 Opt_cache_loose, Opt_fscache, Opt_mmap, 61 Opt_cache_loose, Opt_fscache, Opt_mmap,
62 /* Access options */ 62 /* Access options */
63 Opt_access, Opt_posixacl, 63 Opt_access, Opt_posixacl,
64 /* Lock timeout option */
65 Opt_locktimeout,
64 /* Error token */ 66 /* Error token */
65 Opt_err 67 Opt_err
66}; 68};
@@ -80,6 +82,7 @@ static const match_table_t tokens = {
80 {Opt_cachetag, "cachetag=%s"}, 82 {Opt_cachetag, "cachetag=%s"},
81 {Opt_access, "access=%s"}, 83 {Opt_access, "access=%s"},
82 {Opt_posixacl, "posixacl"}, 84 {Opt_posixacl, "posixacl"},
85 {Opt_locktimeout, "locktimeout=%u"},
83 {Opt_err, NULL} 86 {Opt_err, NULL}
84}; 87};
85 88
@@ -187,6 +190,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
187#ifdef CONFIG_9P_FSCACHE 190#ifdef CONFIG_9P_FSCACHE
188 v9ses->cachetag = NULL; 191 v9ses->cachetag = NULL;
189#endif 192#endif
193 v9ses->session_lock_timeout = P9_LOCK_TIMEOUT;
190 194
191 if (!opts) 195 if (!opts)
192 return 0; 196 return 0;
@@ -359,6 +363,23 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
359#endif 363#endif
360 break; 364 break;
361 365
366 case Opt_locktimeout:
367 r = match_int(&args[0], &option);
368 if (r < 0) {
369 p9_debug(P9_DEBUG_ERROR,
370 "integer field, but no integer?\n");
371 ret = r;
372 continue;
373 }
374 if (option < 1) {
375 p9_debug(P9_DEBUG_ERROR,
376 "locktimeout must be a greater than zero integer.\n");
377 ret = -EINVAL;
378 continue;
379 }
380 v9ses->session_lock_timeout = (long)option * HZ;
381 break;
382
362 default: 383 default:
363 continue; 384 continue;
364 } 385 }
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 982e017acadb..129e5243a6bf 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -116,6 +116,7 @@ struct v9fs_session_info {
116 struct p9_client *clnt; /* 9p client */ 116 struct p9_client *clnt; /* 9p client */
117 struct list_head slist; /* list of sessions registered with v9fs */ 117 struct list_head slist; /* list of sessions registered with v9fs */
118 struct rw_semaphore rename_sem; 118 struct rw_semaphore rename_sem;
119 long session_lock_timeout; /* retry interval for blocking locks */
119}; 120};
120 121
121/* cache_validity flags */ 122/* cache_validity flags */
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index b0405d6aac85..cb6c4031af55 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -76,15 +76,6 @@ static inline int dt_type(struct p9_wstat *mistat)
76 return rettype; 76 return rettype;
77} 77}
78 78
79static void p9stat_init(struct p9_wstat *stbuf)
80{
81 stbuf->name = NULL;
82 stbuf->uid = NULL;
83 stbuf->gid = NULL;
84 stbuf->muid = NULL;
85 stbuf->extension = NULL;
86}
87
88/** 79/**
89 * v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir 80 * v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
90 * @filp: opened file structure 81 * @filp: opened file structure
@@ -114,7 +105,6 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
114 int err = 0; 105 int err = 0;
115 struct p9_fid *fid; 106 struct p9_fid *fid;
116 int buflen; 107 int buflen;
117 int reclen = 0;
118 struct p9_rdir *rdir; 108 struct p9_rdir *rdir;
119 struct kvec kvec; 109 struct kvec kvec;
120 110
@@ -145,15 +135,12 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
145 rdir->tail = n; 135 rdir->tail = n;
146 } 136 }
147 while (rdir->head < rdir->tail) { 137 while (rdir->head < rdir->tail) {
148 p9stat_init(&st);
149 err = p9stat_read(fid->clnt, rdir->buf + rdir->head, 138 err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
150 rdir->tail - rdir->head, &st); 139 rdir->tail - rdir->head, &st);
151 if (err) { 140 if (err <= 0) {
152 p9_debug(P9_DEBUG_VFS, "returned %d\n", err); 141 p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
153 p9stat_free(&st);
154 return -EIO; 142 return -EIO;
155 } 143 }
156 reclen = st.size+2;
157 144
158 over = !dir_emit(ctx, st.name, strlen(st.name), 145 over = !dir_emit(ctx, st.name, strlen(st.name),
159 v9fs_qid2ino(&st.qid), dt_type(&st)); 146 v9fs_qid2ino(&st.qid), dt_type(&st));
@@ -161,8 +148,8 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
161 if (over) 148 if (over)
162 return 0; 149 return 0;
163 150
164 rdir->head += reclen; 151 rdir->head += err;
165 ctx->pos += reclen; 152 ctx->pos += err;
166 } 153 }
167 } 154 }
168} 155}
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 5f2e48d41d72..a25efa782fcc 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -154,6 +154,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
154 uint8_t status = P9_LOCK_ERROR; 154 uint8_t status = P9_LOCK_ERROR;
155 int res = 0; 155 int res = 0;
156 unsigned char fl_type; 156 unsigned char fl_type;
157 struct v9fs_session_info *v9ses;
157 158
158 fid = filp->private_data; 159 fid = filp->private_data;
159 BUG_ON(fid == NULL); 160 BUG_ON(fid == NULL);
@@ -189,6 +190,8 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
189 if (IS_SETLKW(cmd)) 190 if (IS_SETLKW(cmd))
190 flock.flags = P9_LOCK_FLAGS_BLOCK; 191 flock.flags = P9_LOCK_FLAGS_BLOCK;
191 192
193 v9ses = v9fs_inode2v9ses(file_inode(filp));
194
192 /* 195 /*
193 * if its a blocked request and we get P9_LOCK_BLOCKED as the status 196 * if its a blocked request and we get P9_LOCK_BLOCKED as the status
194 * for lock request, keep on trying 197 * for lock request, keep on trying
@@ -202,8 +205,17 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
202 break; 205 break;
203 if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) 206 if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
204 break; 207 break;
205 if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0) 208 if (schedule_timeout_interruptible(v9ses->session_lock_timeout)
209 != 0)
206 break; 210 break;
211 /*
212 * p9_client_lock_dotl overwrites flock.client_id with the
213 * server message, free and reuse the client name
214 */
215 if (flock.client_id != fid->clnt->name) {
216 kfree(flock.client_id);
217 flock.client_id = fid->clnt->name;
218 }
207 } 219 }
208 220
209 /* map 9p status to VFS status */ 221 /* map 9p status to VFS status */
@@ -216,7 +228,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
216 break; 228 break;
217 default: 229 default:
218 WARN_ONCE(1, "unknown lock status code: %d\n", status); 230 WARN_ONCE(1, "unknown lock status code: %d\n", status);
219 /* fallthough */ 231 /* fall through */
220 case P9_LOCK_ERROR: 232 case P9_LOCK_ERROR:
221 case P9_LOCK_GRACE: 233 case P9_LOCK_GRACE:
222 res = -ENOLCK; 234 res = -ENOLCK;
@@ -235,6 +247,8 @@ out_unlock:
235 locks_lock_file_wait(filp, fl); 247 locks_lock_file_wait(filp, fl);
236 fl->fl_type = fl_type; 248 fl->fl_type = fl_type;
237 } 249 }
250 if (flock.client_id != fid->clnt->name)
251 kfree(flock.client_id);
238out: 252out:
239 return res; 253 return res;
240} 254}
@@ -269,7 +283,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
269 283
270 res = p9_client_getlock_dotl(fid, &glock); 284 res = p9_client_getlock_dotl(fid, &glock);
271 if (res < 0) 285 if (res < 0)
272 return res; 286 goto out;
273 /* map 9p lock type to os lock type */ 287 /* map 9p lock type to os lock type */
274 switch (glock.type) { 288 switch (glock.type) {
275 case P9_LOCK_TYPE_RDLCK: 289 case P9_LOCK_TYPE_RDLCK:
@@ -290,7 +304,9 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
290 fl->fl_end = glock.start + glock.length - 1; 304 fl->fl_end = glock.start + glock.length - 1;
291 fl->fl_pid = -glock.proc_id; 305 fl->fl_pid = -glock.proc_id;
292 } 306 }
293 kfree(glock.client_id); 307out:
308 if (glock.client_id != fid->clnt->name)
309 kfree(glock.client_id);
294 return res; 310 return res;
295} 311}
296 312
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index b8eb51a661e5..beede1e1a919 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -336,6 +336,9 @@ enum p9_qid_t {
336#define P9_NOFID (u32)(~0) 336#define P9_NOFID (u32)(~0)
337#define P9_MAXWELEM 16 337#define P9_MAXWELEM 16
338 338
339/* Minimal header size: size[4] type[1] tag[2] */
340#define P9_HDRSZ 7
341
339/* ample room for Twrite/Rread header */ 342/* ample room for Twrite/Rread header */
340#define P9_IOHDRSZ 24 343#define P9_IOHDRSZ 24
341 344
@@ -558,19 +561,12 @@ struct p9_fcall {
558 size_t offset; 561 size_t offset;
559 size_t capacity; 562 size_t capacity;
560 563
564 struct kmem_cache *cache;
561 u8 *sdata; 565 u8 *sdata;
562}; 566};
563 567
564struct p9_idpool;
565
566int p9_errstr2errno(char *errstr, int len); 568int p9_errstr2errno(char *errstr, int len);
567 569
568struct p9_idpool *p9_idpool_create(void);
569void p9_idpool_destroy(struct p9_idpool *);
570int p9_idpool_get(struct p9_idpool *p);
571void p9_idpool_put(int id, struct p9_idpool *p);
572int p9_idpool_check(int id, struct p9_idpool *p);
573
574int p9_error_init(void); 570int p9_error_init(void);
575int p9_trans_fd_init(void); 571int p9_trans_fd_init(void);
576void p9_trans_fd_exit(void); 572void p9_trans_fd_exit(void);
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 0fa0fbab33b0..947a570307a6 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -64,22 +64,15 @@ enum p9_trans_status {
64 64
65/** 65/**
66 * enum p9_req_status_t - status of a request 66 * enum p9_req_status_t - status of a request
67 * @REQ_STATUS_IDLE: request slot unused
68 * @REQ_STATUS_ALLOC: request has been allocated but not sent 67 * @REQ_STATUS_ALLOC: request has been allocated but not sent
69 * @REQ_STATUS_UNSENT: request waiting to be sent 68 * @REQ_STATUS_UNSENT: request waiting to be sent
70 * @REQ_STATUS_SENT: request sent to server 69 * @REQ_STATUS_SENT: request sent to server
71 * @REQ_STATUS_RCVD: response received from server 70 * @REQ_STATUS_RCVD: response received from server
72 * @REQ_STATUS_FLSHD: request has been flushed 71 * @REQ_STATUS_FLSHD: request has been flushed
73 * @REQ_STATUS_ERROR: request encountered an error on the client side 72 * @REQ_STATUS_ERROR: request encountered an error on the client side
74 *
75 * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
76 * but use is actually tracked by the idpool structure which handles tag
77 * id allocation.
78 *
79 */ 73 */
80 74
81enum p9_req_status_t { 75enum p9_req_status_t {
82 REQ_STATUS_IDLE,
83 REQ_STATUS_ALLOC, 76 REQ_STATUS_ALLOC,
84 REQ_STATUS_UNSENT, 77 REQ_STATUS_UNSENT,
85 REQ_STATUS_SENT, 78 REQ_STATUS_SENT,
@@ -92,70 +85,46 @@ enum p9_req_status_t {
92 * struct p9_req_t - request slots 85 * struct p9_req_t - request slots
93 * @status: status of this request slot 86 * @status: status of this request slot
94 * @t_err: transport error 87 * @t_err: transport error
95 * @flush_tag: tag of request being flushed (for flush requests)
96 * @wq: wait_queue for the client to block on for this request 88 * @wq: wait_queue for the client to block on for this request
97 * @tc: the request fcall structure 89 * @tc: the request fcall structure
98 * @rc: the response fcall structure 90 * @rc: the response fcall structure
99 * @aux: transport specific data (provided for trans_fd migration) 91 * @aux: transport specific data (provided for trans_fd migration)
100 * @req_list: link for higher level objects to chain requests 92 * @req_list: link for higher level objects to chain requests
101 *
102 * Transport use an array to track outstanding requests
103 * instead of a list. While this may incurr overhead during initial
104 * allocation or expansion, it makes request lookup much easier as the
105 * tag id is a index into an array. (We use tag+1 so that we can accommodate
106 * the -1 tag for the T_VERSION request).
107 * This also has the nice effect of only having to allocate wait_queues
108 * once, instead of constantly allocating and freeing them. Its possible
109 * other resources could benefit from this scheme as well.
110 *
111 */ 93 */
112
113struct p9_req_t { 94struct p9_req_t {
114 int status; 95 int status;
115 int t_err; 96 int t_err;
97 struct kref refcount;
116 wait_queue_head_t wq; 98 wait_queue_head_t wq;
117 struct p9_fcall *tc; 99 struct p9_fcall tc;
118 struct p9_fcall *rc; 100 struct p9_fcall rc;
119 void *aux; 101 void *aux;
120
121 struct list_head req_list; 102 struct list_head req_list;
122}; 103};
123 104
124/** 105/**
125 * struct p9_client - per client instance state 106 * struct p9_client - per client instance state
126 * @lock: protect @fidlist 107 * @lock: protect @fids and @reqs
127 * @msize: maximum data size negotiated by protocol 108 * @msize: maximum data size negotiated by protocol
128 * @dotu: extension flags negotiated by protocol
129 * @proto_version: 9P protocol version to use 109 * @proto_version: 9P protocol version to use
130 * @trans_mod: module API instantiated with this client 110 * @trans_mod: module API instantiated with this client
111 * @status: connection state
131 * @trans: tranport instance state and API 112 * @trans: tranport instance state and API
132 * @fids: All active FID handles 113 * @fids: All active FID handles
133 * @tagpool - transaction id accounting for session 114 * @reqs: All active requests.
134 * @reqs - 2D array of requests 115 * @name: node name used as client id
135 * @max_tag - current maximum tag id allocated
136 * @name - node name used as client id
137 * 116 *
138 * The client structure is used to keep track of various per-client 117 * The client structure is used to keep track of various per-client
139 * state that has been instantiated. 118 * state that has been instantiated.
140 * In order to minimize per-transaction overhead we use a
141 * simple array to lookup requests instead of a hash table
142 * or linked list. In order to support larger number of
143 * transactions, we make this a 2D array, allocating new rows
144 * when we need to grow the total number of the transactions.
145 *
146 * Each row is 256 requests and we'll support up to 256 rows for
147 * a total of 64k concurrent requests per session.
148 *
149 * Bugs: duplicated data and potentially unnecessary elements.
150 */ 119 */
151
152struct p9_client { 120struct p9_client {
153 spinlock_t lock; /* protect client structure */ 121 spinlock_t lock;
154 unsigned int msize; 122 unsigned int msize;
155 unsigned char proto_version; 123 unsigned char proto_version;
156 struct p9_trans_module *trans_mod; 124 struct p9_trans_module *trans_mod;
157 enum p9_trans_status status; 125 enum p9_trans_status status;
158 void *trans; 126 void *trans;
127 struct kmem_cache *fcall_cache;
159 128
160 union { 129 union {
161 struct { 130 struct {
@@ -170,10 +139,7 @@ struct p9_client {
170 } trans_opts; 139 } trans_opts;
171 140
172 struct idr fids; 141 struct idr fids;
173 142 struct idr reqs;
174 struct p9_idpool *tagpool;
175 struct p9_req_t *reqs[P9_ROW_MAXTAG];
176 int max_tag;
177 143
178 char name[__NEW_UTS_LEN + 1]; 144 char name[__NEW_UTS_LEN + 1];
179}; 145};
@@ -266,7 +232,21 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
266 kgid_t gid, struct p9_qid *); 232 kgid_t gid, struct p9_qid *);
267int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); 233int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
268int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); 234int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
235void p9_fcall_fini(struct p9_fcall *fc);
269struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); 236struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
237
238static inline void p9_req_get(struct p9_req_t *r)
239{
240 kref_get(&r->refcount);
241}
242
243static inline int p9_req_try_get(struct p9_req_t *r)
244{
245 return kref_get_unless_zero(&r->refcount);
246}
247
248int p9_req_put(struct p9_req_t *r);
249
270void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); 250void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
271 251
272int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); 252int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
@@ -279,4 +259,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *);
279int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int); 259int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int);
280int p9_client_readlink(struct p9_fid *fid, char **target); 260int p9_client_readlink(struct p9_fid *fid, char **target);
281 261
262int p9_client_init(void);
263void p9_client_exit(void);
264
282#endif /* NET_9P_CLIENT_H */ 265#endif /* NET_9P_CLIENT_H */
diff --git a/net/9p/Makefile b/net/9p/Makefile
index c0486cfc85d9..aa0a5641e5d0 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o
8 mod.o \ 8 mod.o \
9 client.o \ 9 client.o \
10 error.o \ 10 error.o \
11 util.o \
12 protocol.o \ 11 protocol.o \
13 trans_fd.o \ 12 trans_fd.o \
14 trans_common.o \ 13 trans_common.o \
diff --git a/net/9p/client.c b/net/9p/client.c
index deae53a7dffc..5f23e18eecc0 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -231,144 +231,170 @@ free_and_return:
231 return ret; 231 return ret;
232} 232}
233 233
234static struct p9_fcall *p9_fcall_alloc(int alloc_msize) 234static int p9_fcall_init(struct p9_client *c, struct p9_fcall *fc,
235 int alloc_msize)
235{ 236{
236 struct p9_fcall *fc; 237 if (likely(c->fcall_cache) && alloc_msize == c->msize) {
237 fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS); 238 fc->sdata = kmem_cache_alloc(c->fcall_cache, GFP_NOFS);
238 if (!fc) 239 fc->cache = c->fcall_cache;
239 return NULL; 240 } else {
241 fc->sdata = kmalloc(alloc_msize, GFP_NOFS);
242 fc->cache = NULL;
243 }
244 if (!fc->sdata)
245 return -ENOMEM;
240 fc->capacity = alloc_msize; 246 fc->capacity = alloc_msize;
241 fc->sdata = (char *) fc + sizeof(struct p9_fcall); 247 return 0;
242 return fc; 248}
249
250void p9_fcall_fini(struct p9_fcall *fc)
251{
252 /* sdata can be NULL for interrupted requests in trans_rdma,
253 * and kmem_cache_free does not do NULL-check for us
254 */
255 if (unlikely(!fc->sdata))
256 return;
257
258 if (fc->cache)
259 kmem_cache_free(fc->cache, fc->sdata);
260 else
261 kfree(fc->sdata);
243} 262}
263EXPORT_SYMBOL(p9_fcall_fini);
264
265static struct kmem_cache *p9_req_cache;
244 266
245/** 267/**
246 * p9_tag_alloc - lookup/allocate a request by tag 268 * p9_req_alloc - Allocate a new request.
247 * @c: client session to lookup tag within 269 * @c: Client session.
248 * @tag: numeric id for transaction 270 * @type: Transaction type.
249 * 271 * @max_size: Maximum packet size for this request.
250 * this is a simple array lookup, but will grow the
251 * request_slots as necessary to accommodate transaction
252 * ids which did not previously have a slot.
253 *
254 * this code relies on the client spinlock to manage locks, its
255 * possible we should switch to something else, but I'd rather
256 * stick with something low-overhead for the common case.
257 * 272 *
273 * Context: Process context.
274 * Return: Pointer to new request.
258 */ 275 */
259
260static struct p9_req_t * 276static struct p9_req_t *
261p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size) 277p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
262{ 278{
263 unsigned long flags; 279 struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS);
264 int row, col;
265 struct p9_req_t *req;
266 int alloc_msize = min(c->msize, max_size); 280 int alloc_msize = min(c->msize, max_size);
281 int tag;
267 282
268 /* This looks up the original request by tag so we know which 283 if (!req)
269 * buffer to read the data into */ 284 return ERR_PTR(-ENOMEM);
270 tag++;
271
272 if (tag >= c->max_tag) {
273 spin_lock_irqsave(&c->lock, flags);
274 /* check again since original check was outside of lock */
275 while (tag >= c->max_tag) {
276 row = (tag / P9_ROW_MAXTAG);
277 c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
278 sizeof(struct p9_req_t), GFP_ATOMIC);
279
280 if (!c->reqs[row]) {
281 pr_err("Couldn't grow tag array\n");
282 spin_unlock_irqrestore(&c->lock, flags);
283 return ERR_PTR(-ENOMEM);
284 }
285 for (col = 0; col < P9_ROW_MAXTAG; col++) {
286 req = &c->reqs[row][col];
287 req->status = REQ_STATUS_IDLE;
288 init_waitqueue_head(&req->wq);
289 }
290 c->max_tag += P9_ROW_MAXTAG;
291 }
292 spin_unlock_irqrestore(&c->lock, flags);
293 }
294 row = tag / P9_ROW_MAXTAG;
295 col = tag % P9_ROW_MAXTAG;
296
297 req = &c->reqs[row][col];
298 if (!req->tc)
299 req->tc = p9_fcall_alloc(alloc_msize);
300 if (!req->rc)
301 req->rc = p9_fcall_alloc(alloc_msize);
302 if (!req->tc || !req->rc)
303 goto grow_failed;
304 285
305 p9pdu_reset(req->tc); 286 if (p9_fcall_init(c, &req->tc, alloc_msize))
306 p9pdu_reset(req->rc); 287 goto free_req;
288 if (p9_fcall_init(c, &req->rc, alloc_msize))
289 goto free;
307 290
308 req->tc->tag = tag-1; 291 p9pdu_reset(&req->tc);
292 p9pdu_reset(&req->rc);
309 req->status = REQ_STATUS_ALLOC; 293 req->status = REQ_STATUS_ALLOC;
294 init_waitqueue_head(&req->wq);
295 INIT_LIST_HEAD(&req->req_list);
296
297 idr_preload(GFP_NOFS);
298 spin_lock_irq(&c->lock);
299 if (type == P9_TVERSION)
300 tag = idr_alloc(&c->reqs, req, P9_NOTAG, P9_NOTAG + 1,
301 GFP_NOWAIT);
302 else
303 tag = idr_alloc(&c->reqs, req, 0, P9_NOTAG, GFP_NOWAIT);
304 req->tc.tag = tag;
305 spin_unlock_irq(&c->lock);
306 idr_preload_end();
307 if (tag < 0)
308 goto free;
309
310 /* Init ref to two because in the general case there is one ref
311 * that is put asynchronously by a writer thread, one ref
312 * temporarily given by p9_tag_lookup and put by p9_client_cb
313 * in the recv thread, and one ref put by p9_tag_remove in the
314 * main thread. The only exception is virtio that does not use
315 * p9_tag_lookup but does not have a writer thread either
316 * (the write happens synchronously in the request/zc_request
317 * callback), so p9_client_cb eats the second ref there
318 * as the pointer is duplicated directly by virtqueue_add_sgs()
319 */
320 refcount_set(&req->refcount.refcount, 2);
310 321
311 return req; 322 return req;
312 323
313grow_failed: 324free:
314 pr_err("Couldn't grow tag array\n"); 325 p9_fcall_fini(&req->tc);
315 kfree(req->tc); 326 p9_fcall_fini(&req->rc);
316 kfree(req->rc); 327free_req:
317 req->tc = req->rc = NULL; 328 kmem_cache_free(p9_req_cache, req);
318 return ERR_PTR(-ENOMEM); 329 return ERR_PTR(-ENOMEM);
319} 330}
320 331
321/** 332/**
322 * p9_tag_lookup - lookup a request by tag 333 * p9_tag_lookup - Look up a request by tag.
323 * @c: client session to lookup tag within 334 * @c: Client session.
324 * @tag: numeric id for transaction 335 * @tag: Transaction ID.
325 * 336 *
337 * Context: Any context.
338 * Return: A request, or %NULL if there is no request with that tag.
326 */ 339 */
327
328struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag) 340struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
329{ 341{
330 int row, col; 342 struct p9_req_t *req;
331
332 /* This looks up the original request by tag so we know which
333 * buffer to read the data into */
334 tag++;
335
336 if (tag >= c->max_tag)
337 return NULL;
338 343
339 row = tag / P9_ROW_MAXTAG; 344 rcu_read_lock();
340 col = tag % P9_ROW_MAXTAG; 345again:
346 req = idr_find(&c->reqs, tag);
347 if (req) {
348 /* We have to be careful with the req found under rcu_read_lock
349 * Thanks to SLAB_TYPESAFE_BY_RCU we can safely try to get the
350 * ref again without corrupting other data, then check again
351 * that the tag matches once we have the ref
352 */
353 if (!p9_req_try_get(req))
354 goto again;
355 if (req->tc.tag != tag) {
356 p9_req_put(req);
357 goto again;
358 }
359 }
360 rcu_read_unlock();
341 361
342 return &c->reqs[row][col]; 362 return req;
343} 363}
344EXPORT_SYMBOL(p9_tag_lookup); 364EXPORT_SYMBOL(p9_tag_lookup);
345 365
346/** 366/**
347 * p9_tag_init - setup tags structure and contents 367 * p9_tag_remove - Remove a tag.
348 * @c: v9fs client struct 368 * @c: Client session.
349 * 369 * @r: Request of reference.
350 * This initializes the tags structure for each client instance.
351 * 370 *
371 * Context: Any context.
352 */ 372 */
373static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
374{
375 unsigned long flags;
376 u16 tag = r->tc.tag;
377
378 p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
379 spin_lock_irqsave(&c->lock, flags);
380 idr_remove(&c->reqs, tag);
381 spin_unlock_irqrestore(&c->lock, flags);
382 return p9_req_put(r);
383}
353 384
354static int p9_tag_init(struct p9_client *c) 385static void p9_req_free(struct kref *ref)
355{ 386{
356 int err = 0; 387 struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
388 p9_fcall_fini(&r->tc);
389 p9_fcall_fini(&r->rc);
390 kmem_cache_free(p9_req_cache, r);
391}
357 392
358 c->tagpool = p9_idpool_create(); 393int p9_req_put(struct p9_req_t *r)
359 if (IS_ERR(c->tagpool)) { 394{
360 err = PTR_ERR(c->tagpool); 395 return kref_put(&r->refcount, p9_req_free);
361 goto error;
362 }
363 err = p9_idpool_get(c->tagpool); /* reserve tag 0 */
364 if (err < 0) {
365 p9_idpool_destroy(c->tagpool);
366 goto error;
367 }
368 c->max_tag = 0;
369error:
370 return err;
371} 396}
397EXPORT_SYMBOL(p9_req_put);
372 398
373/** 399/**
374 * p9_tag_cleanup - cleans up tags structure and reclaims resources 400 * p9_tag_cleanup - cleans up tags structure and reclaims resources
@@ -379,52 +405,17 @@ error:
379 */ 405 */
380static void p9_tag_cleanup(struct p9_client *c) 406static void p9_tag_cleanup(struct p9_client *c)
381{ 407{
382 int row, col; 408 struct p9_req_t *req;
383 409 int id;
384 /* check to insure all requests are idle */
385 for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
386 for (col = 0; col < P9_ROW_MAXTAG; col++) {
387 if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
388 p9_debug(P9_DEBUG_MUX,
389 "Attempting to cleanup non-free tag %d,%d\n",
390 row, col);
391 /* TODO: delay execution of cleanup */
392 return;
393 }
394 }
395 }
396
397 if (c->tagpool) {
398 p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
399 p9_idpool_destroy(c->tagpool);
400 }
401 410
402 /* free requests associated with tags */ 411 rcu_read_lock();
403 for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { 412 idr_for_each_entry(&c->reqs, req, id) {
404 for (col = 0; col < P9_ROW_MAXTAG; col++) { 413 pr_info("Tag %d still in use\n", id);
405 kfree(c->reqs[row][col].tc); 414 if (p9_tag_remove(c, req) == 0)
406 kfree(c->reqs[row][col].rc); 415 pr_warn("Packet with tag %d has still references",
407 } 416 req->tc.tag);
408 kfree(c->reqs[row]);
409 } 417 }
410 c->max_tag = 0; 418 rcu_read_unlock();
411}
412
413/**
414 * p9_free_req - free a request and clean-up as necessary
415 * c: client state
416 * r: request to release
417 *
418 */
419
420static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
421{
422 int tag = r->tc->tag;
423 p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
424
425 r->status = REQ_STATUS_IDLE;
426 if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
427 p9_idpool_put(tag, c->tagpool);
428} 419}
429 420
430/** 421/**
@@ -435,7 +426,7 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
435 */ 426 */
436void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status) 427void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
437{ 428{
438 p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); 429 p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag);
439 430
440 /* 431 /*
441 * This barrier is needed to make sure any change made to req before 432 * This barrier is needed to make sure any change made to req before
@@ -445,7 +436,8 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
445 req->status = status; 436 req->status = status;
446 437
447 wake_up(&req->wq); 438 wake_up(&req->wq);
448 p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); 439 p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
440 p9_req_put(req);
449} 441}
450EXPORT_SYMBOL(p9_client_cb); 442EXPORT_SYMBOL(p9_client_cb);
451 443
@@ -516,18 +508,18 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
516 int err; 508 int err;
517 int ecode; 509 int ecode;
518 510
519 err = p9_parse_header(req->rc, NULL, &type, NULL, 0); 511 err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
520 if (req->rc->size >= c->msize) { 512 if (req->rc.size >= c->msize) {
521 p9_debug(P9_DEBUG_ERROR, 513 p9_debug(P9_DEBUG_ERROR,
522 "requested packet size too big: %d\n", 514 "requested packet size too big: %d\n",
523 req->rc->size); 515 req->rc.size);
524 return -EIO; 516 return -EIO;
525 } 517 }
526 /* 518 /*
527 * dump the response from server 519 * dump the response from server
528 * This should be after check errors which poplulate pdu_fcall. 520 * This should be after check errors which poplulate pdu_fcall.
529 */ 521 */
530 trace_9p_protocol_dump(c, req->rc); 522 trace_9p_protocol_dump(c, &req->rc);
531 if (err) { 523 if (err) {
532 p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err); 524 p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
533 return err; 525 return err;
@@ -537,7 +529,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
537 529
538 if (!p9_is_proto_dotl(c)) { 530 if (!p9_is_proto_dotl(c)) {
539 char *ename; 531 char *ename;
540 err = p9pdu_readf(req->rc, c->proto_version, "s?d", 532 err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
541 &ename, &ecode); 533 &ename, &ecode);
542 if (err) 534 if (err)
543 goto out_err; 535 goto out_err;
@@ -553,7 +545,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
553 } 545 }
554 kfree(ename); 546 kfree(ename);
555 } else { 547 } else {
556 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); 548 err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
557 err = -ecode; 549 err = -ecode;
558 550
559 p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); 551 p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
@@ -587,12 +579,12 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
587 int8_t type; 579 int8_t type;
588 char *ename = NULL; 580 char *ename = NULL;
589 581
590 err = p9_parse_header(req->rc, NULL, &type, NULL, 0); 582 err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
591 /* 583 /*
592 * dump the response from server 584 * dump the response from server
593 * This should be after parse_header which poplulate pdu_fcall. 585 * This should be after parse_header which poplulate pdu_fcall.
594 */ 586 */
595 trace_9p_protocol_dump(c, req->rc); 587 trace_9p_protocol_dump(c, &req->rc);
596 if (err) { 588 if (err) {
597 p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err); 589 p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
598 return err; 590 return err;
@@ -607,13 +599,13 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
607 /* 7 = header size for RERROR; */ 599 /* 7 = header size for RERROR; */
608 int inline_len = in_hdrlen - 7; 600 int inline_len = in_hdrlen - 7;
609 601
610 len = req->rc->size - req->rc->offset; 602 len = req->rc.size - req->rc.offset;
611 if (len > (P9_ZC_HDR_SZ - 7)) { 603 if (len > (P9_ZC_HDR_SZ - 7)) {
612 err = -EFAULT; 604 err = -EFAULT;
613 goto out_err; 605 goto out_err;
614 } 606 }
615 607
616 ename = &req->rc->sdata[req->rc->offset]; 608 ename = &req->rc.sdata[req->rc.offset];
617 if (len > inline_len) { 609 if (len > inline_len) {
618 /* We have error in external buffer */ 610 /* We have error in external buffer */
619 if (!copy_from_iter_full(ename + inline_len, 611 if (!copy_from_iter_full(ename + inline_len,
@@ -623,7 +615,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
623 } 615 }
624 } 616 }
625 ename = NULL; 617 ename = NULL;
626 err = p9pdu_readf(req->rc, c->proto_version, "s?d", 618 err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
627 &ename, &ecode); 619 &ename, &ecode);
628 if (err) 620 if (err)
629 goto out_err; 621 goto out_err;
@@ -639,7 +631,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
639 } 631 }
640 kfree(ename); 632 kfree(ename);
641 } else { 633 } else {
642 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); 634 err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
643 err = -ecode; 635 err = -ecode;
644 636
645 p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); 637 p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
@@ -672,7 +664,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
672 int16_t oldtag; 664 int16_t oldtag;
673 int err; 665 int err;
674 666
675 err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1); 667 err = p9_parse_header(&oldreq->tc, NULL, NULL, &oldtag, 1);
676 if (err) 668 if (err)
677 return err; 669 return err;
678 670
@@ -686,11 +678,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
686 * if we haven't received a response for oldreq, 678 * if we haven't received a response for oldreq,
687 * remove it from the list 679 * remove it from the list
688 */ 680 */
689 if (oldreq->status == REQ_STATUS_SENT) 681 if (oldreq->status == REQ_STATUS_SENT) {
690 if (c->trans_mod->cancelled) 682 if (c->trans_mod->cancelled)
691 c->trans_mod->cancelled(c, oldreq); 683 c->trans_mod->cancelled(c, oldreq);
684 }
692 685
693 p9_free_req(c, req); 686 p9_tag_remove(c, req);
694 return 0; 687 return 0;
695} 688}
696 689
@@ -698,7 +691,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
698 int8_t type, int req_size, 691 int8_t type, int req_size,
699 const char *fmt, va_list ap) 692 const char *fmt, va_list ap)
700{ 693{
701 int tag, err; 694 int err;
702 struct p9_req_t *req; 695 struct p9_req_t *req;
703 696
704 p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type); 697 p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type);
@@ -711,27 +704,22 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
711 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) 704 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
712 return ERR_PTR(-EIO); 705 return ERR_PTR(-EIO);
713 706
714 tag = P9_NOTAG; 707 req = p9_tag_alloc(c, type, req_size);
715 if (type != P9_TVERSION) {
716 tag = p9_idpool_get(c->tagpool);
717 if (tag < 0)
718 return ERR_PTR(-ENOMEM);
719 }
720
721 req = p9_tag_alloc(c, tag, req_size);
722 if (IS_ERR(req)) 708 if (IS_ERR(req))
723 return req; 709 return req;
724 710
725 /* marshall the data */ 711 /* marshall the data */
726 p9pdu_prepare(req->tc, tag, type); 712 p9pdu_prepare(&req->tc, req->tc.tag, type);
727 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); 713 err = p9pdu_vwritef(&req->tc, c->proto_version, fmt, ap);
728 if (err) 714 if (err)
729 goto reterr; 715 goto reterr;
730 p9pdu_finalize(c, req->tc); 716 p9pdu_finalize(c, &req->tc);
731 trace_9p_client_req(c, type, tag); 717 trace_9p_client_req(c, type, req->tc.tag);
732 return req; 718 return req;
733reterr: 719reterr:
734 p9_free_req(c, req); 720 p9_tag_remove(c, req);
721 /* We have to put also the 2nd reference as it won't be used */
722 p9_req_put(req);
735 return ERR_PTR(err); 723 return ERR_PTR(err);
736} 724}
737 725
@@ -741,7 +729,7 @@ reterr:
741 * @type: type of request 729 * @type: type of request
742 * @fmt: protocol format string (see protocol.c) 730 * @fmt: protocol format string (see protocol.c)
743 * 731 *
744 * Returns request structure (which client must free using p9_free_req) 732 * Returns request structure (which client must free using p9_tag_remove)
745 */ 733 */
746 734
747static struct p9_req_t * 735static struct p9_req_t *
@@ -766,6 +754,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
766 754
767 err = c->trans_mod->request(c, req); 755 err = c->trans_mod->request(c, req);
768 if (err < 0) { 756 if (err < 0) {
757 /* write won't happen */
758 p9_req_put(req);
769 if (err != -ERESTARTSYS && err != -EFAULT) 759 if (err != -ERESTARTSYS && err != -EFAULT)
770 c->status = Disconnected; 760 c->status = Disconnected;
771 goto recalc_sigpending; 761 goto recalc_sigpending;
@@ -813,11 +803,11 @@ recalc_sigpending:
813 goto reterr; 803 goto reterr;
814 804
815 err = p9_check_errors(c, req); 805 err = p9_check_errors(c, req);
816 trace_9p_client_res(c, type, req->rc->tag, err); 806 trace_9p_client_res(c, type, req->rc.tag, err);
817 if (!err) 807 if (!err)
818 return req; 808 return req;
819reterr: 809reterr:
820 p9_free_req(c, req); 810 p9_tag_remove(c, req);
821 return ERR_PTR(safe_errno(err)); 811 return ERR_PTR(safe_errno(err));
822} 812}
823 813
@@ -832,7 +822,7 @@ reterr:
832 * @hdrlen: reader header size, This is the size of response protocol data 822 * @hdrlen: reader header size, This is the size of response protocol data
833 * @fmt: protocol format string (see protocol.c) 823 * @fmt: protocol format string (see protocol.c)
834 * 824 *
835 * Returns request structure (which client must free using p9_free_req) 825 * Returns request structure (which client must free using p9_tag_remove)
836 */ 826 */
837static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, 827static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
838 struct iov_iter *uidata, 828 struct iov_iter *uidata,
@@ -895,11 +885,11 @@ recalc_sigpending:
895 goto reterr; 885 goto reterr;
896 886
897 err = p9_check_zc_errors(c, req, uidata, in_hdrlen); 887 err = p9_check_zc_errors(c, req, uidata, in_hdrlen);
898 trace_9p_client_res(c, type, req->rc->tag, err); 888 trace_9p_client_res(c, type, req->rc.tag, err);
899 if (!err) 889 if (!err)
900 return req; 890 return req;
901reterr: 891reterr:
902 p9_free_req(c, req); 892 p9_tag_remove(c, req);
903 return ERR_PTR(safe_errno(err)); 893 return ERR_PTR(safe_errno(err));
904} 894}
905 895
@@ -978,10 +968,10 @@ static int p9_client_version(struct p9_client *c)
978 if (IS_ERR(req)) 968 if (IS_ERR(req))
979 return PTR_ERR(req); 969 return PTR_ERR(req);
980 970
981 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); 971 err = p9pdu_readf(&req->rc, c->proto_version, "ds", &msize, &version);
982 if (err) { 972 if (err) {
983 p9_debug(P9_DEBUG_9P, "version error %d\n", err); 973 p9_debug(P9_DEBUG_9P, "version error %d\n", err);
984 trace_9p_protocol_dump(c, req->rc); 974 trace_9p_protocol_dump(c, &req->rc);
985 goto error; 975 goto error;
986 } 976 }
987 977
@@ -1002,7 +992,7 @@ static int p9_client_version(struct p9_client *c)
1002 992
1003error: 993error:
1004 kfree(version); 994 kfree(version);
1005 p9_free_req(c, req); 995 p9_tag_remove(c, req);
1006 996
1007 return err; 997 return err;
1008} 998}
@@ -1020,20 +1010,18 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1020 1010
1021 clnt->trans_mod = NULL; 1011 clnt->trans_mod = NULL;
1022 clnt->trans = NULL; 1012 clnt->trans = NULL;
1013 clnt->fcall_cache = NULL;
1023 1014
1024 client_id = utsname()->nodename; 1015 client_id = utsname()->nodename;
1025 memcpy(clnt->name, client_id, strlen(client_id) + 1); 1016 memcpy(clnt->name, client_id, strlen(client_id) + 1);
1026 1017
1027 spin_lock_init(&clnt->lock); 1018 spin_lock_init(&clnt->lock);
1028 idr_init(&clnt->fids); 1019 idr_init(&clnt->fids);
1029 1020 idr_init(&clnt->reqs);
1030 err = p9_tag_init(clnt);
1031 if (err < 0)
1032 goto free_client;
1033 1021
1034 err = parse_opts(options, clnt); 1022 err = parse_opts(options, clnt);
1035 if (err < 0) 1023 if (err < 0)
1036 goto destroy_tagpool; 1024 goto free_client;
1037 1025
1038 if (!clnt->trans_mod) 1026 if (!clnt->trans_mod)
1039 clnt->trans_mod = v9fs_get_default_trans(); 1027 clnt->trans_mod = v9fs_get_default_trans();
@@ -1042,7 +1030,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1042 err = -EPROTONOSUPPORT; 1030 err = -EPROTONOSUPPORT;
1043 p9_debug(P9_DEBUG_ERROR, 1031 p9_debug(P9_DEBUG_ERROR,
1044 "No transport defined or default transport\n"); 1032 "No transport defined or default transport\n");
1045 goto destroy_tagpool; 1033 goto free_client;
1046 } 1034 }
1047 1035
1048 p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n", 1036 p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
@@ -1059,14 +1047,21 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1059 if (err) 1047 if (err)
1060 goto close_trans; 1048 goto close_trans;
1061 1049
1050 /* P9_HDRSZ + 4 is the smallest packet header we can have that is
1051 * followed by data accessed from userspace by read
1052 */
1053 clnt->fcall_cache =
1054 kmem_cache_create_usercopy("9p-fcall-cache", clnt->msize,
1055 0, 0, P9_HDRSZ + 4,
1056 clnt->msize - (P9_HDRSZ + 4),
1057 NULL);
1058
1062 return clnt; 1059 return clnt;
1063 1060
1064close_trans: 1061close_trans:
1065 clnt->trans_mod->close(clnt); 1062 clnt->trans_mod->close(clnt);
1066put_trans: 1063put_trans:
1067 v9fs_put_trans(clnt->trans_mod); 1064 v9fs_put_trans(clnt->trans_mod);
1068destroy_tagpool:
1069 p9_idpool_destroy(clnt->tagpool);
1070free_client: 1065free_client:
1071 kfree(clnt); 1066 kfree(clnt);
1072 return ERR_PTR(err); 1067 return ERR_PTR(err);
@@ -1092,6 +1087,7 @@ void p9_client_destroy(struct p9_client *clnt)
1092 1087
1093 p9_tag_cleanup(clnt); 1088 p9_tag_cleanup(clnt);
1094 1089
1090 kmem_cache_destroy(clnt->fcall_cache);
1095 kfree(clnt); 1091 kfree(clnt);
1096} 1092}
1097EXPORT_SYMBOL(p9_client_destroy); 1093EXPORT_SYMBOL(p9_client_destroy);
@@ -1135,10 +1131,10 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1135 goto error; 1131 goto error;
1136 } 1132 }
1137 1133
1138 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); 1134 err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid);
1139 if (err) { 1135 if (err) {
1140 trace_9p_protocol_dump(clnt, req->rc); 1136 trace_9p_protocol_dump(clnt, &req->rc);
1141 p9_free_req(clnt, req); 1137 p9_tag_remove(clnt, req);
1142 goto error; 1138 goto error;
1143 } 1139 }
1144 1140
@@ -1147,7 +1143,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1147 1143
1148 memmove(&fid->qid, &qid, sizeof(struct p9_qid)); 1144 memmove(&fid->qid, &qid, sizeof(struct p9_qid));
1149 1145
1150 p9_free_req(clnt, req); 1146 p9_tag_remove(clnt, req);
1151 return fid; 1147 return fid;
1152 1148
1153error: 1149error:
@@ -1192,13 +1188,13 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
1192 goto error; 1188 goto error;
1193 } 1189 }
1194 1190
1195 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); 1191 err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids);
1196 if (err) { 1192 if (err) {
1197 trace_9p_protocol_dump(clnt, req->rc); 1193 trace_9p_protocol_dump(clnt, &req->rc);
1198 p9_free_req(clnt, req); 1194 p9_tag_remove(clnt, req);
1199 goto clunk_fid; 1195 goto clunk_fid;
1200 } 1196 }
1201 p9_free_req(clnt, req); 1197 p9_tag_remove(clnt, req);
1202 1198
1203 p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids); 1199 p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
1204 1200
@@ -1259,9 +1255,9 @@ int p9_client_open(struct p9_fid *fid, int mode)
1259 goto error; 1255 goto error;
1260 } 1256 }
1261 1257
1262 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1258 err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1263 if (err) { 1259 if (err) {
1264 trace_9p_protocol_dump(clnt, req->rc); 1260 trace_9p_protocol_dump(clnt, &req->rc);
1265 goto free_and_error; 1261 goto free_and_error;
1266 } 1262 }
1267 1263
@@ -1273,7 +1269,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
1273 fid->iounit = iounit; 1269 fid->iounit = iounit;
1274 1270
1275free_and_error: 1271free_and_error:
1276 p9_free_req(clnt, req); 1272 p9_tag_remove(clnt, req);
1277error: 1273error:
1278 return err; 1274 return err;
1279} 1275}
@@ -1303,9 +1299,9 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
1303 goto error; 1299 goto error;
1304 } 1300 }
1305 1301
1306 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); 1302 err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", qid, &iounit);
1307 if (err) { 1303 if (err) {
1308 trace_9p_protocol_dump(clnt, req->rc); 1304 trace_9p_protocol_dump(clnt, &req->rc);
1309 goto free_and_error; 1305 goto free_and_error;
1310 } 1306 }
1311 1307
@@ -1318,7 +1314,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
1318 ofid->iounit = iounit; 1314 ofid->iounit = iounit;
1319 1315
1320free_and_error: 1316free_and_error:
1321 p9_free_req(clnt, req); 1317 p9_tag_remove(clnt, req);
1322error: 1318error:
1323 return err; 1319 return err;
1324} 1320}
@@ -1348,9 +1344,9 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
1348 goto error; 1344 goto error;
1349 } 1345 }
1350 1346
1351 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1347 err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1352 if (err) { 1348 if (err) {
1353 trace_9p_protocol_dump(clnt, req->rc); 1349 trace_9p_protocol_dump(clnt, &req->rc);
1354 goto free_and_error; 1350 goto free_and_error;
1355 } 1351 }
1356 1352
@@ -1363,7 +1359,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
1363 fid->iounit = iounit; 1359 fid->iounit = iounit;
1364 1360
1365free_and_error: 1361free_and_error:
1366 p9_free_req(clnt, req); 1362 p9_tag_remove(clnt, req);
1367error: 1363error:
1368 return err; 1364 return err;
1369} 1365}
@@ -1387,9 +1383,9 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
1387 goto error; 1383 goto error;
1388 } 1384 }
1389 1385
1390 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1386 err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
1391 if (err) { 1387 if (err) {
1392 trace_9p_protocol_dump(clnt, req->rc); 1388 trace_9p_protocol_dump(clnt, &req->rc);
1393 goto free_and_error; 1389 goto free_and_error;
1394 } 1390 }
1395 1391
@@ -1397,7 +1393,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
1397 qid->type, (unsigned long long)qid->path, qid->version); 1393 qid->type, (unsigned long long)qid->path, qid->version);
1398 1394
1399free_and_error: 1395free_and_error:
1400 p9_free_req(clnt, req); 1396 p9_tag_remove(clnt, req);
1401error: 1397error:
1402 return err; 1398 return err;
1403} 1399}
@@ -1417,7 +1413,7 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna
1417 return PTR_ERR(req); 1413 return PTR_ERR(req);
1418 1414
1419 p9_debug(P9_DEBUG_9P, "<<< RLINK\n"); 1415 p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
1420 p9_free_req(clnt, req); 1416 p9_tag_remove(clnt, req);
1421 return 0; 1417 return 0;
1422} 1418}
1423EXPORT_SYMBOL(p9_client_link); 1419EXPORT_SYMBOL(p9_client_link);
@@ -1441,7 +1437,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync)
1441 1437
1442 p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid); 1438 p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
1443 1439
1444 p9_free_req(clnt, req); 1440 p9_tag_remove(clnt, req);
1445 1441
1446error: 1442error:
1447 return err; 1443 return err;
@@ -1476,7 +1472,7 @@ again:
1476 1472
1477 p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid); 1473 p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
1478 1474
1479 p9_free_req(clnt, req); 1475 p9_tag_remove(clnt, req);
1480error: 1476error:
1481 /* 1477 /*
1482 * Fid is not valid even after a failed clunk 1478 * Fid is not valid even after a failed clunk
@@ -1510,7 +1506,7 @@ int p9_client_remove(struct p9_fid *fid)
1510 1506
1511 p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid); 1507 p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
1512 1508
1513 p9_free_req(clnt, req); 1509 p9_tag_remove(clnt, req);
1514error: 1510error:
1515 if (err == -ERESTARTSYS) 1511 if (err == -ERESTARTSYS)
1516 p9_client_clunk(fid); 1512 p9_client_clunk(fid);
@@ -1537,7 +1533,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
1537 } 1533 }
1538 p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name); 1534 p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
1539 1535
1540 p9_free_req(clnt, req); 1536 p9_tag_remove(clnt, req);
1541error: 1537error:
1542 return err; 1538 return err;
1543} 1539}
@@ -1585,11 +1581,11 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
1585 break; 1581 break;
1586 } 1582 }
1587 1583
1588 *err = p9pdu_readf(req->rc, clnt->proto_version, 1584 *err = p9pdu_readf(&req->rc, clnt->proto_version,
1589 "D", &count, &dataptr); 1585 "D", &count, &dataptr);
1590 if (*err) { 1586 if (*err) {
1591 trace_9p_protocol_dump(clnt, req->rc); 1587 trace_9p_protocol_dump(clnt, &req->rc);
1592 p9_free_req(clnt, req); 1588 p9_tag_remove(clnt, req);
1593 break; 1589 break;
1594 } 1590 }
1595 if (rsize < count) { 1591 if (rsize < count) {
@@ -1599,7 +1595,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
1599 1595
1600 p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1596 p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1601 if (!count) { 1597 if (!count) {
1602 p9_free_req(clnt, req); 1598 p9_tag_remove(clnt, req);
1603 break; 1599 break;
1604 } 1600 }
1605 1601
@@ -1609,7 +1605,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
1609 offset += n; 1605 offset += n;
1610 if (n != count) { 1606 if (n != count) {
1611 *err = -EFAULT; 1607 *err = -EFAULT;
1612 p9_free_req(clnt, req); 1608 p9_tag_remove(clnt, req);
1613 break; 1609 break;
1614 } 1610 }
1615 } else { 1611 } else {
@@ -1617,7 +1613,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
1617 total += count; 1613 total += count;
1618 offset += count; 1614 offset += count;
1619 } 1615 }
1620 p9_free_req(clnt, req); 1616 p9_tag_remove(clnt, req);
1621 } 1617 }
1622 return total; 1618 return total;
1623} 1619}
@@ -1658,10 +1654,10 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
1658 break; 1654 break;
1659 } 1655 }
1660 1656
1661 *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); 1657 *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
1662 if (*err) { 1658 if (*err) {
1663 trace_9p_protocol_dump(clnt, req->rc); 1659 trace_9p_protocol_dump(clnt, &req->rc);
1664 p9_free_req(clnt, req); 1660 p9_tag_remove(clnt, req);
1665 break; 1661 break;
1666 } 1662 }
1667 if (rsize < count) { 1663 if (rsize < count) {
@@ -1671,7 +1667,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
1671 1667
1672 p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); 1668 p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
1673 1669
1674 p9_free_req(clnt, req); 1670 p9_tag_remove(clnt, req);
1675 iov_iter_advance(from, count); 1671 iov_iter_advance(from, count);
1676 total += count; 1672 total += count;
1677 offset += count; 1673 offset += count;
@@ -1702,10 +1698,10 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1702 goto error; 1698 goto error;
1703 } 1699 }
1704 1700
1705 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); 1701 err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret);
1706 if (err) { 1702 if (err) {
1707 trace_9p_protocol_dump(clnt, req->rc); 1703 trace_9p_protocol_dump(clnt, &req->rc);
1708 p9_free_req(clnt, req); 1704 p9_tag_remove(clnt, req);
1709 goto error; 1705 goto error;
1710 } 1706 }
1711 1707
@@ -1722,7 +1718,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1722 from_kgid(&init_user_ns, ret->n_gid), 1718 from_kgid(&init_user_ns, ret->n_gid),
1723 from_kuid(&init_user_ns, ret->n_muid)); 1719 from_kuid(&init_user_ns, ret->n_muid));
1724 1720
1725 p9_free_req(clnt, req); 1721 p9_tag_remove(clnt, req);
1726 return ret; 1722 return ret;
1727 1723
1728error: 1724error:
@@ -1755,10 +1751,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1755 goto error; 1751 goto error;
1756 } 1752 }
1757 1753
1758 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); 1754 err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret);
1759 if (err) { 1755 if (err) {
1760 trace_9p_protocol_dump(clnt, req->rc); 1756 trace_9p_protocol_dump(clnt, &req->rc);
1761 p9_free_req(clnt, req); 1757 p9_tag_remove(clnt, req);
1762 goto error; 1758 goto error;
1763 } 1759 }
1764 1760
@@ -1783,7 +1779,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1783 ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, 1779 ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
1784 ret->st_gen, ret->st_data_version); 1780 ret->st_gen, ret->st_data_version);
1785 1781
1786 p9_free_req(clnt, req); 1782 p9_tag_remove(clnt, req);
1787 return ret; 1783 return ret;
1788 1784
1789error: 1785error:
@@ -1852,7 +1848,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
1852 1848
1853 p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid); 1849 p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
1854 1850
1855 p9_free_req(clnt, req); 1851 p9_tag_remove(clnt, req);
1856error: 1852error:
1857 return err; 1853 return err;
1858} 1854}
@@ -1884,7 +1880,7 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
1884 goto error; 1880 goto error;
1885 } 1881 }
1886 p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid); 1882 p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
1887 p9_free_req(clnt, req); 1883 p9_tag_remove(clnt, req);
1888error: 1884error:
1889 return err; 1885 return err;
1890} 1886}
@@ -1907,12 +1903,12 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1907 goto error; 1903 goto error;
1908 } 1904 }
1909 1905
1910 err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type, 1906 err = p9pdu_readf(&req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
1911 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, 1907 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1912 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); 1908 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1913 if (err) { 1909 if (err) {
1914 trace_9p_protocol_dump(clnt, req->rc); 1910 trace_9p_protocol_dump(clnt, &req->rc);
1915 p9_free_req(clnt, req); 1911 p9_tag_remove(clnt, req);
1916 goto error; 1912 goto error;
1917 } 1913 }
1918 1914
@@ -1923,7 +1919,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1923 sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree, 1919 sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree,
1924 sb->fsid, (long int)sb->namelen); 1920 sb->fsid, (long int)sb->namelen);
1925 1921
1926 p9_free_req(clnt, req); 1922 p9_tag_remove(clnt, req);
1927error: 1923error:
1928 return err; 1924 return err;
1929} 1925}
@@ -1951,7 +1947,7 @@ int p9_client_rename(struct p9_fid *fid,
1951 1947
1952 p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid); 1948 p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
1953 1949
1954 p9_free_req(clnt, req); 1950 p9_tag_remove(clnt, req);
1955error: 1951error:
1956 return err; 1952 return err;
1957} 1953}
@@ -1981,7 +1977,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
1981 p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n", 1977 p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
1982 newdirfid->fid, new_name); 1978 newdirfid->fid, new_name);
1983 1979
1984 p9_free_req(clnt, req); 1980 p9_tag_remove(clnt, req);
1985error: 1981error:
1986 return err; 1982 return err;
1987} 1983}
@@ -2015,13 +2011,13 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
2015 err = PTR_ERR(req); 2011 err = PTR_ERR(req);
2016 goto error; 2012 goto error;
2017 } 2013 }
2018 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); 2014 err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size);
2019 if (err) { 2015 if (err) {
2020 trace_9p_protocol_dump(clnt, req->rc); 2016 trace_9p_protocol_dump(clnt, &req->rc);
2021 p9_free_req(clnt, req); 2017 p9_tag_remove(clnt, req);
2022 goto clunk_fid; 2018 goto clunk_fid;
2023 } 2019 }
2024 p9_free_req(clnt, req); 2020 p9_tag_remove(clnt, req);
2025 p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n", 2021 p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
2026 attr_fid->fid, *attr_size); 2022 attr_fid->fid, *attr_size);
2027 return attr_fid; 2023 return attr_fid;
@@ -2055,7 +2051,7 @@ int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
2055 goto error; 2051 goto error;
2056 } 2052 }
2057 p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid); 2053 p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
2058 p9_free_req(clnt, req); 2054 p9_tag_remove(clnt, req);
2059error: 2055error:
2060 return err; 2056 return err;
2061} 2057}
@@ -2103,9 +2099,9 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2103 goto error; 2099 goto error;
2104 } 2100 }
2105 2101
2106 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 2102 err = p9pdu_readf(&req->rc, clnt->proto_version, "D", &count, &dataptr);
2107 if (err) { 2103 if (err) {
2108 trace_9p_protocol_dump(clnt, req->rc); 2104 trace_9p_protocol_dump(clnt, &req->rc);
2109 goto free_and_error; 2105 goto free_and_error;
2110 } 2106 }
2111 if (rsize < count) { 2107 if (rsize < count) {
@@ -2118,11 +2114,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2118 if (non_zc) 2114 if (non_zc)
2119 memmove(data, dataptr, count); 2115 memmove(data, dataptr, count);
2120 2116
2121 p9_free_req(clnt, req); 2117 p9_tag_remove(clnt, req);
2122 return count; 2118 return count;
2123 2119
2124free_and_error: 2120free_and_error:
2125 p9_free_req(clnt, req); 2121 p9_tag_remove(clnt, req);
2126error: 2122error:
2127 return err; 2123 return err;
2128} 2124}
@@ -2144,16 +2140,16 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
2144 if (IS_ERR(req)) 2140 if (IS_ERR(req))
2145 return PTR_ERR(req); 2141 return PTR_ERR(req);
2146 2142
2147 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 2143 err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
2148 if (err) { 2144 if (err) {
2149 trace_9p_protocol_dump(clnt, req->rc); 2145 trace_9p_protocol_dump(clnt, &req->rc);
2150 goto error; 2146 goto error;
2151 } 2147 }
2152 p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, 2148 p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
2153 (unsigned long long)qid->path, qid->version); 2149 (unsigned long long)qid->path, qid->version);
2154 2150
2155error: 2151error:
2156 p9_free_req(clnt, req); 2152 p9_tag_remove(clnt, req);
2157 return err; 2153 return err;
2158 2154
2159} 2155}
@@ -2175,16 +2171,16 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
2175 if (IS_ERR(req)) 2171 if (IS_ERR(req))
2176 return PTR_ERR(req); 2172 return PTR_ERR(req);
2177 2173
2178 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 2174 err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
2179 if (err) { 2175 if (err) {
2180 trace_9p_protocol_dump(clnt, req->rc); 2176 trace_9p_protocol_dump(clnt, &req->rc);
2181 goto error; 2177 goto error;
2182 } 2178 }
2183 p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, 2179 p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
2184 (unsigned long long)qid->path, qid->version); 2180 (unsigned long long)qid->path, qid->version);
2185 2181
2186error: 2182error:
2187 p9_free_req(clnt, req); 2183 p9_tag_remove(clnt, req);
2188 return err; 2184 return err;
2189 2185
2190} 2186}
@@ -2210,14 +2206,14 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
2210 if (IS_ERR(req)) 2206 if (IS_ERR(req))
2211 return PTR_ERR(req); 2207 return PTR_ERR(req);
2212 2208
2213 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status); 2209 err = p9pdu_readf(&req->rc, clnt->proto_version, "b", status);
2214 if (err) { 2210 if (err) {
2215 trace_9p_protocol_dump(clnt, req->rc); 2211 trace_9p_protocol_dump(clnt, &req->rc);
2216 goto error; 2212 goto error;
2217 } 2213 }
2218 p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status); 2214 p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
2219error: 2215error:
2220 p9_free_req(clnt, req); 2216 p9_tag_remove(clnt, req);
2221 return err; 2217 return err;
2222 2218
2223} 2219}
@@ -2241,18 +2237,18 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
2241 if (IS_ERR(req)) 2237 if (IS_ERR(req))
2242 return PTR_ERR(req); 2238 return PTR_ERR(req);
2243 2239
2244 err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type, 2240 err = p9pdu_readf(&req->rc, clnt->proto_version, "bqqds", &glock->type,
2245 &glock->start, &glock->length, &glock->proc_id, 2241 &glock->start, &glock->length, &glock->proc_id,
2246 &glock->client_id); 2242 &glock->client_id);
2247 if (err) { 2243 if (err) {
2248 trace_9p_protocol_dump(clnt, req->rc); 2244 trace_9p_protocol_dump(clnt, &req->rc);
2249 goto error; 2245 goto error;
2250 } 2246 }
2251 p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " 2247 p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
2252 "proc_id %d client_id %s\n", glock->type, glock->start, 2248 "proc_id %d client_id %s\n", glock->type, glock->start,
2253 glock->length, glock->proc_id, glock->client_id); 2249 glock->length, glock->proc_id, glock->client_id);
2254error: 2250error:
2255 p9_free_req(clnt, req); 2251 p9_tag_remove(clnt, req);
2256 return err; 2252 return err;
2257} 2253}
2258EXPORT_SYMBOL(p9_client_getlock_dotl); 2254EXPORT_SYMBOL(p9_client_getlock_dotl);
@@ -2271,14 +2267,25 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
2271 if (IS_ERR(req)) 2267 if (IS_ERR(req))
2272 return PTR_ERR(req); 2268 return PTR_ERR(req);
2273 2269
2274 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target); 2270 err = p9pdu_readf(&req->rc, clnt->proto_version, "s", target);
2275 if (err) { 2271 if (err) {
2276 trace_9p_protocol_dump(clnt, req->rc); 2272 trace_9p_protocol_dump(clnt, &req->rc);
2277 goto error; 2273 goto error;
2278 } 2274 }
2279 p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target); 2275 p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
2280error: 2276error:
2281 p9_free_req(clnt, req); 2277 p9_tag_remove(clnt, req);
2282 return err; 2278 return err;
2283} 2279}
2284EXPORT_SYMBOL(p9_client_readlink); 2280EXPORT_SYMBOL(p9_client_readlink);
2281
2282int __init p9_client_init(void)
2283{
2284 p9_req_cache = KMEM_CACHE(p9_req_t, SLAB_TYPESAFE_BY_RCU);
2285 return p9_req_cache ? 0 : -ENOMEM;
2286}
2287
2288void __exit p9_client_exit(void)
2289{
2290 kmem_cache_destroy(p9_req_cache);
2291}
diff --git a/net/9p/mod.c b/net/9p/mod.c
index 253ba824a325..0da56d6af73b 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -171,11 +171,17 @@ void v9fs_put_trans(struct p9_trans_module *m)
171 */ 171 */
172static int __init init_p9(void) 172static int __init init_p9(void)
173{ 173{
174 int ret;
175
176 ret = p9_client_init();
177 if (ret)
178 return ret;
179
174 p9_error_init(); 180 p9_error_init();
175 pr_info("Installing 9P2000 support\n"); 181 pr_info("Installing 9P2000 support\n");
176 p9_trans_fd_init(); 182 p9_trans_fd_init();
177 183
178 return 0; 184 return ret;
179} 185}
180 186
181/** 187/**
@@ -188,6 +194,7 @@ static void __exit exit_p9(void)
188 pr_info("Unloading 9P2000 support\n"); 194 pr_info("Unloading 9P2000 support\n");
189 195
190 p9_trans_fd_exit(); 196 p9_trans_fd_exit();
197 p9_client_exit();
191} 198}
192 199
193module_init(init_p9) 200module_init(init_p9)
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 4a1e1dd30b52..462ba144cb39 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -46,10 +46,15 @@ p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
46void p9stat_free(struct p9_wstat *stbuf) 46void p9stat_free(struct p9_wstat *stbuf)
47{ 47{
48 kfree(stbuf->name); 48 kfree(stbuf->name);
49 stbuf->name = NULL;
49 kfree(stbuf->uid); 50 kfree(stbuf->uid);
51 stbuf->uid = NULL;
50 kfree(stbuf->gid); 52 kfree(stbuf->gid);
53 stbuf->gid = NULL;
51 kfree(stbuf->muid); 54 kfree(stbuf->muid);
55 stbuf->muid = NULL;
52 kfree(stbuf->extension); 56 kfree(stbuf->extension);
57 stbuf->extension = NULL;
53} 58}
54EXPORT_SYMBOL(p9stat_free); 59EXPORT_SYMBOL(p9stat_free);
55 60
@@ -566,9 +571,10 @@ int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
566 if (ret) { 571 if (ret) {
567 p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); 572 p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
568 trace_9p_protocol_dump(clnt, &fake_pdu); 573 trace_9p_protocol_dump(clnt, &fake_pdu);
574 return ret;
569 } 575 }
570 576
571 return ret; 577 return fake_pdu.offset;
572} 578}
573EXPORT_SYMBOL(p9stat_read); 579EXPORT_SYMBOL(p9stat_read);
574 580
@@ -617,13 +623,19 @@ int p9dirent_read(struct p9_client *clnt, char *buf, int len,
617 if (ret) { 623 if (ret) {
618 p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret); 624 p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
619 trace_9p_protocol_dump(clnt, &fake_pdu); 625 trace_9p_protocol_dump(clnt, &fake_pdu);
620 goto out; 626 return ret;
621 } 627 }
622 628
623 strcpy(dirent->d_name, nameptr); 629 ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
630 if (ret < 0) {
631 p9_debug(P9_DEBUG_ERROR,
632 "On the wire dirent name too long: %s\n",
633 nameptr);
634 kfree(nameptr);
635 return ret;
636 }
624 kfree(nameptr); 637 kfree(nameptr);
625 638
626out:
627 return fake_pdu.offset; 639 return fake_pdu.offset;
628} 640}
629EXPORT_SYMBOL(p9dirent_read); 641EXPORT_SYMBOL(p9dirent_read);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index e2ef3c782c53..f868cf6fba79 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -131,7 +131,8 @@ struct p9_conn {
131 int err; 131 int err;
132 struct list_head req_list; 132 struct list_head req_list;
133 struct list_head unsent_req_list; 133 struct list_head unsent_req_list;
134 struct p9_req_t *req; 134 struct p9_req_t *rreq;
135 struct p9_req_t *wreq;
135 char tmp_buf[7]; 136 char tmp_buf[7];
136 struct p9_fcall rc; 137 struct p9_fcall rc;
137 int wpos; 138 int wpos;
@@ -291,7 +292,6 @@ static void p9_read_work(struct work_struct *work)
291 __poll_t n; 292 __poll_t n;
292 int err; 293 int err;
293 struct p9_conn *m; 294 struct p9_conn *m;
294 int status = REQ_STATUS_ERROR;
295 295
296 m = container_of(work, struct p9_conn, rq); 296 m = container_of(work, struct p9_conn, rq);
297 297
@@ -322,7 +322,7 @@ static void p9_read_work(struct work_struct *work)
322 m->rc.offset += err; 322 m->rc.offset += err;
323 323
324 /* header read in */ 324 /* header read in */
325 if ((!m->req) && (m->rc.offset == m->rc.capacity)) { 325 if ((!m->rreq) && (m->rc.offset == m->rc.capacity)) {
326 p9_debug(P9_DEBUG_TRANS, "got new header\n"); 326 p9_debug(P9_DEBUG_TRANS, "got new header\n");
327 327
328 /* Header size */ 328 /* Header size */
@@ -346,23 +346,23 @@ static void p9_read_work(struct work_struct *work)
346 "mux %p pkt: size: %d bytes tag: %d\n", 346 "mux %p pkt: size: %d bytes tag: %d\n",
347 m, m->rc.size, m->rc.tag); 347 m, m->rc.size, m->rc.tag);
348 348
349 m->req = p9_tag_lookup(m->client, m->rc.tag); 349 m->rreq = p9_tag_lookup(m->client, m->rc.tag);
350 if (!m->req || (m->req->status != REQ_STATUS_SENT)) { 350 if (!m->rreq || (m->rreq->status != REQ_STATUS_SENT)) {
351 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", 351 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
352 m->rc.tag); 352 m->rc.tag);
353 err = -EIO; 353 err = -EIO;
354 goto error; 354 goto error;
355 } 355 }
356 356
357 if (m->req->rc == NULL) { 357 if (!m->rreq->rc.sdata) {
358 p9_debug(P9_DEBUG_ERROR, 358 p9_debug(P9_DEBUG_ERROR,
359 "No recv fcall for tag %d (req %p), disconnecting!\n", 359 "No recv fcall for tag %d (req %p), disconnecting!\n",
360 m->rc.tag, m->req); 360 m->rc.tag, m->rreq);
361 m->req = NULL; 361 m->rreq = NULL;
362 err = -EIO; 362 err = -EIO;
363 goto error; 363 goto error;
364 } 364 }
365 m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall); 365 m->rc.sdata = m->rreq->rc.sdata;
366 memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity); 366 memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
367 m->rc.capacity = m->rc.size; 367 m->rc.capacity = m->rc.size;
368 } 368 }
@@ -370,20 +370,27 @@ static void p9_read_work(struct work_struct *work)
370 /* packet is read in 370 /* packet is read in
371 * not an else because some packets (like clunk) have no payload 371 * not an else because some packets (like clunk) have no payload
372 */ 372 */
373 if ((m->req) && (m->rc.offset == m->rc.capacity)) { 373 if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
374 p9_debug(P9_DEBUG_TRANS, "got new packet\n"); 374 p9_debug(P9_DEBUG_TRANS, "got new packet\n");
375 m->req->rc->size = m->rc.offset; 375 m->rreq->rc.size = m->rc.offset;
376 spin_lock(&m->client->lock); 376 spin_lock(&m->client->lock);
377 if (m->req->status != REQ_STATUS_ERROR) 377 if (m->rreq->status == REQ_STATUS_SENT) {
378 status = REQ_STATUS_RCVD; 378 list_del(&m->rreq->req_list);
379 list_del(&m->req->req_list); 379 p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
380 /* update req->status while holding client->lock */ 380 } else {
381 p9_client_cb(m->client, m->req, status); 381 spin_unlock(&m->client->lock);
382 p9_debug(P9_DEBUG_ERROR,
383 "Request tag %d errored out while we were reading the reply\n",
384 m->rc.tag);
385 err = -EIO;
386 goto error;
387 }
382 spin_unlock(&m->client->lock); 388 spin_unlock(&m->client->lock);
383 m->rc.sdata = NULL; 389 m->rc.sdata = NULL;
384 m->rc.offset = 0; 390 m->rc.offset = 0;
385 m->rc.capacity = 0; 391 m->rc.capacity = 0;
386 m->req = NULL; 392 p9_req_put(m->rreq);
393 m->rreq = NULL;
387 } 394 }
388 395
389end_clear: 396end_clear:
@@ -469,9 +476,11 @@ static void p9_write_work(struct work_struct *work)
469 p9_debug(P9_DEBUG_TRANS, "move req %p\n", req); 476 p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
470 list_move_tail(&req->req_list, &m->req_list); 477 list_move_tail(&req->req_list, &m->req_list);
471 478
472 m->wbuf = req->tc->sdata; 479 m->wbuf = req->tc.sdata;
473 m->wsize = req->tc->size; 480 m->wsize = req->tc.size;
474 m->wpos = 0; 481 m->wpos = 0;
482 p9_req_get(req);
483 m->wreq = req;
475 spin_unlock(&m->client->lock); 484 spin_unlock(&m->client->lock);
476 } 485 }
477 486
@@ -492,8 +501,11 @@ static void p9_write_work(struct work_struct *work)
492 } 501 }
493 502
494 m->wpos += err; 503 m->wpos += err;
495 if (m->wpos == m->wsize) 504 if (m->wpos == m->wsize) {
496 m->wpos = m->wsize = 0; 505 m->wpos = m->wsize = 0;
506 p9_req_put(m->wreq);
507 m->wreq = NULL;
508 }
497 509
498end_clear: 510end_clear:
499 clear_bit(Wworksched, &m->wsched); 511 clear_bit(Wworksched, &m->wsched);
@@ -663,7 +675,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
663 struct p9_conn *m = &ts->conn; 675 struct p9_conn *m = &ts->conn;
664 676
665 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", 677 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
666 m, current, req->tc, req->tc->id); 678 m, current, &req->tc, req->tc.id);
667 if (m->err < 0) 679 if (m->err < 0)
668 return m->err; 680 return m->err;
669 681
@@ -694,6 +706,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
694 if (req->status == REQ_STATUS_UNSENT) { 706 if (req->status == REQ_STATUS_UNSENT) {
695 list_del(&req->req_list); 707 list_del(&req->req_list);
696 req->status = REQ_STATUS_FLSHD; 708 req->status = REQ_STATUS_FLSHD;
709 p9_req_put(req);
697 ret = 0; 710 ret = 0;
698 } 711 }
699 spin_unlock(&client->lock); 712 spin_unlock(&client->lock);
@@ -711,6 +724,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
711 spin_lock(&client->lock); 724 spin_lock(&client->lock);
712 list_del(&req->req_list); 725 list_del(&req->req_list);
713 spin_unlock(&client->lock); 726 spin_unlock(&client->lock);
727 p9_req_put(req);
714 728
715 return 0; 729 return 0;
716} 730}
@@ -862,7 +876,15 @@ static void p9_conn_destroy(struct p9_conn *m)
862 876
863 p9_mux_poll_stop(m); 877 p9_mux_poll_stop(m);
864 cancel_work_sync(&m->rq); 878 cancel_work_sync(&m->rq);
879 if (m->rreq) {
880 p9_req_put(m->rreq);
881 m->rreq = NULL;
882 }
865 cancel_work_sync(&m->wq); 883 cancel_work_sync(&m->wq);
884 if (m->wreq) {
885 p9_req_put(m->wreq);
886 m->wreq = NULL;
887 }
866 888
867 p9_conn_cancel(m, -ECONNRESET); 889 p9_conn_cancel(m, -ECONNRESET);
868 890
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index b513cffeeb3c..119103bfa82e 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -122,7 +122,7 @@ struct p9_rdma_context {
122 dma_addr_t busa; 122 dma_addr_t busa;
123 union { 123 union {
124 struct p9_req_t *req; 124 struct p9_req_t *req;
125 struct p9_fcall *rc; 125 struct p9_fcall rc;
126 }; 126 };
127}; 127};
128 128
@@ -274,8 +274,7 @@ p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
274 case RDMA_CM_EVENT_DISCONNECTED: 274 case RDMA_CM_EVENT_DISCONNECTED:
275 if (rdma) 275 if (rdma)
276 rdma->state = P9_RDMA_CLOSED; 276 rdma->state = P9_RDMA_CLOSED;
277 if (c) 277 c->status = Disconnected;
278 c->status = Disconnected;
279 break; 278 break;
280 279
281 case RDMA_CM_EVENT_TIMEWAIT_EXIT: 280 case RDMA_CM_EVENT_TIMEWAIT_EXIT:
@@ -320,8 +319,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
320 if (wc->status != IB_WC_SUCCESS) 319 if (wc->status != IB_WC_SUCCESS)
321 goto err_out; 320 goto err_out;
322 321
323 c->rc->size = wc->byte_len; 322 c->rc.size = wc->byte_len;
324 err = p9_parse_header(c->rc, NULL, NULL, &tag, 1); 323 err = p9_parse_header(&c->rc, NULL, NULL, &tag, 1);
325 if (err) 324 if (err)
326 goto err_out; 325 goto err_out;
327 326
@@ -331,12 +330,13 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
331 330
332 /* Check that we have not yet received a reply for this request. 331 /* Check that we have not yet received a reply for this request.
333 */ 332 */
334 if (unlikely(req->rc)) { 333 if (unlikely(req->rc.sdata)) {
335 pr_err("Duplicate reply for request %d", tag); 334 pr_err("Duplicate reply for request %d", tag);
336 goto err_out; 335 goto err_out;
337 } 336 }
338 337
339 req->rc = c->rc; 338 req->rc.size = c->rc.size;
339 req->rc.sdata = c->rc.sdata;
340 p9_client_cb(client, req, REQ_STATUS_RCVD); 340 p9_client_cb(client, req, REQ_STATUS_RCVD);
341 341
342 out: 342 out:
@@ -361,9 +361,10 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
361 container_of(wc->wr_cqe, struct p9_rdma_context, cqe); 361 container_of(wc->wr_cqe, struct p9_rdma_context, cqe);
362 362
363 ib_dma_unmap_single(rdma->cm_id->device, 363 ib_dma_unmap_single(rdma->cm_id->device,
364 c->busa, c->req->tc->size, 364 c->busa, c->req->tc.size,
365 DMA_TO_DEVICE); 365 DMA_TO_DEVICE);
366 up(&rdma->sq_sem); 366 up(&rdma->sq_sem);
367 p9_req_put(c->req);
367 kfree(c); 368 kfree(c);
368} 369}
369 370
@@ -401,7 +402,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
401 struct ib_sge sge; 402 struct ib_sge sge;
402 403
403 c->busa = ib_dma_map_single(rdma->cm_id->device, 404 c->busa = ib_dma_map_single(rdma->cm_id->device,
404 c->rc->sdata, client->msize, 405 c->rc.sdata, client->msize,
405 DMA_FROM_DEVICE); 406 DMA_FROM_DEVICE);
406 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) 407 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
407 goto error; 408 goto error;
@@ -443,9 +444,9 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
443 **/ 444 **/
444 if (unlikely(atomic_read(&rdma->excess_rc) > 0)) { 445 if (unlikely(atomic_read(&rdma->excess_rc) > 0)) {
445 if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) { 446 if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) {
446 /* Got one ! */ 447 /* Got one! */
447 kfree(req->rc); 448 p9_fcall_fini(&req->rc);
448 req->rc = NULL; 449 req->rc.sdata = NULL;
449 goto dont_need_post_recv; 450 goto dont_need_post_recv;
450 } else { 451 } else {
451 /* We raced and lost. */ 452 /* We raced and lost. */
@@ -459,7 +460,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
459 err = -ENOMEM; 460 err = -ENOMEM;
460 goto recv_error; 461 goto recv_error;
461 } 462 }
462 rpl_context->rc = req->rc; 463 rpl_context->rc.sdata = req->rc.sdata;
463 464
464 /* 465 /*
465 * Post a receive buffer for this request. We need to ensure 466 * Post a receive buffer for this request. We need to ensure
@@ -475,11 +476,11 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
475 476
476 err = post_recv(client, rpl_context); 477 err = post_recv(client, rpl_context);
477 if (err) { 478 if (err) {
478 p9_debug(P9_DEBUG_FCALL, "POST RECV failed\n"); 479 p9_debug(P9_DEBUG_ERROR, "POST RECV failed: %d\n", err);
479 goto recv_error; 480 goto recv_error;
480 } 481 }
481 /* remove posted receive buffer from request structure */ 482 /* remove posted receive buffer from request structure */
482 req->rc = NULL; 483 req->rc.sdata = NULL;
483 484
484dont_need_post_recv: 485dont_need_post_recv:
485 /* Post the request */ 486 /* Post the request */
@@ -491,7 +492,7 @@ dont_need_post_recv:
491 c->req = req; 492 c->req = req;
492 493
493 c->busa = ib_dma_map_single(rdma->cm_id->device, 494 c->busa = ib_dma_map_single(rdma->cm_id->device,
494 c->req->tc->sdata, c->req->tc->size, 495 c->req->tc.sdata, c->req->tc.size,
495 DMA_TO_DEVICE); 496 DMA_TO_DEVICE);
496 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) { 497 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) {
497 err = -EIO; 498 err = -EIO;
@@ -501,7 +502,7 @@ dont_need_post_recv:
501 c->cqe.done = send_done; 502 c->cqe.done = send_done;
502 503
503 sge.addr = c->busa; 504 sge.addr = c->busa;
504 sge.length = c->req->tc->size; 505 sge.length = c->req->tc.size;
505 sge.lkey = rdma->pd->local_dma_lkey; 506 sge.lkey = rdma->pd->local_dma_lkey;
506 507
507 wr.next = NULL; 508 wr.next = NULL;
@@ -544,7 +545,7 @@ dont_need_post_recv:
544 recv_error: 545 recv_error:
545 kfree(rpl_context); 546 kfree(rpl_context);
546 spin_lock_irqsave(&rdma->req_lock, flags); 547 spin_lock_irqsave(&rdma->req_lock, flags);
547 if (rdma->state < P9_RDMA_CLOSING) { 548 if (err != -EINTR && rdma->state < P9_RDMA_CLOSING) {
548 rdma->state = P9_RDMA_CLOSING; 549 rdma->state = P9_RDMA_CLOSING;
549 spin_unlock_irqrestore(&rdma->req_lock, flags); 550 spin_unlock_irqrestore(&rdma->req_lock, flags);
550 rdma_disconnect(rdma->cm_id); 551 rdma_disconnect(rdma->cm_id);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 7728b0acde09..eb596c2ed546 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -155,7 +155,7 @@ static void req_done(struct virtqueue *vq)
155 } 155 }
156 156
157 if (len) { 157 if (len) {
158 req->rc->size = len; 158 req->rc.size = len;
159 p9_client_cb(chan->client, req, REQ_STATUS_RCVD); 159 p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
160 } 160 }
161 } 161 }
@@ -207,6 +207,13 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
207 return 1; 207 return 1;
208} 208}
209 209
210/* Reply won't come, so drop req ref */
211static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
212{
213 p9_req_put(req);
214 return 0;
215}
216
210/** 217/**
211 * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer, 218 * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
212 * this takes a list of pages. 219 * this takes a list of pages.
@@ -273,12 +280,12 @@ req_retry:
273 out_sgs = in_sgs = 0; 280 out_sgs = in_sgs = 0;
274 /* Handle out VirtIO ring buffers */ 281 /* Handle out VirtIO ring buffers */
275 out = pack_sg_list(chan->sg, 0, 282 out = pack_sg_list(chan->sg, 0,
276 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); 283 VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
277 if (out) 284 if (out)
278 sgs[out_sgs++] = chan->sg; 285 sgs[out_sgs++] = chan->sg;
279 286
280 in = pack_sg_list(chan->sg, out, 287 in = pack_sg_list(chan->sg, out,
281 VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity); 288 VIRTQUEUE_NUM, req->rc.sdata, req->rc.capacity);
282 if (in) 289 if (in)
283 sgs[out_sgs + in_sgs++] = chan->sg + out; 290 sgs[out_sgs + in_sgs++] = chan->sg + out;
284 291
@@ -404,6 +411,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
404 struct scatterlist *sgs[4]; 411 struct scatterlist *sgs[4];
405 size_t offs; 412 size_t offs;
406 int need_drop = 0; 413 int need_drop = 0;
414 int kicked = 0;
407 415
408 p9_debug(P9_DEBUG_TRANS, "virtio request\n"); 416 p9_debug(P9_DEBUG_TRANS, "virtio request\n");
409 417
@@ -411,29 +419,33 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
411 __le32 sz; 419 __le32 sz;
412 int n = p9_get_mapped_pages(chan, &out_pages, uodata, 420 int n = p9_get_mapped_pages(chan, &out_pages, uodata,
413 outlen, &offs, &need_drop); 421 outlen, &offs, &need_drop);
414 if (n < 0) 422 if (n < 0) {
415 return n; 423 err = n;
424 goto err_out;
425 }
416 out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); 426 out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
417 if (n != outlen) { 427 if (n != outlen) {
418 __le32 v = cpu_to_le32(n); 428 __le32 v = cpu_to_le32(n);
419 memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); 429 memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
420 outlen = n; 430 outlen = n;
421 } 431 }
422 /* The size field of the message must include the length of the 432 /* The size field of the message must include the length of the
423 * header and the length of the data. We didn't actually know 433 * header and the length of the data. We didn't actually know
424 * the length of the data until this point so add it in now. 434 * the length of the data until this point so add it in now.
425 */ 435 */
426 sz = cpu_to_le32(req->tc->size + outlen); 436 sz = cpu_to_le32(req->tc.size + outlen);
427 memcpy(&req->tc->sdata[0], &sz, sizeof(sz)); 437 memcpy(&req->tc.sdata[0], &sz, sizeof(sz));
428 } else if (uidata) { 438 } else if (uidata) {
429 int n = p9_get_mapped_pages(chan, &in_pages, uidata, 439 int n = p9_get_mapped_pages(chan, &in_pages, uidata,
430 inlen, &offs, &need_drop); 440 inlen, &offs, &need_drop);
431 if (n < 0) 441 if (n < 0) {
432 return n; 442 err = n;
443 goto err_out;
444 }
433 in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); 445 in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
434 if (n != inlen) { 446 if (n != inlen) {
435 __le32 v = cpu_to_le32(n); 447 __le32 v = cpu_to_le32(n);
436 memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); 448 memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
437 inlen = n; 449 inlen = n;
438 } 450 }
439 } 451 }
@@ -445,7 +457,7 @@ req_retry_pinned:
445 457
446 /* out data */ 458 /* out data */
447 out = pack_sg_list(chan->sg, 0, 459 out = pack_sg_list(chan->sg, 0,
448 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); 460 VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
449 461
450 if (out) 462 if (out)
451 sgs[out_sgs++] = chan->sg; 463 sgs[out_sgs++] = chan->sg;
@@ -464,7 +476,7 @@ req_retry_pinned:
464 * alloced memory and payload onto the user buffer. 476 * alloced memory and payload onto the user buffer.
465 */ 477 */
466 in = pack_sg_list(chan->sg, out, 478 in = pack_sg_list(chan->sg, out,
467 VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len); 479 VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len);
468 if (in) 480 if (in)
469 sgs[out_sgs + in_sgs++] = chan->sg + out; 481 sgs[out_sgs + in_sgs++] = chan->sg + out;
470 482
@@ -498,6 +510,7 @@ req_retry_pinned:
498 } 510 }
499 virtqueue_kick(chan->vq); 511 virtqueue_kick(chan->vq);
500 spin_unlock_irqrestore(&chan->lock, flags); 512 spin_unlock_irqrestore(&chan->lock, flags);
513 kicked = 1;
501 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); 514 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
502 err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD); 515 err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
503 /* 516 /*
@@ -518,6 +531,10 @@ err_out:
518 } 531 }
519 kvfree(in_pages); 532 kvfree(in_pages);
520 kvfree(out_pages); 533 kvfree(out_pages);
534 if (!kicked) {
535 /* reply won't come */
536 p9_req_put(req);
537 }
521 return err; 538 return err;
522} 539}
523 540
@@ -750,6 +767,7 @@ static struct p9_trans_module p9_virtio_trans = {
750 .request = p9_virtio_request, 767 .request = p9_virtio_request,
751 .zc_request = p9_virtio_zc_request, 768 .zc_request = p9_virtio_zc_request,
752 .cancel = p9_virtio_cancel, 769 .cancel = p9_virtio_cancel,
770 .cancelled = p9_virtio_cancelled,
753 /* 771 /*
754 * We leave one entry for input and one entry for response 772 * We leave one entry for input and one entry for response
755 * headers. We also skip one more entry to accomodate, address 773 * headers. We also skip one more entry to accomodate, address
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index c2d54ac76bfd..e2fbf3677b9b 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -141,7 +141,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
141 struct xen_9pfs_front_priv *priv = NULL; 141 struct xen_9pfs_front_priv *priv = NULL;
142 RING_IDX cons, prod, masked_cons, masked_prod; 142 RING_IDX cons, prod, masked_cons, masked_prod;
143 unsigned long flags; 143 unsigned long flags;
144 u32 size = p9_req->tc->size; 144 u32 size = p9_req->tc.size;
145 struct xen_9pfs_dataring *ring; 145 struct xen_9pfs_dataring *ring;
146 int num; 146 int num;
147 147
@@ -154,7 +154,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
154 if (!priv || priv->client != client) 154 if (!priv || priv->client != client)
155 return -EINVAL; 155 return -EINVAL;
156 156
157 num = p9_req->tc->tag % priv->num_rings; 157 num = p9_req->tc.tag % priv->num_rings;
158 ring = &priv->rings[num]; 158 ring = &priv->rings[num];
159 159
160again: 160again:
@@ -176,7 +176,7 @@ again:
176 masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE); 176 masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE);
177 masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); 177 masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
178 178
179 xen_9pfs_write_packet(ring->data.out, p9_req->tc->sdata, size, 179 xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size,
180 &masked_prod, masked_cons, XEN_9PFS_RING_SIZE); 180 &masked_prod, masked_cons, XEN_9PFS_RING_SIZE);
181 181
182 p9_req->status = REQ_STATUS_SENT; 182 p9_req->status = REQ_STATUS_SENT;
@@ -185,6 +185,7 @@ again:
185 ring->intf->out_prod = prod; 185 ring->intf->out_prod = prod;
186 spin_unlock_irqrestore(&ring->lock, flags); 186 spin_unlock_irqrestore(&ring->lock, flags);
187 notify_remote_via_irq(ring->irq); 187 notify_remote_via_irq(ring->irq);
188 p9_req_put(p9_req);
188 189
189 return 0; 190 return 0;
190} 191}
@@ -229,12 +230,12 @@ static void p9_xen_response(struct work_struct *work)
229 continue; 230 continue;
230 } 231 }
231 232
232 memcpy(req->rc, &h, sizeof(h)); 233 memcpy(&req->rc, &h, sizeof(h));
233 req->rc->offset = 0; 234 req->rc.offset = 0;
234 235
235 masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); 236 masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
236 /* Then, read the whole packet (including the header) */ 237 /* Then, read the whole packet (including the header) */
237 xen_9pfs_read_packet(req->rc->sdata, ring->data.in, h.size, 238 xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size,
238 masked_prod, &masked_cons, 239 masked_prod, &masked_cons,
239 XEN_9PFS_RING_SIZE); 240 XEN_9PFS_RING_SIZE);
240 241
@@ -391,8 +392,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
391 unsigned int max_rings, max_ring_order, len = 0; 392 unsigned int max_rings, max_ring_order, len = 0;
392 393
393 versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len); 394 versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
394 if (!len) 395 if (IS_ERR(versions))
395 return -EINVAL; 396 return PTR_ERR(versions);
396 if (strcmp(versions, "1")) { 397 if (strcmp(versions, "1")) {
397 kfree(versions); 398 kfree(versions);
398 return -EINVAL; 399 return -EINVAL;
diff --git a/net/9p/util.c b/net/9p/util.c
deleted file mode 100644
index 55ad98277e85..000000000000
--- a/net/9p/util.c
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 * net/9p/util.c
3 *
4 * This file contains some helper functions
5 *
6 * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/sched.h>
31#include <linux/parser.h>
32#include <linux/idr.h>
33#include <linux/slab.h>
34#include <net/9p/9p.h>
35
36/**
37 * struct p9_idpool - per-connection accounting for tag idpool
38 * @lock: protects the pool
39 * @pool: idr to allocate tag id from
40 *
41 */
42
43struct p9_idpool {
44 spinlock_t lock;
45 struct idr pool;
46};
47
48/**
49 * p9_idpool_create - create a new per-connection id pool
50 *
51 */
52
53struct p9_idpool *p9_idpool_create(void)
54{
55 struct p9_idpool *p;
56
57 p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
58 if (!p)
59 return ERR_PTR(-ENOMEM);
60
61 spin_lock_init(&p->lock);
62 idr_init(&p->pool);
63
64 return p;
65}
66EXPORT_SYMBOL(p9_idpool_create);
67
68/**
69 * p9_idpool_destroy - create a new per-connection id pool
70 * @p: idpool to destroy
71 */
72
73void p9_idpool_destroy(struct p9_idpool *p)
74{
75 idr_destroy(&p->pool);
76 kfree(p);
77}
78EXPORT_SYMBOL(p9_idpool_destroy);
79
80/**
81 * p9_idpool_get - allocate numeric id from pool
82 * @p: pool to allocate from
83 *
84 * Bugs: This seems to be an awful generic function, should it be in idr.c with
85 * the lock included in struct idr?
86 */
87
88int p9_idpool_get(struct p9_idpool *p)
89{
90 int i;
91 unsigned long flags;
92
93 idr_preload(GFP_NOFS);
94 spin_lock_irqsave(&p->lock, flags);
95
96 /* no need to store exactly p, we just need something non-null */
97 i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
98
99 spin_unlock_irqrestore(&p->lock, flags);
100 idr_preload_end();
101 if (i < 0)
102 return -1;
103
104 p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
105 return i;
106}
107EXPORT_SYMBOL(p9_idpool_get);
108
109/**
110 * p9_idpool_put - release numeric id from pool
111 * @id: numeric id which is being released
112 * @p: pool to release id into
113 *
114 * Bugs: This seems to be an awful generic function, should it be in idr.c with
115 * the lock included in struct idr?
116 */
117
118void p9_idpool_put(int id, struct p9_idpool *p)
119{
120 unsigned long flags;
121
122 p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
123
124 spin_lock_irqsave(&p->lock, flags);
125 idr_remove(&p->pool, id);
126 spin_unlock_irqrestore(&p->lock, flags);
127}
128EXPORT_SYMBOL(p9_idpool_put);
129
130/**
131 * p9_idpool_check - check if the specified id is available
132 * @id: id to check
133 * @p: pool to check
134 */
135
136int p9_idpool_check(int id, struct p9_idpool *p)
137{
138 return idr_find(&p->pool, id) != NULL;
139}
140EXPORT_SYMBOL(p9_idpool_check);