summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2004-11-14 01:02:44 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2004-11-14 01:02:44 +0000
commit3f2fb4a05af190cd2885fb11e13db87b9bc43933 (patch)
tree899e207ac61b0b1e1a97f565391f871ac5bad775
parentc1492663269321a71fd9cb27a3097ed437dc4a26 (diff)
downloadfuse-3f2fb4a05af190cd2885fb11e13db87b9bc43933.tar.gz
fix oops
-rw-r--r--ChangeLog5
-rw-r--r--kernel/dev.c16
-rw-r--r--kernel/file.c4
-rw-r--r--kernel/fuse_i.h5
4 files changed, 19 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index ffdb774..494815b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2004-11-14 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Fix bug in fuse_readpages() causing Oops in certain situations.
+ Bug found by Vincenzo Ciancia.
+
2004-11-11 Miklos Szeredi <miklos@szeredi.hu>
* Check kernel interface version in fusermount to prevent
diff --git a/kernel/dev.c b/kernel/dev.c
index e3ead67..9250fe1 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -131,24 +131,22 @@ static struct fuse_req *do_get_request(struct fuse_conn *fc)
struct fuse_req *fuse_get_request(struct fuse_conn *fc)
{
- struct fuse_req *req;
-
if (down_interruptible(&fc->unused_sem))
return NULL;
+ return do_get_request(fc);
+}
- req = do_get_request(fc);
- return req;
+struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
+{
+ down(&fc->unused_sem);
+ return do_get_request(fc);
}
struct fuse_req *fuse_get_request_nonblock(struct fuse_conn *fc)
{
- struct fuse_req *req;
-
if (down_trylock(&fc->unused_sem))
return NULL;
-
- req = do_get_request(fc);
- return req;
+ return do_get_request(fc);
}
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
diff --git a/kernel/file.c b/kernel/file.c
index aa6662b..cea140f 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -375,7 +375,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
req->pages[req->num_pages - 1]->index + 1 != page->index)) {
struct fuse_conn *fc = INO_FC(page->mapping->host);
fuse_send_readpages(req, data->file, inode);
- data->req = req = fuse_get_request(fc);
+ data->req = req = fuse_get_request_nonint(fc);
}
req->pages[req->num_pages] = page;
req->num_pages ++;
@@ -389,7 +389,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
struct fuse_conn *fc = INO_FC(inode);
struct fuse_readpages_data data;
- data.req = fuse_get_request(fc);
+ data.req = fuse_get_request_nonint(fc);
data.file = file;
data.inode = inode;
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index c256bb2..d2eeece 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -344,6 +344,11 @@ void fuse_reset_request(struct fuse_req *req);
struct fuse_req *fuse_get_request(struct fuse_conn *fc);
/**
+ * Reserve a preallocated request, non-interruptible
+ */
+struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
+
+/**
* Reserve a preallocated request, non-blocking
*/
struct fuse_req *fuse_get_request_nonblock(struct fuse_conn *fc);