From c3b76815f753b8303a16f7f394748948665c75ba Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sat, 16 Sep 2006 08:52:09 +0000 Subject: [PATCH] fix --- ChangeLog | 9 ++++ README | 5 +- example/fusexmp.c | 4 +- example/fusexmp_fh.c | 4 +- include/fuse.h | 2 +- lib/fuse.c | 17 ++++--- test/test.c | 107 +++++++++++++++++++++++++++++++++++-------- 7 files changed, 113 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad21e97..eedd12d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-09-16 Miklos Szeredi + + * Rename new utimes() method to more logical utimens() + +2006-09-14 Miklos Szeredi + + * Fuse tried to unlink already unlinked hidden files. Bug + reported by Milan Svoboda + 2006-09-10 Miklos Szeredi * Released 2.6.0-rc1 diff --git a/README b/README index 6333943..5d537b7 100644 --- a/README +++ b/README @@ -11,11 +11,10 @@ You can download the source code releases from http://sourceforge.net/projects/fuse or alternatively you can use CVS to get the very latest development -version by setting the cvsroot to +version: - :pserver:anonymous@cvs.sourceforge.net:/cvsroot/fuse + cvs -d :pserver:anonymous@fuse.cvs.sourceforge.net:/cvsroot/fuse co fuse -and checking out the 'fuse' module. Dependencies ============ diff --git a/example/fusexmp.c b/example/fusexmp.c index 5f54667..b32e236 100644 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -205,7 +205,7 @@ static int xmp_truncate(const char *path, off_t size) return 0; } -static int xmp_utimes(const char *path, const struct timespec ts[2]) +static int xmp_utimens(const char *path, const struct timespec ts[2]) { int res; struct timeval tv[2]; @@ -357,7 +357,7 @@ static struct fuse_operations xmp_oper = { .chmod = xmp_chmod, .chown = xmp_chown, .truncate = xmp_truncate, - .utimes = xmp_utimes, + .utimens = xmp_utimens, .open = xmp_open, .read = xmp_read, .write = xmp_write, diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c index 047ad09..9bf0d25 100644 --- a/example/fusexmp_fh.c +++ b/example/fusexmp_fh.c @@ -241,7 +241,7 @@ static int xmp_ftruncate(const char *path, off_t size, return 0; } -static int xmp_utimes(const char *path, const struct timespec ts[2]) +static int xmp_utimens(const char *path, const struct timespec ts[2]) { int res; struct timeval tv[2]; @@ -428,7 +428,7 @@ static struct fuse_operations xmp_oper = { .chown = xmp_chown, .truncate = xmp_truncate, .ftruncate = xmp_ftruncate, - .utimes = xmp_utimes, + .utimens = xmp_utimens, .create = xmp_create, .open = xmp_open, .read = xmp_read, diff --git a/include/fuse.h b/include/fuse.h index 6a25052..1e0bd3c 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -407,7 +407,7 @@ struct fuse_operations { * * Introduced in version 2.6 */ - int (*utimes) (const char *, const struct timespec tv[2]); + int (*utimens) (const char *, const struct timespec tv[2]); }; /** Extra context that may be needed by some filesystems diff --git a/lib/fuse.c b/lib/fuse.c index 92f21db..8c507d9 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -1018,19 +1018,19 @@ static int do_truncate(struct fuse *f, fuse_req_t req, const char *path, return err; } -static int do_utimes(struct fuse *f, fuse_req_t req, const char *path, - struct stat *attr) +static int do_utimens(struct fuse *f, fuse_req_t req, const char *path, + struct stat *attr) { int err; struct fuse_intr_data d; err = -ENOSYS; - if (f->op.utimes) { + if (f->op.utimens) { struct timespec tv[2]; tv[0] = attr->st_atim; tv[1] = attr->st_mtim; fuse_prepare_interrupt(f, req, &d); - err = f->op.utimes(path, tv); + err = f->op.utimens(path, tv); fuse_finish_interrupt(f, req, &d); } else if (f->op.utime) { struct utimbuf buf; @@ -1066,7 +1066,7 @@ static void fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, if (!err && (valid & FUSE_SET_ATTR_SIZE)) err = do_truncate(f, req, path, attr, fi); if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) - err = do_utimes(f, req, path, attr); + err = do_utimens(f, req, path, attr); if (!err) err = fuse_do_getattr(f, req, path, &buf); } @@ -1621,7 +1621,7 @@ static void fuse_release(fuse_req_t req, fuse_ino_t ino, struct fuse *f = req_fuse_prepare(req); char *path; struct node *node; - int unlink_hidden; + int unlink_hidden = 0; pthread_rwlock_rdlock(&f->tree_lock); path = get_path(f, ino); @@ -1637,7 +1637,10 @@ static void fuse_release(fuse_req_t req, fuse_ino_t ino, node = get_node(f, ino); assert(node->open_count > 0); --node->open_count; - unlink_hidden = (node->is_hidden && !node->open_count); + if (node->is_hidden && !node->open_count) { + unlink_hidden = 1; + node->is_hidden = 0; + } pthread_mutex_unlock(&f->lock); if(unlink_hidden && path) diff --git a/test/test.c b/test/test.c index 6a82467..bbe937e 100644 --- a/test/test.c +++ b/test/test.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,29 @@ static int check_mode(const char *path, mode_t mode) return 0; } +static int check_times(const char *path, time_t atime, time_t mtime) +{ + int err = 0; + struct stat stbuf; + int res = lstat(path, &stbuf); + if (res == -1) { + PERROR("lstat"); + return -1; + } + if (stbuf.st_atime != atime) { + ERROR("atime %li instead of %li", stbuf.st_atime, atime); + err--; + } + if (stbuf.st_mtime != mtime) { + ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime); + err--; + } + if (err) + return -1; + + return 0; +} + static int check_nlink(const char *path, nlink_t nlink) { struct stat stbuf; @@ -271,16 +295,18 @@ static int create_file(const char *path, const char *data, int len) PERROR("creat"); return -1; } - res = write(fd, data, len); - if (res == -1) { - PERROR("write"); - close(fd); - return -1; - } - if (res != len) { - ERROR("write is short: %u instead of %u", res, len); - close(fd); - return -1; + if (len) { + res = write(fd, data, len); + if (res == -1) { + PERROR("write"); + close(fd); + return -1; + } + if (res != len) { + ERROR("write is short: %u instead of %u", res, len); + close(fd); + return -1; + } } res = close(fd); if (res == -1) { @@ -300,9 +326,11 @@ static int create_file(const char *path, const char *data, int len) if (res == -1) return -1; - res = check_data(path, data, 0, len); - if (res == -1) - return -1; + if (len) { + res = check_data(path, data, 0, len); + if (res == -1) + return -1; + } return 0; } @@ -364,7 +392,7 @@ static int create_dir(const char *path, const char **dir_files) return 0; } -int test_truncate(int len) +static int test_truncate(int len) { const char *data = testdata; int datalen = testdatalen; @@ -403,7 +431,7 @@ int test_truncate(int len) PERROR("unlink"); return -1; } - res = check_nonexist(testfile2); + res = check_nonexist(testfile); if (res == -1) return -1; @@ -411,7 +439,7 @@ int test_truncate(int len) return 0; } -int test_ftruncate(int len, int mode) +static int test_ftruncate(int len, int mode) { const char *data = testdata; int datalen = testdatalen; @@ -470,7 +498,43 @@ int test_ftruncate(int len, int mode) PERROR("unlink"); return -1; } - res = check_nonexist(testfile2); + res = check_nonexist(testfile); + if (res == -1) + return -1; + + success(); + return 0; +} + +static int test_utime(void) +{ + struct utimbuf utm; + time_t atime = 987631200; + time_t mtime = 123116400; + int res; + + start_test("utime"); + res = create_file(testfile, NULL, 0); + if (res == -1) + return -1; + + utm.actime = atime; + utm.modtime = mtime; + res = utime(testfile, &utm); + if (res == -1) { + PERROR("utime"); + return -1; + } + res = check_times(testfile, atime, mtime); + if (res == -1) { + return -1; + } + res = unlink(testfile); + if (res == -1) { + PERROR("unlink"); + return -1; + } + res = check_nonexist(testfile); if (res == -1) return -1; @@ -865,7 +929,7 @@ static int test_rename_dir(void) return 0; } -int test_mkfifo(void) +static int test_mkfifo(void) { int res; int err = 0; @@ -897,7 +961,7 @@ int test_mkfifo(void) return 0; } -int test_mkdir(void) +static int test_mkdir(void) { int res; int err = 0; @@ -954,6 +1018,7 @@ int main(int argc, char *argv[]) err += test_mkdir(); err += test_rename_file(); err += test_rename_dir(); + err += test_utime(); err += test_truncate(0); err += test_truncate(testdatalen / 2); err += test_truncate(testdatalen); @@ -1007,8 +1072,10 @@ int main(int argc, char *argv[]) rmdir(testdir); rmdir(testdir2); - if (err) + if (err) { + fprintf(stderr, "%i tests failed\n", -err); return 1; + } return 0; } -- 2.30.2