summary refs log tree commit diff
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-01-16 22:14:38 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-16 23:15:30 -0800
commit0cd5b88553acf0611474dbaf8e43770eed268060 (patch)
treef3b08ab3a4a1cb42d92e2997f60f30d945601600 /fs/fuse
parentf543f253f3aa721a24557d7df8259145bb01b734 (diff)
downloadlinux-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>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c12
-rw-r--r--fs/fuse/fuse_i.h3
-rw-r--r--fs/fuse/inode.c9
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)
 	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 6ef1e5f5873b..bcb453f68111 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 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 = {
 	.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,
 };