From b6a04305afe0891799a90c4fc0d3840911eb6daa Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 2 Feb 2007 12:23:45 +0000 Subject: [PATCH] Fix regression --- ChangeLog | 10 ++++++++++ include/fuse.h | 1 - lib/fuse.c | 10 ++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9d2bcd..8137979 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-02-02 Miklos Szeredi + + * Fix regression caused by "Fix possible double lock in certain + cases if request is interrupted" on 2007-01-19. Reported by José + Antonio Sánchez + +2007-01-30 Miklos Szeredi + + * Released 2.6.2 + 2007-01-28 Miklos Szeredi * kernel: fix BUG in control filesystem if it is umounted and diff --git a/include/fuse.h b/include/fuse.h index 90c4d5d..83b6f21 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -172,7 +172,6 @@ struct fuse_operations { int (*write) (const char *, const char *, size_t, off_t, struct fuse_file_info *); - /** Just a placeholder, don't set */ /** Get file system statistics * * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored diff --git a/lib/fuse.c b/lib/fuse.c index 3c5dc6c..f34c7cb 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -1437,13 +1437,15 @@ static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name, if (f->conf.kernel_cache) fi->keep_cache = 1; + /* see comment for open */ + pthread_mutex_lock(&f->lock); if (fuse_reply_create(req, &e, fi) == -ENOENT) { /* The open syscall was interrupted, so it must be cancelled */ + pthread_mutex_unlock(&f->lock); if(f->op.release) fuse_do_release(f, req, path, fi); forget_node(f, e.ino, 1); } else { - pthread_mutex_lock(&f->lock); get_node(f, e.ino)->open_count++; pthread_mutex_unlock(&f->lock); } @@ -1526,12 +1528,16 @@ static void fuse_open(fuse_req_t req, fuse_ino_t ino, if (f->conf.auto_cache) open_auto_cache(f, req, ino, path, fi); + /* The reply and the open count increase needs to be under a + single locked section, otherwise a release could come in + between and screw up the accounting */ + pthread_mutex_lock(&f->lock); if (fuse_reply_open(req, fi) == -ENOENT) { /* The open syscall was interrupted, so it must be cancelled */ + pthread_mutex_unlock(&f->lock); if(f->op.release && path != NULL) fuse_compat_release(f, req, path, fi); } else { - pthread_mutex_lock(&f->lock); get_node(f, ino)->open_count++; pthread_mutex_unlock(&f->lock); } -- 2.30.2