aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2012-04-10 16:37:03 +0200
committerMiklos Szeredi <mszeredi@suse.cz>2012-04-10 16:37:03 +0200
commit71bfb92607ce2312c8adb7359a6d883473c51748 (patch)
treef7c5a7c5d493a40cc1b56e4932aa93805e71cd7a
parent6f77e7de6f0ad9a8d6991c213841c926acc53a96 (diff)
downloadandroid_external_fuse-71bfb92607ce2312c8adb7359a6d883473c51748.tar.gz
android_external_fuse-71bfb92607ce2312c8adb7359a6d883473c51748.tar.bz2
android_external_fuse-71bfb92607ce2312c8adb7359a6d883473c51748.zip
Add 'flag_utime_omit_ok' flag to fuse_operations
If the filesystem sets this flag then ->utimens() will receive UTIME_OMIT and UTIME_NOW values as specified in utimensat(2).
-rw-r--r--ChangeLog4
-rw-r--r--example/fusexmp_fh.c3
-rw-r--r--include/fuse.h8
-rw-r--r--lib/fuse.c27
4 files changed, 41 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index fab6ee1..c8d9323 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
* Check protocol version before sending notifications and return
-ENOSYS if a particular notification is not supported.
+ * Add 'flag_utime_omit_ok' flag to fuse_operations. If the
+ filesystem sets this flag then ->utimens() will receive UTIME_OMIT
+ and UTIME_NOW values as specified in utimensat(2).
+
2012-01-27 Miklos Szeredi <miklos@szeredi.hu>
* Interpret octal escape codes in options. Requested by Jan
diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c
index 57053ca..e9524c6 100644
--- a/example/fusexmp_fh.c
+++ b/example/fusexmp_fh.c
@@ -539,6 +539,9 @@ static struct fuse_operations xmp_oper = {
.flock = xmp_flock,
.flag_nullpath_ok = 1,
+#if HAVE_UTIMENSAT
+ .flag_utime_omit_ok = 1,
+#endif
};
int main(int argc, char *argv[])
diff --git a/include/fuse.h b/include/fuse.h
index b05152d..36b168c 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -480,9 +480,15 @@ struct fuse_operations {
unsigned int flag_nopath:1;
/**
+ * Flag indicating that the filesystem accepts special
+ * UTIME_NOW and UTIME_OMIT values in its utimens operation.
+ */
+ unsigned int flag_utime_omit_ok:1;
+
+ /**
* Reserved flags, don't set
*/
- unsigned int flag_reserved:30;
+ unsigned int flag_reserved:29;
/**
* Ioctl
diff --git a/lib/fuse.c b/lib/fuse.c
index e01f450..4922361 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -132,6 +132,7 @@ struct fuse {
int intr_installed;
struct fuse_fs *fs;
int nullpath_ok;
+ int utime_omit_ok;
int curr_ticket;
struct lock_queue_element *lockq;
int pagesize;
@@ -2720,6 +2721,29 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
err = fuse_fs_truncate(f->fs, path,
attr->st_size);
}
+#ifdef HAVE_UTIMENSAT
+ if (!err && f->utime_omit_ok &&
+ (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
+ struct timespec tv[2];
+
+ tv[0].tv_sec = 0;
+ tv[1].tv_sec = 0;
+ tv[0].tv_nsec = UTIME_OMIT;
+ tv[1].tv_nsec = UTIME_OMIT;
+
+ if (valid & FUSE_SET_ATTR_ATIME_NOW)
+ tv[0].tv_nsec = UTIME_NOW;
+ else if (valid & FUSE_SET_ATTR_ATIME)
+ tv[0] = attr->st_atim;
+
+ if (valid & FUSE_SET_ATTR_MTIME_NOW)
+ tv[1].tv_nsec = UTIME_NOW;
+ else if (valid & FUSE_SET_ATTR_MTIME)
+ tv[1] = attr->st_mtim;
+
+ err = fuse_fs_utimens(f->fs, path, tv);
+ } else
+#endif
if (!err &&
(valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
(FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
@@ -4401,6 +4425,7 @@ static int fuse_push_module(struct fuse *f, const char *module,
f->fs = newfs;
f->nullpath_ok = newfs->op.flag_nullpath_ok && f->nullpath_ok;
f->conf.nopath = newfs->op.flag_nopath && f->conf.nopath;
+ f->utime_omit_ok = newfs->op.flag_utime_omit_ok && f->utime_omit_ok;
return 0;
}
@@ -4496,6 +4521,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
f->fs = fs;
f->nullpath_ok = fs->op.flag_nullpath_ok;
f->conf.nopath = fs->op.flag_nopath;
+ f->utime_omit_ok = fs->op.flag_utime_omit_ok;
/* Oh f**k, this is ugly! */
if (!fs->op.lock) {
@@ -4560,6 +4586,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
if (f->conf.debug) {
fprintf(stderr, "nullpath_ok: %i\n", f->nullpath_ok);
fprintf(stderr, "nopath: %i\n", f->conf.nopath);
+ fprintf(stderr, "utime_omit_ok: %i\n", f->utime_omit_ok);
}
/* Trace topmost layer by default */