aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-04-11 01:54:58 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-11 09:18:49 -0400
commitce1d5a491f0ee50560416a73faa5e4ddbab074bd (patch)
tree21f91d983b467ad05df0213f54fe00aad84e5761 /fs/fuse/inode.c
parenta87046d822f2d982d25b24c4a644d34f22d4888a (diff)
[PATCH] fuse: clean up request accounting
FUSE allocated most requests from a fixed size pool filled at mount time. However in some cases (release/forget) non-pool requests were used. File locking operations aren't well served by the request pool, since they may block indefinetly thus exhausting the pool. This patch removes the request pool and always allocates requests on demand. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c54
1 files changed, 15 insertions, 39 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index cc58debeabd4..824ebbc428ed 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -243,9 +243,9 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
243 struct fuse_statfs_out outarg; 243 struct fuse_statfs_out outarg;
244 int err; 244 int err;
245 245
246 req = fuse_get_request(fc); 246 req = fuse_get_req(fc);
247 if (!req) 247 if (IS_ERR(req))
248 return -EINTR; 248 return PTR_ERR(req);
249 249
250 memset(&outarg, 0, sizeof(outarg)); 250 memset(&outarg, 0, sizeof(outarg));
251 req->in.numargs = 0; 251 req->in.numargs = 0;
@@ -370,15 +370,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
370 370
371static void fuse_conn_release(struct kobject *kobj) 371static void fuse_conn_release(struct kobject *kobj)
372{ 372{
373 struct fuse_conn *fc = get_fuse_conn_kobj(kobj); 373 kfree(get_fuse_conn_kobj(kobj));
374
375 while (!list_empty(&fc->unused_list)) {
376 struct fuse_req *req;
377 req = list_entry(fc->unused_list.next, struct fuse_req, list);
378 list_del(&req->list);
379 fuse_request_free(req);
380 }
381 kfree(fc);
382} 374}
383 375
384static struct fuse_conn *new_conn(void) 376static struct fuse_conn *new_conn(void)
@@ -387,27 +379,16 @@ static struct fuse_conn *new_conn(void)
387 379
388 fc = kzalloc(sizeof(*fc), GFP_KERNEL); 380 fc = kzalloc(sizeof(*fc), GFP_KERNEL);
389 if (fc) { 381 if (fc) {
390 int i;
391 spin_lock_init(&fc->lock); 382 spin_lock_init(&fc->lock);
392 init_waitqueue_head(&fc->waitq); 383 init_waitqueue_head(&fc->waitq);
393 INIT_LIST_HEAD(&fc->pending); 384 INIT_LIST_HEAD(&fc->pending);
394 INIT_LIST_HEAD(&fc->processing); 385 INIT_LIST_HEAD(&fc->processing);
395 INIT_LIST_HEAD(&fc->io); 386 INIT_LIST_HEAD(&fc->io);
396 INIT_LIST_HEAD(&fc->unused_list);
397 INIT_LIST_HEAD(&fc->background); 387 INIT_LIST_HEAD(&fc->background);
398 sema_init(&fc->outstanding_sem, 1); /* One for INIT */
399 init_rwsem(&fc->sbput_sem); 388 init_rwsem(&fc->sbput_sem);
400 kobj_set_kset_s(fc, connections_subsys); 389 kobj_set_kset_s(fc, connections_subsys);
401 kobject_init(&fc->kobj); 390 kobject_init(&fc->kobj);
402 atomic_set(&fc->num_waiting, 0); 391 atomic_set(&fc->num_waiting, 0);
403 for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
404 struct fuse_req *req = fuse_request_alloc();
405 if (!req) {
406 kobject_put(&fc->kobj);
407 return NULL;
408 }
409 list_add(&req->list, &fc->unused_list);
410 }
411 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 392 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
412 fc->bdi.unplug_io_fn = default_unplug_io_fn; 393 fc->bdi.unplug_io_fn = default_unplug_io_fn;
413 fc->reqctr = 0; 394 fc->reqctr = 0;
@@ -438,7 +419,6 @@ static struct super_operations fuse_super_operations = {
438 419
439static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) 420static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
440{ 421{
441 int i;
442 struct fuse_init_out *arg = &req->misc.init_out; 422 struct fuse_init_out *arg = &req->misc.init_out;
443 423
444 if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) 424 if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION)
@@ -457,22 +437,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
457 fc->minor = arg->minor; 437 fc->minor = arg->minor;
458 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; 438 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
459 } 439 }
460
461 /* After INIT reply is received other requests can go
462 out. So do (FUSE_MAX_OUTSTANDING - 1) number of
463 up()s on outstanding_sem. The last up() is done in
464 fuse_putback_request() */
465 for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
466 up(&fc->outstanding_sem);
467
468 fuse_put_request(fc, req); 440 fuse_put_request(fc, req);
469} 441}
470 442
471static void fuse_send_init(struct fuse_conn *fc) 443static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
472{ 444{
473 /* This is called from fuse_read_super() so there's guaranteed
474 to be exactly one request available */
475 struct fuse_req *req = fuse_get_request(fc);
476 struct fuse_init_in *arg = &req->misc.init_in; 445 struct fuse_init_in *arg = &req->misc.init_in;
477 446
478 arg->major = FUSE_KERNEL_VERSION; 447 arg->major = FUSE_KERNEL_VERSION;
@@ -508,6 +477,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
508 struct fuse_mount_data d; 477 struct fuse_mount_data d;
509 struct file *file; 478 struct file *file;
510 struct dentry *root_dentry; 479 struct dentry *root_dentry;
480 struct fuse_req *init_req;
511 int err; 481 int err;
512 482
513 if (!parse_fuse_opt((char *) data, &d)) 483 if (!parse_fuse_opt((char *) data, &d))
@@ -554,13 +524,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
554 goto err; 524 goto err;
555 } 525 }
556 526
527 init_req = fuse_request_alloc();
528 if (!init_req)
529 goto err_put_root;
530
557 err = kobject_set_name(&fc->kobj, "%llu", conn_id()); 531 err = kobject_set_name(&fc->kobj, "%llu", conn_id());
558 if (err) 532 if (err)
559 goto err_put_root; 533 goto err_free_req;
560 534
561 err = kobject_add(&fc->kobj); 535 err = kobject_add(&fc->kobj);
562 if (err) 536 if (err)
563 goto err_put_root; 537 goto err_free_req;
564 538
565 sb->s_root = root_dentry; 539 sb->s_root = root_dentry;
566 fc->mounted = 1; 540 fc->mounted = 1;
@@ -574,10 +548,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
574 */ 548 */
575 fput(file); 549 fput(file);
576 550
577 fuse_send_init(fc); 551 fuse_send_init(fc, init_req);
578 552
579 return 0; 553 return 0;
580 554
555 err_free_req:
556 fuse_request_free(init_req);
581 err_put_root: 557 err_put_root:
582 dput(root_dentry); 558 dput(root_dentry);
583 err: 559 err: