[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>

authored by

Miklos Szeredi and committed by
Linus Torvalds
0cd5b885 f543f253

+21 -3
+9 -3
fs/fuse/dev.c
··· 109 int intr; 110 sigset_t oldset; 111 112 block_sigs(&oldset); 113 intr = down_interruptible(&fc->outstanding_sem); 114 restore_sigs(&oldset); 115 - return intr ? NULL : do_get_request(fc); 116 } 117 118 static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) 119 { 120 spin_lock(&fuse_lock); 121 - if (req->preallocated) 122 list_add(&req->list, &fc->unused_list); 123 - else 124 fuse_request_free(req); 125 126 /* If we are in debt decrease that first */
··· 109 int intr; 110 sigset_t oldset; 111 112 + atomic_inc(&fc->num_waiting); 113 block_sigs(&oldset); 114 intr = down_interruptible(&fc->outstanding_sem); 115 restore_sigs(&oldset); 116 + if (intr) { 117 + atomic_dec(&fc->num_waiting); 118 + return NULL; 119 + } 120 + return do_get_request(fc); 121 } 122 123 static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) 124 { 125 spin_lock(&fuse_lock); 126 + if (req->preallocated) { 127 + atomic_dec(&fc->num_waiting); 128 list_add(&req->list, &fc->unused_list); 129 + } else 130 fuse_request_free(req); 131 132 /* If we are in debt decrease that first */
+3
fs/fuse/fuse_i.h
··· 280 /** Is create not implemented by fs? */ 281 unsigned no_create : 1; 282 283 /** Negotiated minor version */ 284 unsigned minor; 285
··· 280 /** Is create not implemented by fs? */ 281 unsigned no_create : 1; 282 283 + /** The number of requests waiting for completion */ 284 + atomic_t num_waiting; 285 + 286 /** Negotiated minor version */ 287 unsigned minor; 288
+9
fs/fuse/inode.c
··· 555 .kill_sb = kill_anon_super, 556 }; 557 558 static struct attribute *fuse_conn_attrs[] = { 559 NULL, 560 }; 561
··· 555 .kill_sb = kill_anon_super, 556 }; 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 + 566 static struct attribute *fuse_conn_attrs[] = { 567 + &fuse_conn_waiting.attr, 568 NULL, 569 }; 570