diff options
| author | Ken Sumrall <ksumrall@android.com> | 2011-03-24 22:35:37 -0700 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2011-03-24 22:35:37 -0700 |
| commit | b26662c0a2876767b2c06cb740f07b1010f91548 (patch) | |
| tree | 5fec857e44ccc72f5acf156f7f97b948b8779367 | |
| parent | 5c8cc8036cd2565ccf541f87b192a7c7a74f42e4 (diff) | |
| parent | c3e69903ed5f9e406fe51093fc41917512aa4036 (diff) | |
| download | system_core-b26662c0a2876767b2c06cb740f07b1010f91548.tar.gz system_core-b26662c0a2876767b2c06cb740f07b1010f91548.tar.bz2 system_core-b26662c0a2876767b2c06cb740f07b1010f91548.zip | |
am c3e69903: am 97919656: Add support for the utime(2) family of system calls to the sdcard fuse filesystem.
* commit 'c3e69903ed5f9e406fe51093fc41917512aa4036':
Add support for the utime(2) family of system calls to the sdcard fuse filesystem.
| -rw-r--r-- | sdcard/sdcard.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c index 0b8f656c..7112ebf5 100644 --- a/sdcard/sdcard.c +++ b/sdcard/sdcard.c @@ -581,17 +581,50 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da struct fuse_attr_out out; char *path, buffer[PATH_BUFFER_SIZE]; int res = 0; + struct timespec times[2]; TRACE("SETATTR fh=%llx id=%llx valid=%x\n", req->fh, hdr->nodeid, req->valid); - /* XXX: incomplete implementation -- truncate only. chmod/chown - * should NEVER be implemented. */ + /* XXX: incomplete implementation on purpose. chmod/chown + * should NEVER be implemented.*/ path = node_get_path(node, buffer, 0); if (req->valid & FATTR_SIZE) res = truncate(path, req->size); + if (res) + goto getout; + + /* Handle changing atime and mtime. If FATTR_ATIME_and FATTR_ATIME_NOW + * are both set, then set it to the current time. Else, set it to the + * time specified in the request. Same goes for mtime. Use utimensat(2) + * as it allows ATIME and MTIME to be changed independently, and has + * nanosecond resolution which fuse also has. + */ + if (req->valid & (FATTR_ATIME | FATTR_MTIME)) { + times[0].tv_nsec = UTIME_OMIT; + times[1].tv_nsec = UTIME_OMIT; + if (req->valid & FATTR_ATIME) { + if (req->valid & FATTR_ATIME_NOW) { + times[0].tv_nsec = UTIME_NOW; + } else { + times[0].tv_sec = req->atime; + times[0].tv_nsec = req->atimensec; + } + } + if (req->valid & FATTR_MTIME) { + if (req->valid & FATTR_MTIME_NOW) { + times[1].tv_nsec = UTIME_NOW; + } else { + times[1].tv_sec = req->mtime; + times[1].tv_nsec = req->mtimensec; + } + } + TRACE("Calling utimensat on %s with atime %ld, mtime=%ld\n", path, times[0].tv_sec, times[1].tv_sec); + res = utimensat(-1, path, times, 0); + } + getout: memset(&out, 0, sizeof(out)); node_get_attr(node, &out.attr); out.attr_valid = 10; |
