diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-01-17 01:14:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-17 02:15:30 -0500 |
commit | 0cd5b88553acf0611474dbaf8e43770eed268060 (patch) | |
tree | f3b08ab3a4a1cb42d92e2997f60f30d945601600 /fs/fuse | |
parent | f543f253f3aa721a24557d7df8259145bb01b734 (diff) |
[PATCH] fuse: add number of waiting requests attribute
This patch adds the 'waiting' attribute which indicates how many filesystem
requests are currently waiting to be completed. A non-zero value without any
filesystem activity indicates a hung or deadlocked filesystem.
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')
-rw-r--r-- | fs/fuse/dev.c | 12 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 3 | ||||
-rw-r--r-- | fs/fuse/inode.c | 9 |
3 files changed, 21 insertions, 3 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index de4a0a0bda8a..c72e44b58d09 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -109,18 +109,24 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc) | |||
109 | int intr; | 109 | int intr; |
110 | sigset_t oldset; | 110 | sigset_t oldset; |
111 | 111 | ||
112 | atomic_inc(&fc->num_waiting); | ||
112 | block_sigs(&oldset); | 113 | block_sigs(&oldset); |
113 | intr = down_interruptible(&fc->outstanding_sem); | 114 | intr = down_interruptible(&fc->outstanding_sem); |
114 | restore_sigs(&oldset); | 115 | restore_sigs(&oldset); |
115 | return intr ? NULL : do_get_request(fc); | 116 | if (intr) { |
117 | atomic_dec(&fc->num_waiting); | ||
118 | return NULL; | ||
119 | } | ||
120 | return do_get_request(fc); | ||
116 | } | 121 | } |
117 | 122 | ||
118 | static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) | 123 | static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) |
119 | { | 124 | { |
120 | spin_lock(&fuse_lock); | 125 | spin_lock(&fuse_lock); |
121 | if (req->preallocated) | 126 | if (req->preallocated) { |
127 | atomic_dec(&fc->num_waiting); | ||
122 | list_add(&req->list, &fc->unused_list); | 128 | list_add(&req->list, &fc->unused_list); |
123 | else | 129 | } else |
124 | fuse_request_free(req); | 130 | fuse_request_free(req); |
125 | 131 | ||
126 | /* If we are in debt decrease that first */ | 132 | /* If we are in debt decrease that first */ |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6ef1e5f5873b..bcb453f68111 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -280,6 +280,9 @@ struct fuse_conn { | |||
280 | /** Is create not implemented by fs? */ | 280 | /** Is create not implemented by fs? */ |
281 | unsigned no_create : 1; | 281 | unsigned no_create : 1; |
282 | 282 | ||
283 | /** The number of requests waiting for completion */ | ||
284 | atomic_t num_waiting; | ||
285 | |||
283 | /** Negotiated minor version */ | 286 | /** Negotiated minor version */ |
284 | unsigned minor; | 287 | unsigned minor; |
285 | 288 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 514b700c863d..182235923cdd 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -555,7 +555,16 @@ static struct file_system_type fuse_fs_type = { | |||
555 | .kill_sb = kill_anon_super, | 555 | .kill_sb = kill_anon_super, |
556 | }; | 556 | }; |
557 | 557 | ||
558 | static ssize_t fuse_conn_waiting_show(struct fuse_conn *fc, char *page) | ||
559 | { | ||
560 | return sprintf(page, "%i\n", atomic_read(&fc->num_waiting)); | ||
561 | } | ||
562 | |||
563 | static struct fuse_conn_attr fuse_conn_waiting = | ||
564 | __ATTR(waiting, 0400, fuse_conn_waiting_show, NULL); | ||
565 | |||
558 | static struct attribute *fuse_conn_attrs[] = { | 566 | static struct attribute *fuse_conn_attrs[] = { |
567 | &fuse_conn_waiting.attr, | ||
559 | NULL, | 568 | NULL, |
560 | }; | 569 | }; |
561 | 570 | ||