diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2009-07-16 11:07:31 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2009-07-16 11:07:31 +0000 |
commit | 3846394e7ad0a85a0eee3346444befa81f4425af (patch) | |
tree | 2a5fbdf198100bc6d7f92f9dca46ba62cbebad9f /lib | |
parent | 37a90f29e8609951a18e5190d1fd3659e3aee135 (diff) |
* Clarify how the protocol version should be negotiated between
kernel and userspace. Notably libfuse didn't correctly handle the
case when the supported major versions didn't match
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse_lowlevel.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 32b9db3..c0347b3 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1150,7 +1150,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) (void) nodeid; if (f->debug) { fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); - if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { + if (arg->major == 7 && arg->minor >= 6) { fprintf(stderr, "flags=0x%08x\n", arg->flags); fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead); @@ -1161,6 +1161,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.capable = 0; f->conn.want = 0; + memset(&outarg, 0, sizeof(outarg)); + outarg.major = FUSE_KERNEL_VERSION; + outarg.minor = FUSE_KERNEL_MINOR_VERSION; + if (arg->major < 7) { fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); @@ -1168,7 +1172,13 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) return; } - if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { + if (arg->major > 7) { + /* Wait for a second INIT request with a 7.X version */ + send_reply_ok(req, &outarg, sizeof(outarg)); + return; + } + + if (arg->minor >= 6) { if (f->conn.async_read) f->conn.async_read = arg->flags & FUSE_ASYNC_READ; if (arg->max_readahead < f->conn.max_readahead) @@ -1211,9 +1221,6 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) if (f->op.init) f->op.init(f->userdata, &f->conn); - memset(&outarg, 0, sizeof(outarg)); - outarg.major = FUSE_KERNEL_VERSION; - outarg.minor = FUSE_KERNEL_MINOR_VERSION; if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ)) outarg.flags |= FUSE_ASYNC_READ; if (f->conn.want & FUSE_CAP_POSIX_LOCKS) |