diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-01-16 22:14:38 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-16 23:15:30 -0800 |
commit | 0cd5b88553acf0611474dbaf8e43770eed268060 (patch) | |
tree | f3b08ab3a4a1cb42d92e2997f60f30d945601600 | |
parent | f543f253f3aa721a24557d7df8259145bb01b734 (diff) | |
download | op-kernel-dev-0cd5b88553acf0611474dbaf8e43770eed268060.zip op-kernel-dev-0cd5b88553acf0611474dbaf8e43770eed268060.tar.gz |
[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>
-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 de4a0a0..c72e44b 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) int intr; sigset_t oldset; + atomic_inc(&fc->num_waiting); block_sigs(&oldset); intr = down_interruptible(&fc->outstanding_sem); restore_sigs(&oldset); - return intr ? NULL : do_get_request(fc); + if (intr) { + atomic_dec(&fc->num_waiting); + return NULL; + } + return do_get_request(fc); } static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) { spin_lock(&fuse_lock); - if (req->preallocated) + if (req->preallocated) { + atomic_dec(&fc->num_waiting); list_add(&req->list, &fc->unused_list); - else + } else fuse_request_free(req); /* If we are in debt decrease that first */ diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6ef1e5f..bcb453f 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -280,6 +280,9 @@ struct fuse_conn { /** Is create not implemented by fs? */ unsigned no_create : 1; + /** The number of requests waiting for completion */ + atomic_t num_waiting; + /** Negotiated minor version */ unsigned minor; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 514b700..1822359 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -555,7 +555,16 @@ static struct file_system_type fuse_fs_type = { .kill_sb = kill_anon_super, }; +static ssize_t fuse_conn_waiting_show(struct fuse_conn *fc, char *page) +{ + return sprintf(page, "%i\n", atomic_read(&fc->num_waiting)); +} + +static struct fuse_conn_attr fuse_conn_waiting = + __ATTR(waiting, 0400, fuse_conn_waiting_show, NULL); + static struct attribute *fuse_conn_attrs[] = { + &fuse_conn_waiting.attr, NULL, }; |