aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorBryan Green <bryan@grid-net.com>2011-03-01 19:43:52 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2011-03-21 08:58:05 -0400
commit357ccf2b69bcefa650a54db83702381d1c9d6959 (patch)
tree0bbcbb308b0a28a489d38177a4ad7b84b1ae36d5 /fs/fuse
parent07d5f69b457019eda4ca568923b1d62b7ada89e1 (diff)
fuse: wakeup pollers on connection release/abort
If a fuse dev connection is broken, wake up any processes that are blocking, in a poll system call, on one of the files in the now defunct filesystem. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c17
-rw-r--r--fs/fuse/file.c2
2 files changed, 18 insertions, 1 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index cf8d28d1fbad..213d3cf4f5e9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1910,6 +1910,21 @@ __acquires(fc->lock)
1910 kfree(dequeue_forget(fc, 1, NULL)); 1910 kfree(dequeue_forget(fc, 1, NULL));
1911} 1911}
1912 1912
1913static void end_polls(struct fuse_conn *fc)
1914{
1915 struct rb_node *p;
1916
1917 p = rb_first(&fc->polled_files);
1918
1919 while (p) {
1920 struct fuse_file *ff;
1921 ff = rb_entry(p, struct fuse_file, polled_node);
1922 wake_up_interruptible_all(&ff->poll_wait);
1923
1924 p = rb_next(p);
1925 }
1926}
1927
1913/* 1928/*
1914 * Abort all requests. 1929 * Abort all requests.
1915 * 1930 *
@@ -1937,6 +1952,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
1937 fc->blocked = 0; 1952 fc->blocked = 0;
1938 end_io_requests(fc); 1953 end_io_requests(fc);
1939 end_queued_requests(fc); 1954 end_queued_requests(fc);
1955 end_polls(fc);
1940 wake_up_all(&fc->waitq); 1956 wake_up_all(&fc->waitq);
1941 wake_up_all(&fc->blocked_waitq); 1957 wake_up_all(&fc->blocked_waitq);
1942 kill_fasync(&fc->fasync, SIGIO, POLL_IN); 1958 kill_fasync(&fc->fasync, SIGIO, POLL_IN);
@@ -1953,6 +1969,7 @@ int fuse_dev_release(struct inode *inode, struct file *file)
1953 fc->connected = 0; 1969 fc->connected = 0;
1954 fc->blocked = 0; 1970 fc->blocked = 0;
1955 end_queued_requests(fc); 1971 end_queued_requests(fc);
1972 end_polls(fc);
1956 wake_up_all(&fc->blocked_waitq); 1973 wake_up_all(&fc->blocked_waitq);
1957 spin_unlock(&fc->lock); 1974 spin_unlock(&fc->lock);
1958 fuse_conn_put(fc); 1975 fuse_conn_put(fc);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 9e0832dbb1e3..6ea00734984e 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -222,7 +222,7 @@ static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode)
222 rb_erase(&ff->polled_node, &fc->polled_files); 222 rb_erase(&ff->polled_node, &fc->polled_files);
223 spin_unlock(&fc->lock); 223 spin_unlock(&fc->lock);
224 224
225 wake_up_interruptible_sync(&ff->poll_wait); 225 wake_up_interruptible_all(&ff->poll_wait);
226 226
227 inarg->fh = ff->fh; 227 inarg->fh = ff->fh;
228 inarg->flags = flags; 228 inarg->flags = flags;