summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2007-01-19 22:26:39 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2007-01-19 22:26:39 +0000
commiteb39e5a3c7eba9bcd806ec5a9c75bf428bc8b65c (patch)
tree2dc53a5381c1b714fd25cc62aa782cc454803067
parent1035b38a9a89713d50dcec6451fc5d3d77760686 (diff)
downloadfuse-eb39e5a3c7eba9bcd806ec5a9c75bf428bc8b65c.tar.gz
Fix possible double lock in certain cases if request is interrupted
-rw-r--r--ChangeLog3
-rw-r--r--lib/fuse.c10
2 files changed, 7 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index c40b3c3..d9558ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
* Build fix for 2.6.16 vanila and 2.6.15 FC5 kernels. Patch from
Ian Abbott
+ * Fix possible double lock in certain cases if request is
+ interrupted
+
2007-01-18 Miklos Szeredi <miklos@szeredi.hu>
* Fix abort in fuse_new() compatibility API for opts == NULL case.
diff --git a/lib/fuse.c b/lib/fuse.c
index 994a31f..e6e2a7d 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1437,16 +1437,14 @@ static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
if (f->conf.kernel_cache)
fi->keep_cache = 1;
- pthread_mutex_lock(&f->lock);
if (fuse_reply_create(req, &e, fi) == -ENOENT) {
/* The open syscall was interrupted, so it must be cancelled */
if(f->op.release)
fuse_do_release(f, req, path, fi);
- pthread_mutex_unlock(&f->lock);
forget_node(f, e.ino, 1);
} else {
- struct node *node = get_node(f, e.ino);
- node->open_count ++;
+ pthread_mutex_lock(&f->lock);
+ get_node(f, e.ino)->open_count ++;
pthread_mutex_unlock(&f->lock);
}
} else
@@ -1476,10 +1474,12 @@ static void open_auto_cache(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
struct stat stbuf;
int err;
+ pthread_mutex_unlock(&f->lock);
if (f->op.fgetattr)
err = fuse_do_fgetattr(f, req, path, &stbuf, fi);
else
err = fuse_do_getattr(f, req, path, &stbuf);
+ pthread_mutex_lock(&f->lock);
if (!err)
update_stat(node, &stbuf);
@@ -1750,7 +1750,6 @@ static void fuse_opendir(fuse_req_t req, fuse_ino_t ino,
dh->fh = fi.fh;
}
if (!err) {
- pthread_mutex_lock(&f->lock);
if (fuse_reply_open(req, llfi) == -ENOENT) {
/* The opendir syscall was interrupted, so it must be
cancelled */
@@ -1759,7 +1758,6 @@ static void fuse_opendir(fuse_req_t req, fuse_ino_t ino,
pthread_mutex_destroy(&dh->lock);
free(dh);
}
- pthread_mutex_unlock(&f->lock);
} else {
reply_err(req, err);
free(dh);