public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] FUSE: fix busy inodes after unmount
@ 2005-03-18 17:33 Miklos Szeredi
  2005-03-20 16:15 ` fuse is cool and robust bert hubert
  0 siblings, 1 reply; 76+ messages in thread
From: Miklos Szeredi @ 2005-03-18 17:33 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

Hi Andrew!

If background requests (*) were pending at umount time, the inodes
stored in the request weren't released, resulting in busy inodes after
unmount and possibly Oopsen.

This patch fixes this bug by storing background requests on a
separate list.  In fuse_put_super() the list is walked and the inodes
belonging to the background requests are released.  In addition
sending FORGET messages from fuse_clear_inode() is inhibited if
unmount has started (MS_ACTIVE flag not set).  Releasing inodes in
fuse_super() results in a race with request_end() doing the same.
This is resolved with a per-mount RW semaphore which is acquired for
read in request_end() and for write in fuse_put_super().

(*) requests for which the original requester thread isn't waiting any
more

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>

 dev.c    |   33 ++++++++++++++++++++++-----------
 fuse_i.h |   15 +++++++++++++++
 inode.c  |   10 +++++++++-
 3 files changed, 46 insertions(+), 12 deletions(-)

diff -rup linux-2.6.11-mm4/fs/fuse/dev.c linux-fuse/fs/fuse/dev.c
--- linux-2.6.11-mm4/fs/fuse/dev.c	2005-03-18 18:01:34.000000000 +0100
+++ linux-fuse/fs/fuse/dev.c	2005-03-18 18:02:16.000000000 +0100
@@ -140,6 +140,17 @@ void fuse_put_request(struct fuse_conn *
 		fuse_putback_request(fc, req);
 }
 
+void fuse_release_background(struct fuse_req *req)
+{
+	if (req->inode)
+		iput(req->inode);
+	if (req->inode2)
+		iput(req->inode2);
+	if (req->file)
+		fput(req->file);
+	list_del(&req->bg_entry);
+}
+
 /* Called with fuse_lock, unlocks it */
 static void request_end(struct fuse_conn *fc, struct fuse_req *req)
 {
@@ -148,12 +159,10 @@ static void request_end(struct fuse_conn
 	putback = atomic_dec_and_test(&req->count);
 	spin_unlock(&fuse_lock);
 	if (req->background) {
-		if (req->inode)
-			iput(req->inode);
-		if (req->inode2)
-			iput(req->inode2);
-		if (req->file)
-			fput(req->file);
+		down_read(&fc->sbput_sem);
+		if (fc->sb)
+			fuse_release_background(req);
+		up_read(&fc->sbput_sem);
 	}
 	wake_up(&req->waitq);
 	if (req->in.h.opcode == FUSE_INIT) {
@@ -169,11 +178,12 @@ static void request_end(struct fuse_conn
 		fuse_putback_request(fc, req);
 }
 
-static void background_request(struct fuse_req *req)
+static void background_request(struct fuse_conn *fc, struct fuse_req *req)
 {
 	/* Need to get hold of the inode(s) and/or file used in the
 	   request, so FORGET and RELEASE are not sent too early */
 	req->background = 1;
+	list_add(&req->bg_entry, &fc->background);
 	if (req->inode)
 		req->inode = igrab(req->inode);
 	if (req->inode2)
@@ -193,7 +203,8 @@ static int request_wait_answer_nonint(st
 }
 
 /* Called with fuse_lock held.  Releases, and then reacquires it. */
-static void request_wait_answer(struct fuse_req *req, int interruptible)
+static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req,
+				int interruptible)
 {
 	int intr;
 
@@ -233,7 +244,7 @@ static void request_wait_answer(struct f
 		list_del(&req->list);
 		__fuse_put_request(req);
 	} else if (!req->finished && req->sent)
-		background_request(req);
+		background_request(fc, req);
 }
 
 static unsigned len_args(unsigned numargs, struct fuse_arg *args)
@@ -277,7 +288,7 @@ static void request_send_wait(struct fus
 		   after request_end() */
 		__fuse_get_request(req);
 
-		request_wait_answer(req, interruptible);
+		request_wait_answer(fc, req, interruptible);
 	}
 	spin_unlock(&fuse_lock);
 }
@@ -313,7 +324,7 @@ void request_send_noreply(struct fuse_co
 void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
 {
 	req->isreply = 1;
-	background_request(req);
+	background_request(fc, req);
 	request_send_nowait(fc, req);
 }
 
diff -rup linux-2.6.11-mm4/fs/fuse/fuse_i.h linux-fuse/fs/fuse/fuse_i.h
--- linux-2.6.11-mm4/fs/fuse/fuse_i.h	2005-03-18 18:01:34.000000000 +0100
+++ linux-fuse/fs/fuse/fuse_i.h	2005-03-18 18:02:16.000000000 +0100
@@ -126,6 +126,9 @@ struct fuse_req {
 	    lists in fuse_conn */
 	struct list_head list;
 
+	/** Entry on the background list */
+	struct list_head bg_entry;
+
 	/** refcount */
 	atomic_t count;
 
@@ -220,6 +223,10 @@ struct fuse_conn {
 	/** The list of requests being processed */
 	struct list_head processing;
 
+	/** Requests put in the background (RELEASE or any other
+	    interrupted request) */
+	struct list_head background;
+
 	/** Controls the maximum number of outstanding requests */
 	struct semaphore outstanding_sem;
 
@@ -227,6 +234,9 @@ struct fuse_conn {
 	    outstanding_sem would go negative */
 	unsigned outstanding_debt;
 
+	/** RW semaphore for exclusion with fuse_put_super() */
+	struct rw_semaphore sbput_sem;
+
 	/** The list of unused requests */
 	struct list_head unused_list;
 
@@ -419,6 +429,11 @@ void request_send_noreply(struct fuse_co
 void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
 
 /**
+ * Release inodes and file assiciated with background request
+ */
+void fuse_release_background(struct fuse_req *req);
+
+/**
  * Get the attributes of a file
  */
 int fuse_do_getattr(struct inode *inode);
diff -rup linux-2.6.11-mm4/fs/fuse/inode.c linux-fuse/fs/fuse/inode.c
--- linux-2.6.11-mm4/fs/fuse/inode.c	2005-03-18 18:01:34.000000000 +0100
+++ linux-fuse/fs/fuse/inode.c	2005-03-18 18:02:16.000000000 +0100
@@ -85,7 +85,7 @@ void fuse_send_forget(struct fuse_conn *
 static void fuse_clear_inode(struct inode *inode)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	if (fc) {
+	if (fc && (inode->i_sb->s_flags & MS_ACTIVE)) {
 		struct fuse_inode *fi = get_fuse_inode(inode);
 		fuse_send_forget(fc, fi->forget_req, fi->nodeid, inode->i_version);
 		fi->forget_req = NULL;
@@ -188,12 +188,18 @@ static void fuse_put_super(struct super_
 {
 	struct fuse_conn *fc = get_fuse_conn_super(sb);
 
+	down_write(&fc->sbput_sem);
+	while (!list_empty(&fc->background))
+		fuse_release_background(list_entry(fc->background.next,
+						   struct fuse_req, bg_entry));
+
 	spin_lock(&fuse_lock);
 	fc->sb = NULL;
 	fc->user_id = 0;
 	fc->flags = 0;
 	/* Flush all readers on this fs */
 	wake_up_all(&fc->waitq);
+	up_write(&fc->sbput_sem);
 	fuse_release_conn(fc);
 	*get_fuse_conn_super_p(sb) = NULL;
 	spin_unlock(&fuse_lock);
@@ -386,7 +392,9 @@ static struct fuse_conn *new_conn(void)
 		INIT_LIST_HEAD(&fc->pending);
 		INIT_LIST_HEAD(&fc->processing);
 		INIT_LIST_HEAD(&fc->unused_list);
+		INIT_LIST_HEAD(&fc->background);
 		sema_init(&fc->outstanding_sem, 0);
+		init_rwsem(&fc->sbput_sem);
 		for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
 			struct fuse_req *req = fuse_request_alloc();
 			if (!req) {


^ permalink raw reply	[flat|nested] 76+ messages in thread
[parent not found: <3S8oM-So-11@gated-at.bofh.it>]
[parent not found: <3UrQt-2Js-3@gated-at.bofh.it>]

end of thread, other threads:[~2005-04-20 19:53 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-18 17:33 [PATCH] FUSE: fix busy inodes after unmount Miklos Szeredi
2005-03-20 16:15 ` fuse is cool and robust bert hubert
2005-03-20 21:55   ` Jan Engelhardt
2005-03-21  6:52     ` bert hubert
2005-03-20 23:12   ` Andrew Morton
     [not found]     ` <20050321073519.GA13879@outpost.ds9a.nl>
     [not found]       ` <20050323083347.GA1807@infradead.org>
     [not found]         ` <E1DE2D1-0005Ie-00@dorka.pomaz.szeredi.hu>
     [not found]           ` <20050325095838.GA9471@infradead.org>
     [not found]             ` <E1DEmYC-0008Qg-00@dorka.pomaz.szeredi.hu>
     [not found]               ` <20050331112427.GA15034@infradead.org>
     [not found]                 ` <E1DH13O-000400-00@dorka.pomaz.szeredi.hu>
     [not found]                   ` <20050331200502.GA24589@infradead.org>
     [not found]                     ` <E1DJsH6-0004nv-00@dorka.pomaz.szeredi.hu>
     [not found]                       ` <20050411114728.GA13128@infradead.org>
2005-04-11 14:43                         ` [RFC] FUSE permission modell (Was: fuse review bits) Miklos Szeredi
2005-04-11 15:36                           ` Daniel Jacobowitz
2005-04-11 15:56                             ` Miklos Szeredi
2005-04-11 18:17                               ` Daniel Jacobowitz
2005-04-11 19:10                                 ` Miklos Szeredi
2005-04-11 19:22                                   ` Daniel Jacobowitz
2005-04-11 19:56                                     ` Miklos Szeredi
2005-04-11 21:41                                       ` Jamie Lokier
2005-04-12  6:10                                         ` Miklos Szeredi
2005-04-12 14:33                                           ` Jamie Lokier
2005-04-12 15:13                                             ` Miklos Szeredi
2005-04-12 16:03                                               ` Miklos Szeredi
2005-04-12 15:16                                             ` Frank Sorenson
2005-04-12 15:56                                               ` Jamie Lokier
2005-04-17 17:45                                           ` Eric Van Hensbergen
2005-04-17 18:06                                             ` Jamie Lokier
2005-04-12 20:36                                         ` Anton Altaparmakov
2005-04-11 22:13                                       ` Daniel Jacobowitz
2005-04-12  6:27                                         ` Miklos Szeredi
2005-04-12 14:32                                           ` Jamie Lokier
2005-04-12 14:59                                             ` Miklos Szeredi
2005-04-12 16:13                                               ` Jamie Lokier
2005-04-12 16:37                                                 ` Miklos Szeredi
2005-04-12 16:45                                                   ` Jamie Lokier
2005-04-12 16:52                                                     ` Miklos Szeredi
2005-04-12 17:14                                                       ` Jamie Lokier
2005-04-12 19:10                                                         ` Miklos Szeredi
2005-04-12 16:42                                                 ` Jan Hudec
2005-04-11 19:43                                   ` Yaroslav Rastrigin
2005-04-12  8:06                               ` Jan Hudec
2005-04-11 18:22                           ` Jamie Lokier
2005-04-11 18:27                             ` Daniel Jacobowitz
2005-04-11 19:38                             ` Miklos Szeredi
2005-04-17 18:01                           ` Eric Van Hensbergen
2005-04-17 18:45                             ` Miklos Szeredi
2005-04-17 19:57                               ` Eric Van Hensbergen
     [not found] <3S8oM-So-11@gated-at.bofh.it>
     [not found] ` <3S8oM-So-13@gated-at.bofh.it>
     [not found]   ` <3S8oN-So-15@gated-at.bofh.it>
     [not found]     ` <3S8oN-So-17@gated-at.bofh.it>
     [not found]       ` <3S8oN-So-19@gated-at.bofh.it>
     [not found]         ` <3S8oN-So-21@gated-at.bofh.it>
     [not found]           ` <3S8oN-So-23@gated-at.bofh.it>
     [not found]             ` <3S8oN-So-25@gated-at.bofh.it>
     [not found]               ` <3S8oN-So-27@gated-at.bofh.it>
     [not found]                 ` <3S8oM-So-7@gated-at.bofh.it>
     [not found]                   ` <3SbPN-3T4-19@gated-at.bofh.it>
2005-04-12  9:17                     ` Bodo Eggert <harvested.in.lkml@posting.7eggert.dyndns.org>
2005-04-12 14:45                       ` Jamie Lokier
2005-04-12 15:19                         ` Miklos Szeredi
2005-04-12 16:04                           ` Jamie Lokier
2005-04-12 16:31                             ` Miklos Szeredi
2005-04-12 16:44                               ` Jamie Lokier
2005-04-12 16:55                                 ` Miklos Szeredi
2005-04-12 17:13                                   ` Jamie Lokier
2005-04-12 19:08                                     ` Miklos Szeredi
2005-04-13 12:56                                       ` Jan Hudec
2005-04-13 15:08                                         ` Miklos Szeredi
2005-04-13 16:13                                           ` Jamie Lokier
2005-04-13 16:47                                             ` Miklos Szeredi
2005-04-13 16:57                                               ` Jamie Lokier
2005-04-13 15:58                                         ` Jamie Lokier
2005-04-12 20:19                         ` Anton Altaparmakov
2005-04-12 21:52                           ` Jamie Lokier
2005-04-13  9:14                             ` Miklos Szeredi
2005-04-13 12:59                               ` Jan Hudec
2005-04-13 17:02                               ` Jamie Lokier
2005-04-13 17:29                                 ` Miklos Szeredi
2005-04-13 18:36                                   ` Jamie Lokier
2005-04-13 19:16                                     ` Miklos Szeredi
     [not found]                   ` <3S9b7-1yl-1@gated-at.bofh.it>
     [not found]                     ` <3S9uB-1Lj-3@gated-at.bofh.it>
     [not found]                       ` <3SbG5-3Mb-41@gated-at.bofh.it>
     [not found]                         ` <3ScC1-4zl-1@gated-at.bofh.it>
     [not found]                           ` <3ScLO-4GA-9@gated-at.bofh.it>
     [not found]                             ` <3SdeV-54h-21@gated-at.bofh.it>
     [not found]                               ` <3SeXf-6BK-21@gated-at.bofh.it>
     [not found]                                 ` <E1DLKOd-0001Nd-MG@be1.7eggert.dyndns.org>
2005-04-12 14:37                                   ` Jamie Lokier
2005-04-12 19:51                                     ` Bodo Eggert
     [not found]                   ` <3UmnD-6Fy-7@gated-at.bofh.it>
2005-04-17 23:52                     ` Bodo Eggert <harvested.in.lkml@posting.7eggert.dyndns.org>
2005-04-19 11:57                       ` Eric Van Hensbergen
2005-04-19 15:01                         ` Bodo Eggert
2005-04-19 15:21                           ` Miklos Szeredi
2005-04-19 15:26                           ` Eric Van Hensbergen
2005-04-19 16:02                             ` Bodo Eggert
2005-04-19 19:29                               ` Eric Van Hensbergen
2005-04-20  3:59                                 ` Mike Waychison
2005-04-20  7:09                                   ` Miklos Szeredi
     [not found] <3UrQt-2Js-3@gated-at.bofh.it>
     [not found] ` <3SpIW-6UA-17@gated-at.bofh.it>
     [not found]   ` <3SpIW-6UA-19@gated-at.bofh.it>
     [not found]     ` <3SpIW-6UA-21@gated-at.bofh.it>
     [not found]       ` <3UrQt-2Js-5@gated-at.bofh.it>
     [not found]         ` <3UrQt-2Js-1@gated-at.bofh.it>
     [not found]           ` <3UZyS-55i-39@gated-at.bofh.it>
     [not found]             ` <3V2wG-7HR-19@gated-at.bofh.it>
     [not found]               ` <3V2PX-7Vh-23@gated-at.bofh.it>
     [not found]                 ` <3V6Ae-2Ce-17@gated-at.bofh.it>
     [not found]                   ` <3V6JW-2K9-49@gated-at.bofh.it>
     [not found]                     ` <3VeHl-NF-3@gated-at.bofh.it>
2005-04-20 19:52                       ` Bodo Eggert <harvested.in.lkml@posting.7eggert.dyndns.org>

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox