aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-01-17 01:14:41 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-17 02:15:30 -0500
commit69a53bf267fa58b89aa659d121dfe38436562a30 (patch)
tree36276fdbf7bfdc787708e8d5b2d4b79a0b5a4c56 /fs/fuse/inode.c
parent0cd5b88553acf0611474dbaf8e43770eed268060 (diff)
[PATCH] fuse: add connection aborting
Add ability to abort a filesystem connection. With the introduction of asynchronous reads, the ability to interrupt any request is not enough to dissolve deadlocks, since now waiting for the request completion (page unlocked) is independent of the actual request, so in a deadlock all threads will be uninterruptible. The solution is to make it possible to abort all requests, even those currently undergoing I/O to/from userspace. The natural interface for this is 'mount -f mountpoint', but that only works as long as the filesystem is attached. So also add an 'abort' attribute to the sysfs view of the connection. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 182235923cdd..d359d8de22a4 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -196,6 +196,11 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
196 return inode; 196 return inode;
197} 197}
198 198
199static void fuse_umount_begin(struct super_block *sb)
200{
201 fuse_abort_conn(get_fuse_conn_super(sb));
202}
203
199static void fuse_put_super(struct super_block *sb) 204static void fuse_put_super(struct super_block *sb)
200{ 205{
201 struct fuse_conn *fc = get_fuse_conn_super(sb); 206 struct fuse_conn *fc = get_fuse_conn_super(sb);
@@ -454,6 +459,7 @@ static struct super_operations fuse_super_operations = {
454 .read_inode = fuse_read_inode, 459 .read_inode = fuse_read_inode,
455 .clear_inode = fuse_clear_inode, 460 .clear_inode = fuse_clear_inode,
456 .put_super = fuse_put_super, 461 .put_super = fuse_put_super,
462 .umount_begin = fuse_umount_begin,
457 .statfs = fuse_statfs, 463 .statfs = fuse_statfs,
458 .show_options = fuse_show_options, 464 .show_options = fuse_show_options,
459}; 465};
@@ -560,11 +566,21 @@ static ssize_t fuse_conn_waiting_show(struct fuse_conn *fc, char *page)
560 return sprintf(page, "%i\n", atomic_read(&fc->num_waiting)); 566 return sprintf(page, "%i\n", atomic_read(&fc->num_waiting));
561} 567}
562 568
569static ssize_t fuse_conn_abort_store(struct fuse_conn *fc, const char *page,
570 size_t count)
571{
572 fuse_abort_conn(fc);
573 return count;
574}
575
563static struct fuse_conn_attr fuse_conn_waiting = 576static struct fuse_conn_attr fuse_conn_waiting =
564 __ATTR(waiting, 0400, fuse_conn_waiting_show, NULL); 577 __ATTR(waiting, 0400, fuse_conn_waiting_show, NULL);
578static struct fuse_conn_attr fuse_conn_abort =
579 __ATTR(abort, 0600, NULL, fuse_conn_abort_store);
565 580
566static struct attribute *fuse_conn_attrs[] = { 581static struct attribute *fuse_conn_attrs[] = {
567 &fuse_conn_waiting.attr, 582 &fuse_conn_waiting.attr,
583 &fuse_conn_abort.attr,
568 NULL, 584 NULL,
569}; 585};
570 586