diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d359d8de22a4..8683e7254d53 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -464,6 +464,51 @@ static struct super_operations fuse_super_operations = { | |||
464 | .show_options = fuse_show_options, | 464 | .show_options = fuse_show_options, |
465 | }; | 465 | }; |
466 | 466 | ||
467 | static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | ||
468 | { | ||
469 | int i; | ||
470 | struct fuse_init_out *arg = &req->misc.init_out; | ||
471 | |||
472 | if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) | ||
473 | fc->conn_error = 1; | ||
474 | else { | ||
475 | fc->minor = arg->minor; | ||
476 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | ||
477 | } | ||
478 | |||
479 | /* After INIT reply is received other requests can go | ||
480 | out. So do (FUSE_MAX_OUTSTANDING - 1) number of | ||
481 | up()s on outstanding_sem. The last up() is done in | ||
482 | fuse_putback_request() */ | ||
483 | for (i = 1; i < FUSE_MAX_OUTSTANDING; i++) | ||
484 | up(&fc->outstanding_sem); | ||
485 | |||
486 | fuse_put_request(fc, req); | ||
487 | } | ||
488 | |||
489 | static void fuse_send_init(struct fuse_conn *fc) | ||
490 | { | ||
491 | /* This is called from fuse_read_super() so there's guaranteed | ||
492 | to be exactly one request available */ | ||
493 | struct fuse_req *req = fuse_get_request(fc); | ||
494 | struct fuse_init_in *arg = &req->misc.init_in; | ||
495 | arg->major = FUSE_KERNEL_VERSION; | ||
496 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | ||
497 | req->in.h.opcode = FUSE_INIT; | ||
498 | req->in.numargs = 1; | ||
499 | req->in.args[0].size = sizeof(*arg); | ||
500 | req->in.args[0].value = arg; | ||
501 | req->out.numargs = 1; | ||
502 | /* Variable length arguement used for backward compatibility | ||
503 | with interface version < 7.5. Rest of init_out is zeroed | ||
504 | by do_get_request(), so a short reply is not a problem */ | ||
505 | req->out.argvar = 1; | ||
506 | req->out.args[0].size = sizeof(struct fuse_init_out); | ||
507 | req->out.args[0].value = &req->misc.init_out; | ||
508 | req->end = process_init_reply; | ||
509 | request_send_background(fc, req); | ||
510 | } | ||
511 | |||
467 | static unsigned long long conn_id(void) | 512 | static unsigned long long conn_id(void) |
468 | { | 513 | { |
469 | static unsigned long long ctr = 1; | 514 | static unsigned long long ctr = 1; |