diff options
-rw-r--r-- | fs/fuse/file.c | 9 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 3 | ||||
-rw-r--r-- | fs/fuse/inode.c | 14 | ||||
-rw-r--r-- | include/linux/fuse.h | 16 |
4 files changed, 36 insertions, 6 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a7ef5e716f3c..296351615b00 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -335,9 +335,14 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file, | |||
335 | loff_t pos = page_offset(req->pages[0]); | 335 | loff_t pos = page_offset(req->pages[0]); |
336 | size_t count = req->num_pages << PAGE_CACHE_SHIFT; | 336 | size_t count = req->num_pages << PAGE_CACHE_SHIFT; |
337 | req->out.page_zeroing = 1; | 337 | req->out.page_zeroing = 1; |
338 | req->end = fuse_readpages_end; | ||
339 | fuse_read_fill(req, file, inode, pos, count, FUSE_READ); | 338 | fuse_read_fill(req, file, inode, pos, count, FUSE_READ); |
340 | request_send_background(fc, req); | 339 | if (fc->async_read) { |
340 | req->end = fuse_readpages_end; | ||
341 | request_send_background(fc, req); | ||
342 | } else { | ||
343 | request_send(fc, req); | ||
344 | fuse_readpages_end(fc, req); | ||
345 | } | ||
341 | } | 346 | } |
342 | 347 | ||
343 | struct fuse_readpages_data { | 348 | struct fuse_readpages_data { |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 46cf933aa3bf..4a83adfec968 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -272,6 +272,9 @@ struct fuse_conn { | |||
272 | reply, before any other request, and never cleared */ | 272 | reply, before any other request, and never cleared */ |
273 | unsigned conn_error : 1; | 273 | unsigned conn_error : 1; |
274 | 274 | ||
275 | /** Do readpages asynchronously? Only set in INIT */ | ||
276 | unsigned async_read : 1; | ||
277 | |||
275 | /* | 278 | /* |
276 | * The following bitfields are only for optimization purposes | 279 | * The following bitfields are only for optimization purposes |
277 | * and hence races in setting them will not cause malfunction | 280 | * and hence races in setting them will not cause malfunction |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index c755a0440a66..879e6fba9480 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -473,6 +473,16 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
473 | if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) | 473 | if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) |
474 | fc->conn_error = 1; | 474 | fc->conn_error = 1; |
475 | else { | 475 | else { |
476 | unsigned long ra_pages; | ||
477 | |||
478 | if (arg->minor >= 6) { | ||
479 | ra_pages = arg->max_readahead / PAGE_CACHE_SIZE; | ||
480 | if (arg->flags & FUSE_ASYNC_READ) | ||
481 | fc->async_read = 1; | ||
482 | } else | ||
483 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | ||
484 | |||
485 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | ||
476 | fc->minor = arg->minor; | 486 | fc->minor = arg->minor; |
477 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 487 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
478 | } | 488 | } |
@@ -496,6 +506,8 @@ static void fuse_send_init(struct fuse_conn *fc) | |||
496 | 506 | ||
497 | arg->major = FUSE_KERNEL_VERSION; | 507 | arg->major = FUSE_KERNEL_VERSION; |
498 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | 508 | arg->minor = FUSE_KERNEL_MINOR_VERSION; |
509 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; | ||
510 | arg->flags |= FUSE_ASYNC_READ; | ||
499 | req->in.h.opcode = FUSE_INIT; | 511 | req->in.h.opcode = FUSE_INIT; |
500 | req->in.numargs = 1; | 512 | req->in.numargs = 1; |
501 | req->in.args[0].size = sizeof(*arg); | 513 | req->in.args[0].size = sizeof(*arg); |
@@ -552,8 +564,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
552 | fc->user_id = d.user_id; | 564 | fc->user_id = d.user_id; |
553 | fc->group_id = d.group_id; | 565 | fc->group_id = d.group_id; |
554 | fc->max_read = d.max_read; | 566 | fc->max_read = d.max_read; |
555 | if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) | ||
556 | fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; | ||
557 | 567 | ||
558 | /* Used by get_root_inode() */ | 568 | /* Used by get_root_inode() */ |
559 | sb->s_fs_info = fc; | 569 | sb->s_fs_info = fc; |
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 528959c52f1b..5425b60021e3 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #define FUSE_KERNEL_VERSION 7 | 14 | #define FUSE_KERNEL_VERSION 7 |
15 | 15 | ||
16 | /** Minor version number of this interface */ | 16 | /** Minor version number of this interface */ |
17 | #define FUSE_KERNEL_MINOR_VERSION 5 | 17 | #define FUSE_KERNEL_MINOR_VERSION 6 |
18 | 18 | ||
19 | /** The node ID of the root inode */ | 19 | /** The node ID of the root inode */ |
20 | #define FUSE_ROOT_ID 1 | 20 | #define FUSE_ROOT_ID 1 |
@@ -58,6 +58,9 @@ struct fuse_kstatfs { | |||
58 | __u32 spare[6]; | 58 | __u32 spare[6]; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /** | ||
62 | * Bitmasks for fuse_setattr_in.valid | ||
63 | */ | ||
61 | #define FATTR_MODE (1 << 0) | 64 | #define FATTR_MODE (1 << 0) |
62 | #define FATTR_UID (1 << 1) | 65 | #define FATTR_UID (1 << 1) |
63 | #define FATTR_GID (1 << 2) | 66 | #define FATTR_GID (1 << 2) |
@@ -75,6 +78,11 @@ struct fuse_kstatfs { | |||
75 | #define FOPEN_DIRECT_IO (1 << 0) | 78 | #define FOPEN_DIRECT_IO (1 << 0) |
76 | #define FOPEN_KEEP_CACHE (1 << 1) | 79 | #define FOPEN_KEEP_CACHE (1 << 1) |
77 | 80 | ||
81 | /** | ||
82 | * INIT request/reply flags | ||
83 | */ | ||
84 | #define FUSE_ASYNC_READ (1 << 0) | ||
85 | |||
78 | enum fuse_opcode { | 86 | enum fuse_opcode { |
79 | FUSE_LOOKUP = 1, | 87 | FUSE_LOOKUP = 1, |
80 | FUSE_FORGET = 2, /* no reply */ | 88 | FUSE_FORGET = 2, /* no reply */ |
@@ -247,12 +255,16 @@ struct fuse_access_in { | |||
247 | struct fuse_init_in { | 255 | struct fuse_init_in { |
248 | __u32 major; | 256 | __u32 major; |
249 | __u32 minor; | 257 | __u32 minor; |
258 | __u32 max_readahead; | ||
259 | __u32 flags; | ||
250 | }; | 260 | }; |
251 | 261 | ||
252 | struct fuse_init_out { | 262 | struct fuse_init_out { |
253 | __u32 major; | 263 | __u32 major; |
254 | __u32 minor; | 264 | __u32 minor; |
255 | __u32 unused[3]; | 265 | __u32 max_readahead; |
266 | __u32 flags; | ||
267 | __u32 unused; | ||
256 | __u32 max_write; | 268 | __u32 max_write; |
257 | }; | 269 | }; |
258 | 270 | ||