Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: fix lock annotations
  fuse: flush background queue on connection close
This commit is contained in:
Linus Torvalds 2010-09-08 11:12:59 -07:00
commit c8c727db41
2 changed files with 30 additions and 20 deletions

View File

@ -276,7 +276,7 @@ static void flush_bg_queue(struct fuse_conn *fc)
* Called with fc->lock, unlocks it * Called with fc->lock, unlocks it
*/ */
static void request_end(struct fuse_conn *fc, struct fuse_req *req) static void request_end(struct fuse_conn *fc, struct fuse_req *req)
__releases(&fc->lock) __releases(fc->lock)
{ {
void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
req->end = NULL; req->end = NULL;
@ -306,8 +306,8 @@ __releases(&fc->lock)
static void wait_answer_interruptible(struct fuse_conn *fc, static void wait_answer_interruptible(struct fuse_conn *fc,
struct fuse_req *req) struct fuse_req *req)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
if (signal_pending(current)) if (signal_pending(current))
return; return;
@ -325,8 +325,8 @@ static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req)
} }
static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
if (!fc->no_interrupt) { if (!fc->no_interrupt) {
/* Any signal may interrupt this */ /* Any signal may interrupt this */
@ -905,8 +905,8 @@ static int request_pending(struct fuse_conn *fc)
/* Wait until a request is available on the pending list */ /* Wait until a request is available on the pending list */
static void request_wait(struct fuse_conn *fc) static void request_wait(struct fuse_conn *fc)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
@ -934,7 +934,7 @@ __acquires(&fc->lock)
*/ */
static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs,
size_t nbytes, struct fuse_req *req) size_t nbytes, struct fuse_req *req)
__releases(&fc->lock) __releases(fc->lock)
{ {
struct fuse_in_header ih; struct fuse_in_header ih;
struct fuse_interrupt_in arg; struct fuse_interrupt_in arg;
@ -1720,8 +1720,8 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
* This function releases and reacquires fc->lock * This function releases and reacquires fc->lock
*/ */
static void end_requests(struct fuse_conn *fc, struct list_head *head) static void end_requests(struct fuse_conn *fc, struct list_head *head)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
while (!list_empty(head)) { while (!list_empty(head)) {
struct fuse_req *req; struct fuse_req *req;
@ -1744,8 +1744,8 @@ __acquires(&fc->lock)
* locked). * locked).
*/ */
static void end_io_requests(struct fuse_conn *fc) static void end_io_requests(struct fuse_conn *fc)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
while (!list_empty(&fc->io)) { while (!list_empty(&fc->io)) {
struct fuse_req *req = struct fuse_req *req =
@ -1769,6 +1769,16 @@ __acquires(&fc->lock)
} }
} }
static void end_queued_requests(struct fuse_conn *fc)
__releases(fc->lock)
__acquires(fc->lock)
{
fc->max_background = UINT_MAX;
flush_bg_queue(fc);
end_requests(fc, &fc->pending);
end_requests(fc, &fc->processing);
}
/* /*
* Abort all requests. * Abort all requests.
* *
@ -1795,8 +1805,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
fc->connected = 0; fc->connected = 0;
fc->blocked = 0; fc->blocked = 0;
end_io_requests(fc); end_io_requests(fc);
end_requests(fc, &fc->pending); end_queued_requests(fc);
end_requests(fc, &fc->processing);
wake_up_all(&fc->waitq); wake_up_all(&fc->waitq);
wake_up_all(&fc->blocked_waitq); wake_up_all(&fc->blocked_waitq);
kill_fasync(&fc->fasync, SIGIO, POLL_IN); kill_fasync(&fc->fasync, SIGIO, POLL_IN);
@ -1811,8 +1820,9 @@ int fuse_dev_release(struct inode *inode, struct file *file)
if (fc) { if (fc) {
spin_lock(&fc->lock); spin_lock(&fc->lock);
fc->connected = 0; fc->connected = 0;
end_requests(fc, &fc->pending); fc->blocked = 0;
end_requests(fc, &fc->processing); end_queued_requests(fc);
wake_up_all(&fc->blocked_waitq);
spin_unlock(&fc->lock); spin_unlock(&fc->lock);
fuse_conn_put(fc); fuse_conn_put(fc);
} }

View File

@ -1144,8 +1144,8 @@ static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req)
/* Called under fc->lock, may release and reacquire it */ /* Called under fc->lock, may release and reacquire it */
static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
struct fuse_inode *fi = get_fuse_inode(req->inode); struct fuse_inode *fi = get_fuse_inode(req->inode);
loff_t size = i_size_read(req->inode); loff_t size = i_size_read(req->inode);
@ -1183,8 +1183,8 @@ __acquires(&fc->lock)
* Called with fc->lock * Called with fc->lock
*/ */
void fuse_flush_writepages(struct inode *inode) void fuse_flush_writepages(struct inode *inode)
__releases(&fc->lock) __releases(fc->lock)
__acquires(&fc->lock) __acquires(fc->lock)
{ {
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode); struct fuse_inode *fi = get_fuse_inode(inode);