diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-04-11 01:54:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:49 -0400 |
commit | ce1d5a491f0ee50560416a73faa5e4ddbab074bd (patch) | |
tree | 21f91d983b467ad05df0213f54fe00aad84e5761 /fs/fuse/dir.c | |
parent | a87046d822f2d982d25b24c4a644d34f22d4888a (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/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 118 |
1 files changed, 58 insertions, 60 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 256355b80256..8d7546e832e8 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -117,8 +117,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
117 | return 0; | 117 | return 0; |
118 | 118 | ||
119 | fc = get_fuse_conn(inode); | 119 | fc = get_fuse_conn(inode); |
120 | req = fuse_get_request(fc); | 120 | req = fuse_get_req(fc); |
121 | if (!req) | 121 | if (IS_ERR(req)) |
122 | return 0; | 122 | return 0; |
123 | 123 | ||
124 | fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); | 124 | fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); |
@@ -188,9 +188,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
188 | if (entry->d_name.len > FUSE_NAME_MAX) | 188 | if (entry->d_name.len > FUSE_NAME_MAX) |
189 | return ERR_PTR(-ENAMETOOLONG); | 189 | return ERR_PTR(-ENAMETOOLONG); |
190 | 190 | ||
191 | req = fuse_get_request(fc); | 191 | req = fuse_get_req(fc); |
192 | if (!req) | 192 | if (IS_ERR(req)) |
193 | return ERR_PTR(-EINTR); | 193 | return ERR_PTR(PTR_ERR(req)); |
194 | 194 | ||
195 | fuse_lookup_init(req, dir, entry, &outarg); | 195 | fuse_lookup_init(req, dir, entry, &outarg); |
196 | request_send(fc, req); | 196 | request_send(fc, req); |
@@ -244,15 +244,14 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
244 | struct file *file; | 244 | struct file *file; |
245 | int flags = nd->intent.open.flags - 1; | 245 | int flags = nd->intent.open.flags - 1; |
246 | 246 | ||
247 | err = -ENOSYS; | ||
248 | if (fc->no_create) | 247 | if (fc->no_create) |
249 | goto out; | 248 | return -ENOSYS; |
250 | 249 | ||
251 | err = -EINTR; | 250 | req = fuse_get_req(fc); |
252 | req = fuse_get_request(fc); | 251 | if (IS_ERR(req)) |
253 | if (!req) | 252 | return PTR_ERR(req); |
254 | goto out; | ||
255 | 253 | ||
254 | err = -ENOMEM; | ||
256 | ff = fuse_file_alloc(); | 255 | ff = fuse_file_alloc(); |
257 | if (!ff) | 256 | if (!ff) |
258 | goto out_put_request; | 257 | goto out_put_request; |
@@ -314,7 +313,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
314 | fuse_file_free(ff); | 313 | fuse_file_free(ff); |
315 | out_put_request: | 314 | out_put_request: |
316 | fuse_put_request(fc, req); | 315 | fuse_put_request(fc, req); |
317 | out: | ||
318 | return err; | 316 | return err; |
319 | } | 317 | } |
320 | 318 | ||
@@ -375,9 +373,9 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode, | |||
375 | { | 373 | { |
376 | struct fuse_mknod_in inarg; | 374 | struct fuse_mknod_in inarg; |
377 | struct fuse_conn *fc = get_fuse_conn(dir); | 375 | struct fuse_conn *fc = get_fuse_conn(dir); |
378 | struct fuse_req *req = fuse_get_request(fc); | 376 | struct fuse_req *req = fuse_get_req(fc); |
379 | if (!req) | 377 | if (IS_ERR(req)) |
380 | return -EINTR; | 378 | return PTR_ERR(req); |
381 | 379 | ||
382 | memset(&inarg, 0, sizeof(inarg)); | 380 | memset(&inarg, 0, sizeof(inarg)); |
383 | inarg.mode = mode; | 381 | inarg.mode = mode; |
@@ -407,9 +405,9 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode) | |||
407 | { | 405 | { |
408 | struct fuse_mkdir_in inarg; | 406 | struct fuse_mkdir_in inarg; |
409 | struct fuse_conn *fc = get_fuse_conn(dir); | 407 | struct fuse_conn *fc = get_fuse_conn(dir); |
410 | struct fuse_req *req = fuse_get_request(fc); | 408 | struct fuse_req *req = fuse_get_req(fc); |
411 | if (!req) | 409 | if (IS_ERR(req)) |
412 | return -EINTR; | 410 | return PTR_ERR(req); |
413 | 411 | ||
414 | memset(&inarg, 0, sizeof(inarg)); | 412 | memset(&inarg, 0, sizeof(inarg)); |
415 | inarg.mode = mode; | 413 | inarg.mode = mode; |
@@ -427,9 +425,9 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry, | |||
427 | { | 425 | { |
428 | struct fuse_conn *fc = get_fuse_conn(dir); | 426 | struct fuse_conn *fc = get_fuse_conn(dir); |
429 | unsigned len = strlen(link) + 1; | 427 | unsigned len = strlen(link) + 1; |
430 | struct fuse_req *req = fuse_get_request(fc); | 428 | struct fuse_req *req = fuse_get_req(fc); |
431 | if (!req) | 429 | if (IS_ERR(req)) |
432 | return -EINTR; | 430 | return PTR_ERR(req); |
433 | 431 | ||
434 | req->in.h.opcode = FUSE_SYMLINK; | 432 | req->in.h.opcode = FUSE_SYMLINK; |
435 | req->in.numargs = 2; | 433 | req->in.numargs = 2; |
@@ -444,9 +442,9 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) | |||
444 | { | 442 | { |
445 | int err; | 443 | int err; |
446 | struct fuse_conn *fc = get_fuse_conn(dir); | 444 | struct fuse_conn *fc = get_fuse_conn(dir); |
447 | struct fuse_req *req = fuse_get_request(fc); | 445 | struct fuse_req *req = fuse_get_req(fc); |
448 | if (!req) | 446 | if (IS_ERR(req)) |
449 | return -EINTR; | 447 | return PTR_ERR(req); |
450 | 448 | ||
451 | req->in.h.opcode = FUSE_UNLINK; | 449 | req->in.h.opcode = FUSE_UNLINK; |
452 | req->in.h.nodeid = get_node_id(dir); | 450 | req->in.h.nodeid = get_node_id(dir); |
@@ -476,9 +474,9 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
476 | { | 474 | { |
477 | int err; | 475 | int err; |
478 | struct fuse_conn *fc = get_fuse_conn(dir); | 476 | struct fuse_conn *fc = get_fuse_conn(dir); |
479 | struct fuse_req *req = fuse_get_request(fc); | 477 | struct fuse_req *req = fuse_get_req(fc); |
480 | if (!req) | 478 | if (IS_ERR(req)) |
481 | return -EINTR; | 479 | return PTR_ERR(req); |
482 | 480 | ||
483 | req->in.h.opcode = FUSE_RMDIR; | 481 | req->in.h.opcode = FUSE_RMDIR; |
484 | req->in.h.nodeid = get_node_id(dir); | 482 | req->in.h.nodeid = get_node_id(dir); |
@@ -504,9 +502,9 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
504 | int err; | 502 | int err; |
505 | struct fuse_rename_in inarg; | 503 | struct fuse_rename_in inarg; |
506 | struct fuse_conn *fc = get_fuse_conn(olddir); | 504 | struct fuse_conn *fc = get_fuse_conn(olddir); |
507 | struct fuse_req *req = fuse_get_request(fc); | 505 | struct fuse_req *req = fuse_get_req(fc); |
508 | if (!req) | 506 | if (IS_ERR(req)) |
509 | return -EINTR; | 507 | return PTR_ERR(req); |
510 | 508 | ||
511 | memset(&inarg, 0, sizeof(inarg)); | 509 | memset(&inarg, 0, sizeof(inarg)); |
512 | inarg.newdir = get_node_id(newdir); | 510 | inarg.newdir = get_node_id(newdir); |
@@ -553,9 +551,9 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
553 | struct fuse_link_in inarg; | 551 | struct fuse_link_in inarg; |
554 | struct inode *inode = entry->d_inode; | 552 | struct inode *inode = entry->d_inode; |
555 | struct fuse_conn *fc = get_fuse_conn(inode); | 553 | struct fuse_conn *fc = get_fuse_conn(inode); |
556 | struct fuse_req *req = fuse_get_request(fc); | 554 | struct fuse_req *req = fuse_get_req(fc); |
557 | if (!req) | 555 | if (IS_ERR(req)) |
558 | return -EINTR; | 556 | return PTR_ERR(req); |
559 | 557 | ||
560 | memset(&inarg, 0, sizeof(inarg)); | 558 | memset(&inarg, 0, sizeof(inarg)); |
561 | inarg.oldnodeid = get_node_id(inode); | 559 | inarg.oldnodeid = get_node_id(inode); |
@@ -583,9 +581,9 @@ int fuse_do_getattr(struct inode *inode) | |||
583 | int err; | 581 | int err; |
584 | struct fuse_attr_out arg; | 582 | struct fuse_attr_out arg; |
585 | struct fuse_conn *fc = get_fuse_conn(inode); | 583 | struct fuse_conn *fc = get_fuse_conn(inode); |
586 | struct fuse_req *req = fuse_get_request(fc); | 584 | struct fuse_req *req = fuse_get_req(fc); |
587 | if (!req) | 585 | if (IS_ERR(req)) |
588 | return -EINTR; | 586 | return PTR_ERR(req); |
589 | 587 | ||
590 | req->in.h.opcode = FUSE_GETATTR; | 588 | req->in.h.opcode = FUSE_GETATTR; |
591 | req->in.h.nodeid = get_node_id(inode); | 589 | req->in.h.nodeid = get_node_id(inode); |
@@ -673,9 +671,9 @@ static int fuse_access(struct inode *inode, int mask) | |||
673 | if (fc->no_access) | 671 | if (fc->no_access) |
674 | return 0; | 672 | return 0; |
675 | 673 | ||
676 | req = fuse_get_request(fc); | 674 | req = fuse_get_req(fc); |
677 | if (!req) | 675 | if (IS_ERR(req)) |
678 | return -EINTR; | 676 | return PTR_ERR(req); |
679 | 677 | ||
680 | memset(&inarg, 0, sizeof(inarg)); | 678 | memset(&inarg, 0, sizeof(inarg)); |
681 | inarg.mask = mask; | 679 | inarg.mask = mask; |
@@ -780,9 +778,9 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
780 | if (is_bad_inode(inode)) | 778 | if (is_bad_inode(inode)) |
781 | return -EIO; | 779 | return -EIO; |
782 | 780 | ||
783 | req = fuse_get_request(fc); | 781 | req = fuse_get_req(fc); |
784 | if (!req) | 782 | if (IS_ERR(req)) |
785 | return -EINTR; | 783 | return PTR_ERR(req); |
786 | 784 | ||
787 | page = alloc_page(GFP_KERNEL); | 785 | page = alloc_page(GFP_KERNEL); |
788 | if (!page) { | 786 | if (!page) { |
@@ -809,11 +807,11 @@ static char *read_link(struct dentry *dentry) | |||
809 | { | 807 | { |
810 | struct inode *inode = dentry->d_inode; | 808 | struct inode *inode = dentry->d_inode; |
811 | struct fuse_conn *fc = get_fuse_conn(inode); | 809 | struct fuse_conn *fc = get_fuse_conn(inode); |
812 | struct fuse_req *req = fuse_get_request(fc); | 810 | struct fuse_req *req = fuse_get_req(fc); |
813 | char *link; | 811 | char *link; |
814 | 812 | ||
815 | if (!req) | 813 | if (IS_ERR(req)) |
816 | return ERR_PTR(-EINTR); | 814 | return ERR_PTR(PTR_ERR(req)); |
817 | 815 | ||
818 | link = (char *) __get_free_page(GFP_KERNEL); | 816 | link = (char *) __get_free_page(GFP_KERNEL); |
819 | if (!link) { | 817 | if (!link) { |
@@ -933,9 +931,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
933 | } | 931 | } |
934 | } | 932 | } |
935 | 933 | ||
936 | req = fuse_get_request(fc); | 934 | req = fuse_get_req(fc); |
937 | if (!req) | 935 | if (IS_ERR(req)) |
938 | return -EINTR; | 936 | return PTR_ERR(req); |
939 | 937 | ||
940 | memset(&inarg, 0, sizeof(inarg)); | 938 | memset(&inarg, 0, sizeof(inarg)); |
941 | iattr_to_fattr(attr, &inarg); | 939 | iattr_to_fattr(attr, &inarg); |
@@ -995,9 +993,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name, | |||
995 | if (fc->no_setxattr) | 993 | if (fc->no_setxattr) |
996 | return -EOPNOTSUPP; | 994 | return -EOPNOTSUPP; |
997 | 995 | ||
998 | req = fuse_get_request(fc); | 996 | req = fuse_get_req(fc); |
999 | if (!req) | 997 | if (IS_ERR(req)) |
1000 | return -EINTR; | 998 | return PTR_ERR(req); |
1001 | 999 | ||
1002 | memset(&inarg, 0, sizeof(inarg)); | 1000 | memset(&inarg, 0, sizeof(inarg)); |
1003 | inarg.size = size; | 1001 | inarg.size = size; |
@@ -1035,9 +1033,9 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name, | |||
1035 | if (fc->no_getxattr) | 1033 | if (fc->no_getxattr) |
1036 | return -EOPNOTSUPP; | 1034 | return -EOPNOTSUPP; |
1037 | 1035 | ||
1038 | req = fuse_get_request(fc); | 1036 | req = fuse_get_req(fc); |
1039 | if (!req) | 1037 | if (IS_ERR(req)) |
1040 | return -EINTR; | 1038 | return PTR_ERR(req); |
1041 | 1039 | ||
1042 | memset(&inarg, 0, sizeof(inarg)); | 1040 | memset(&inarg, 0, sizeof(inarg)); |
1043 | inarg.size = size; | 1041 | inarg.size = size; |
@@ -1085,9 +1083,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) | |||
1085 | if (fc->no_listxattr) | 1083 | if (fc->no_listxattr) |
1086 | return -EOPNOTSUPP; | 1084 | return -EOPNOTSUPP; |
1087 | 1085 | ||
1088 | req = fuse_get_request(fc); | 1086 | req = fuse_get_req(fc); |
1089 | if (!req) | 1087 | if (IS_ERR(req)) |
1090 | return -EINTR; | 1088 | return PTR_ERR(req); |
1091 | 1089 | ||
1092 | memset(&inarg, 0, sizeof(inarg)); | 1090 | memset(&inarg, 0, sizeof(inarg)); |
1093 | inarg.size = size; | 1091 | inarg.size = size; |
@@ -1131,9 +1129,9 @@ static int fuse_removexattr(struct dentry *entry, const char *name) | |||
1131 | if (fc->no_removexattr) | 1129 | if (fc->no_removexattr) |
1132 | return -EOPNOTSUPP; | 1130 | return -EOPNOTSUPP; |
1133 | 1131 | ||
1134 | req = fuse_get_request(fc); | 1132 | req = fuse_get_req(fc); |
1135 | if (!req) | 1133 | if (IS_ERR(req)) |
1136 | return -EINTR; | 1134 | return PTR_ERR(req); |
1137 | 1135 | ||
1138 | req->in.h.opcode = FUSE_REMOVEXATTR; | 1136 | req->in.h.opcode = FUSE_REMOVEXATTR; |
1139 | req->in.h.nodeid = get_node_id(inode); | 1137 | req->in.h.nodeid = get_node_id(inode); |