From: Miklos Szeredi 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 Signed-off-by: Andrew Morton --- fs/fuse/dev.c | 12 +++++++++--- fs/fuse/fuse_i.h | 3 +++ fs/fuse/inode.c | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff -puN fs/fuse/dev.c~fuse-add-number-of-waiting-requests-attribute fs/fuse/dev.c --- 25/fs/fuse/dev.c~fuse-add-number-of-waiting-requests-attribute Fri Jan 13 17:35:56 2006 +++ 25-akpm/fs/fuse/dev.c Fri Jan 13 17:35:56 2006 @@ -109,18 +109,24 @@ struct fuse_req *fuse_get_request(struct 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 -puN fs/fuse/fuse_i.h~fuse-add-number-of-waiting-requests-attribute fs/fuse/fuse_i.h --- 25/fs/fuse/fuse_i.h~fuse-add-number-of-waiting-requests-attribute Fri Jan 13 17:35:56 2006 +++ 25-akpm/fs/fuse/fuse_i.h Fri Jan 13 17:35:56 2006 @@ -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 -puN fs/fuse/inode.c~fuse-add-number-of-waiting-requests-attribute fs/fuse/inode.c --- 25/fs/fuse/inode.c~fuse-add-number-of-waiting-requests-attribute Fri Jan 13 17:35:56 2006 +++ 25-akpm/fs/fuse/inode.c Fri Jan 13 17:35:56 2006 @@ -555,7 +555,16 @@ static struct file_system_type fuse_fs_t .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, }; _