diff options
Diffstat (limited to 'fs/9p/v9fs.c')
-rw-r--r-- | fs/9p/v9fs.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 418c3743fdee..5250c428fc1f 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "v9fs_vfs.h" | 37 | #include "v9fs_vfs.h" |
38 | #include "transport.h" | 38 | #include "transport.h" |
39 | #include "mux.h" | 39 | #include "mux.h" |
40 | #include "conv.h" | ||
41 | 40 | ||
42 | /* TODO: sysfs or debugfs interface */ | 41 | /* TODO: sysfs or debugfs interface */ |
43 | int v9fs_debug_level = 0; /* feature-rific global debug level */ | 42 | int v9fs_debug_level = 0; /* feature-rific global debug level */ |
@@ -213,7 +212,8 @@ retry: | |||
213 | return -1; | 212 | return -1; |
214 | } | 213 | } |
215 | 214 | ||
216 | error = idr_get_new(&p->pool, NULL, &i); | 215 | /* no need to store exactly p, we just need something non-null */ |
216 | error = idr_get_new(&p->pool, p, &i); | ||
217 | up(&p->lock); | 217 | up(&p->lock); |
218 | 218 | ||
219 | if (error == -EAGAIN) | 219 | if (error == -EAGAIN) |
@@ -243,6 +243,16 @@ void v9fs_put_idpool(int id, struct v9fs_idpool *p) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | /** | 245 | /** |
246 | * v9fs_check_idpool - check if the specified id is available | ||
247 | * @id - id to check | ||
248 | * @p - pool | ||
249 | */ | ||
250 | int v9fs_check_idpool(int id, struct v9fs_idpool *p) | ||
251 | { | ||
252 | return idr_find(&p->pool, id) != NULL; | ||
253 | } | ||
254 | |||
255 | /** | ||
246 | * v9fs_session_init - initialize session | 256 | * v9fs_session_init - initialize session |
247 | * @v9ses: session information structure | 257 | * @v9ses: session information structure |
248 | * @dev_name: device being mounted | 258 | * @dev_name: device being mounted |
@@ -259,6 +269,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
259 | int n = 0; | 269 | int n = 0; |
260 | int newfid = -1; | 270 | int newfid = -1; |
261 | int retval = -EINVAL; | 271 | int retval = -EINVAL; |
272 | struct v9fs_str *version; | ||
262 | 273 | ||
263 | v9ses->name = __getname(); | 274 | v9ses->name = __getname(); |
264 | if (!v9ses->name) | 275 | if (!v9ses->name) |
@@ -281,9 +292,6 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
281 | /* id pools that are session-dependent: FIDs and TIDs */ | 292 | /* id pools that are session-dependent: FIDs and TIDs */ |
282 | idr_init(&v9ses->fidpool.pool); | 293 | idr_init(&v9ses->fidpool.pool); |
283 | init_MUTEX(&v9ses->fidpool.lock); | 294 | init_MUTEX(&v9ses->fidpool.lock); |
284 | idr_init(&v9ses->tidpool.pool); | ||
285 | init_MUTEX(&v9ses->tidpool.lock); | ||
286 | |||
287 | 295 | ||
288 | switch (v9ses->proto) { | 296 | switch (v9ses->proto) { |
289 | case PROTO_TCP: | 297 | case PROTO_TCP: |
@@ -320,7 +328,12 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
320 | v9ses->shutdown = 0; | 328 | v9ses->shutdown = 0; |
321 | v9ses->session_hung = 0; | 329 | v9ses->session_hung = 0; |
322 | 330 | ||
323 | if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) { | 331 | v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, |
332 | &v9ses->extended); | ||
333 | |||
334 | if (IS_ERR(v9ses->mux)) { | ||
335 | retval = PTR_ERR(v9ses->mux); | ||
336 | v9ses->mux = NULL; | ||
324 | dprintk(DEBUG_ERROR, "problem initializing mux\n"); | 337 | dprintk(DEBUG_ERROR, "problem initializing mux\n"); |
325 | goto SessCleanUp; | 338 | goto SessCleanUp; |
326 | } | 339 | } |
@@ -339,13 +352,16 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
339 | goto FreeFcall; | 352 | goto FreeFcall; |
340 | } | 353 | } |
341 | 354 | ||
342 | /* Really should check for 9P1 and report error */ | 355 | version = &fcall->params.rversion.version; |
343 | if (!strcmp(fcall->params.rversion.version, "9P2000.u")) { | 356 | if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { |
344 | dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); | 357 | dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); |
345 | v9ses->extended = 1; | 358 | v9ses->extended = 1; |
346 | } else { | 359 | } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { |
347 | dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); | 360 | dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); |
348 | v9ses->extended = 0; | 361 | v9ses->extended = 0; |
362 | } else { | ||
363 | retval = -EREMOTEIO; | ||
364 | goto FreeFcall; | ||
349 | } | 365 | } |
350 | 366 | ||
351 | n = fcall->params.rversion.msize; | 367 | n = fcall->params.rversion.msize; |
@@ -381,7 +397,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
381 | } | 397 | } |
382 | 398 | ||
383 | if (v9ses->afid != ~0) { | 399 | if (v9ses->afid != ~0) { |
384 | if (v9fs_t_clunk(v9ses, v9ses->afid, NULL)) | 400 | if (v9fs_t_clunk(v9ses, v9ses->afid)) |
385 | dprintk(DEBUG_ERROR, "clunk failed\n"); | 401 | dprintk(DEBUG_ERROR, "clunk failed\n"); |
386 | } | 402 | } |
387 | 403 | ||
@@ -403,13 +419,16 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
403 | 419 | ||
404 | void v9fs_session_close(struct v9fs_session_info *v9ses) | 420 | void v9fs_session_close(struct v9fs_session_info *v9ses) |
405 | { | 421 | { |
406 | if (v9ses->recvproc) { | 422 | if (v9ses->mux) { |
407 | send_sig(SIGKILL, v9ses->recvproc, 1); | 423 | v9fs_mux_destroy(v9ses->mux); |
408 | wait_for_completion(&v9ses->proccmpl); | 424 | v9ses->mux = NULL; |
409 | } | 425 | } |
410 | 426 | ||
411 | if (v9ses->transport) | 427 | if (v9ses->transport) { |
412 | v9ses->transport->close(v9ses->transport); | 428 | v9ses->transport->close(v9ses->transport); |
429 | kfree(v9ses->transport); | ||
430 | v9ses->transport = NULL; | ||
431 | } | ||
413 | 432 | ||
414 | __putname(v9ses->name); | 433 | __putname(v9ses->name); |
415 | __putname(v9ses->remotename); | 434 | __putname(v9ses->remotename); |
@@ -420,8 +439,9 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
420 | * and cancel all pending requests. | 439 | * and cancel all pending requests. |
421 | */ | 440 | */ |
422 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 441 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { |
442 | dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); | ||
423 | v9ses->transport->status = Disconnected; | 443 | v9ses->transport->status = Disconnected; |
424 | v9fs_mux_cancel_requests(v9ses, -EIO); | 444 | v9fs_mux_cancel(v9ses->mux, -EIO); |
425 | } | 445 | } |
426 | 446 | ||
427 | extern int v9fs_error_init(void); | 447 | extern int v9fs_error_init(void); |
@@ -433,11 +453,17 @@ extern int v9fs_error_init(void); | |||
433 | 453 | ||
434 | static int __init init_v9fs(void) | 454 | static int __init init_v9fs(void) |
435 | { | 455 | { |
456 | int ret; | ||
457 | |||
436 | v9fs_error_init(); | 458 | v9fs_error_init(); |
437 | 459 | ||
438 | printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); | 460 | printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); |
439 | 461 | ||
440 | return register_filesystem(&v9fs_fs_type); | 462 | ret = v9fs_mux_global_init(); |
463 | if (!ret) | ||
464 | ret = register_filesystem(&v9fs_fs_type); | ||
465 | |||
466 | return ret; | ||
441 | } | 467 | } |
442 | 468 | ||
443 | /** | 469 | /** |
@@ -447,6 +473,7 @@ static int __init init_v9fs(void) | |||
447 | 473 | ||
448 | static void __exit exit_v9fs(void) | 474 | static void __exit exit_v9fs(void) |
449 | { | 475 | { |
476 | v9fs_mux_global_exit(); | ||
450 | unregister_filesystem(&v9fs_fs_type); | 477 | unregister_filesystem(&v9fs_fs_type); |
451 | } | 478 | } |
452 | 479 | ||