summaryrefslogtreecommitdiffstats
path: root/sdcard/sdcard.c
diff options
context:
space:
mode:
authorKen Sumrall <ksumrall@android.com>2011-03-18 11:53:15 -0700
committerKen Sumrall <ksumrall@android.com>2011-03-24 18:29:41 -0700
commit97919656803126c6b28ea6070fc86d124ac4ef4b (patch)
tree5fec857e44ccc72f5acf156f7f97b948b8779367 /sdcard/sdcard.c
parentf642c3d12f4cffdc349b9ebfc4107de254ad8db9 (diff)
downloadcore-97919656803126c6b28ea6070fc86d124ac4ef4b.tar.gz
core-97919656803126c6b28ea6070fc86d124ac4ef4b.tar.bz2
core-97919656803126c6b28ea6070fc86d124ac4ef4b.zip
Add support for the utime(2) family of system calls to the sdcard fuse filesystem.
Add support for the utime(2) family of system calls to change the modify and access time of files. Requires an updated bionic with support for the utimensat(2) system call. Change-Id: I8cc0c0e6671c5708849752f47e4c3d4be2858b61
Diffstat (limited to 'sdcard/sdcard.c')
-rw-r--r--sdcard/sdcard.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 0b8f656c5..7112ebf51 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;