From 6353dcaf4e68eadbedf9deb7923afcefdd034663 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 11 May 2007 09:19:36 +0000 Subject: [PATCH] update flush changes --- ChangeLog | 4 ++- lib/fuse.c | 84 ++++++++++++++++++-------------------------- lib/modules/subdir.c | 2 +- 3 files changed, 39 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2baf37..d43e088 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,9 @@ * libfuse: fix return value of fuse_loop()/fuse_loop_mt(). Error reported by Csaba Henk, fix by Miklos Szeredi - * libfuse: various flush related fixes + * libfuse: fix unlock in flush + + * libfuse: do unlocking on RELEASE+FLUSH 2007-05-03 Miklos Szeredi diff --git a/lib/fuse.c b/lib/fuse.c index 817b16f..42866f1 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -2579,16 +2579,35 @@ static void lock_to_flock(struct lock *lock, struct flock *flock) flock->l_pid = lock->pid; } -static void fuse_flush_common(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi, - struct flock *lock, int *err, int *errlock) +static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino, + const char *path, struct fuse_file_info *fi) { - *err = fuse_fs_flush(fs, path, fi); + struct fuse_intr_data d; + struct flock lock; + struct lock l; + int err; + int errlock; + + fuse_prepare_interrupt(f, req, &d); + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + err = fuse_fs_flush(f->fs, path, fi); + errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock); + fuse_finish_interrupt(f, req, &d); + + if (errlock != -ENOSYS) { + flock_to_lock(&lock, &l); + l.owner = fi->lock_owner; + pthread_mutex_lock(&f->lock); + locks_insert(get_node(f, ino), &l); + pthread_mutex_unlock(&f->lock); - memset(lock, 0, sizeof(*lock)); - lock->l_type = F_UNLCK; - lock->l_whence = SEEK_SET; - *errlock = fuse_fs_lock(fs, path, fi, F_SETLK, lock); + /* if op.lock() is defined FLUSH is needed regardless of op.flush() */ + if (err == -ENOSYS) + err = 0; + } + return err; } static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino, @@ -2596,41 +2615,27 @@ static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino, { struct fuse *f = req_fuse_prepare(req); struct fuse_intr_data d; - struct flock lock; - struct lock l; char *path; int err = 0; - int errlock = -ENOSYS; pthread_rwlock_rdlock(&f->tree_lock); path = get_path(f, ino); - if (!path) - path = "-"; if (f->conf.debug) { printf("RELEASE%s[%llu] flags: 0x%x\n", fi->flush ? "+FLUSH" : "", (unsigned long long) fi->fh, fi->flags); fflush(stdout); } - fuse_prepare_interrupt(f, req, &d); + if (fi->flush) { - fuse_flush_common(f->fs, path, fi, &lock, &err, &errlock); - if (err == -ENOSYS && errlock == -ENOSYS) + err = fuse_flush_common(f, req, ino, path, fi); + if (err == -ENOSYS) err = 0; - else if (err == -ENOSYS || !err) - err = errlock; } + + fuse_prepare_interrupt(f, req, &d); fuse_do_release(f, ino, path, fi); fuse_finish_interrupt(f, req, &d); - if (errlock != -ENOSYS) { - flock_to_lock(&lock, &l); - l.owner = fi->lock_owner; - pthread_mutex_lock(&f->lock); - locks_insert(get_node(f, ino), &l); - pthread_mutex_unlock(&f->lock); - } - - if (path) - free(path); + free(path); pthread_rwlock_unlock(&f->tree_lock); reply_err(req, err); @@ -2640,36 +2645,17 @@ static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { struct fuse *f = req_fuse_prepare(req); - struct fuse_intr_data d; - struct flock lock; - struct lock l; char *path; int err; - int errlock; - err = -ENOENT; pthread_rwlock_rdlock(&f->tree_lock); path = get_path(f, ino); if (path && f->conf.debug) { printf("FLUSH[%llu]\n", (unsigned long long) fi->fh); fflush(stdout); } - fuse_prepare_interrupt(f, req, &d); - fuse_flush_common(f->fs, path ? path : "-" , fi, &lock, &err, &errlock); - fuse_finish_interrupt(f, req, &d); - if (errlock != -ENOSYS) { - flock_to_lock(&lock, &l); - l.owner = fi->lock_owner; - pthread_mutex_lock(&f->lock); - locks_insert(get_node(f, ino), &l); - pthread_mutex_unlock(&f->lock); - - /* if op.lock() is defined FLUSH is needed regardless of op.flush() */ - if (err == -ENOSYS) - err = 0; - } - if (path) - free(path); + err = fuse_flush_common(f, req, ino, path, fi); + free(path); pthread_rwlock_unlock(&f->tree_lock); reply_err(req, err); } diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c index 8174e34..1d0677e 100644 --- a/lib/modules/subdir.c +++ b/lib/modules/subdir.c @@ -118,7 +118,7 @@ static void transform_symlink(struct subdir *d, const char *path, return; strip_common(&l, &path); - if (l - buf < d->baselen) + if (l - buf < (long) d->baselen) return; dotdots = count_components(path); -- 2.30.2