From b56120409d4e12a7bbb3e2c2fd0dd51d56ce7286 Mon Sep 17 00:00:00 2001 From: Matej Horvat Date: Sat, 30 Aug 2014 20:02:56 +0200 Subject: [PATCH] Add support for creation times MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Axel Dörfler --- src/add-ons/kernel/file_systems/fat/dir.c | 10 ++++++++ src/add-ons/kernel/file_systems/fat/dosfs.c | 6 +++-- src/add-ons/kernel/file_systems/fat/dosfs.h | 1 + src/add-ons/kernel/file_systems/fat/file.c | 27 ++++++++++++++++++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/file_systems/fat/dir.c b/src/add-ons/kernel/file_systems/fat/dir.c index ff3b881f24..cae6b234e8 100644 --- a/src/add-ons/kernel/file_systems/fat/dir.c +++ b/src/add-ons/kernel/file_systems/fat/dir.c @@ -49,6 +49,7 @@ struct _dirent_info_ { uint32 cluster; uint32 size; uint32 time; + uint32 ctime; }; @@ -195,6 +196,7 @@ _next_dirent_(struct diri *iter, struct _dirent_info_ *oinfo, char *filename, oinfo->cluster += 0x10000*read16(buffer,0x14); oinfo->size = read32(buffer,0x1c); oinfo->time = read32(buffer,0x16); + oinfo->ctime = read32(buffer,0x0e); } diri_next_entry(iter); @@ -582,6 +584,7 @@ struct _entry_info_ { uint32 cluster; uint32 size; time_t time; + time_t ctime; }; @@ -737,6 +740,11 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info, memcpy(buffer, nshort, 11); buffer[0x0b] = info->mode; memset(buffer+0xc, 0, 0x16-0xc); + i = time_t2dos(info->ctime); + buffer[0x0e] = i & 0xff; + buffer[0x0f] = (i >> 8) & 0xff; + buffer[0x10] = (i >> 16) & 0xff; + buffer[0x11] = (i >> 24) & 0xff; i = time_t2dos(info->time); buffer[0x16] = i & 0xff; buffer[0x17] = (i >> 8) & 0xff; @@ -915,6 +923,7 @@ create_dir_entry(nspace *vol, vnode *dir, vnode *node, const char *name, info.cluster = node->cluster; info.size = node->st_size; info.time = node->st_time; + info.ctime = node->st_ctim; return _create_dir_entry_(vol, dir, &info, (char *)nshort, (char *)nlong, len, ns, ne); @@ -1031,6 +1040,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type, } else entry->end_cluster = 0; entry->st_time = dos2time_t(info.time); + entry->st_ctim = dos2time_t(info.ctime); #if TRACK_FILENAME entry->filename = malloc(sizeof(filename) + 1); if (entry->filename) strcpy(entry->filename, filename); diff --git a/src/add-ons/kernel/file_systems/fat/dosfs.c b/src/add-ons/kernel/file_systems/fat/dosfs.c index c53fff3f81..9b5a174f7e 100644 --- a/src/add-ons/kernel/file_systems/fat/dosfs.c +++ b/src/add-ons/kernel/file_systems/fat/dosfs.c @@ -117,7 +117,8 @@ debug_dvnode(int argc, char **argv) ", cluster=%" B_PRIu32 "\n", n->iteration, n->sindex, n->eindex, n->cluster); kprintf("mode %#" B_PRIx32 ", size %" B_PRIdOFF ", time %" B_PRIdTIME - "\n", n->mode, n->st_size, n->st_time); + ", crtime %" B_PRIdTIME "\n", n->mode, n->st_size, n->st_time, + n->st_ctim); kprintf("end cluster = %" B_PRIu32 "\n", n->end_cluster); if (n->mime) kprintf("mime type %s\n", n->mime); } @@ -663,6 +664,7 @@ mount_fat_disk(const char *path, fs_volume *_vol, const int flags, vol->root_vnode.sindex = vol->root_vnode.eindex = 0xffffffff; vol->root_vnode.mode = FAT_SUBDIR; time(&(vol->root_vnode.st_time)); + vol->root_vnode.st_ctim = vol->root_vnode.st_time; vol->root_vnode.mime = NULL; vol->root_vnode.dirty = false; dlist_add(vol, vol->root_vnode.vnid); @@ -1163,7 +1165,7 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, uint32 code, switch (code) { case 10002 : /* return real creation time */ - if (buf) *(bigtime_t *)buf = node->st_time; + if (buf) *(bigtime_t *)buf = node->st_ctim; break; case 10003 : /* return real last modification time */ if (buf) *(bigtime_t *)buf = node->st_time; diff --git a/src/add-ons/kernel/file_systems/fat/dosfs.h b/src/add-ons/kernel/file_systems/fat/dosfs.h index c7dbb20fcd..99e5e44139 100644 --- a/src/add-ons/kernel/file_systems/fat/dosfs.h +++ b/src/add-ons/kernel/file_systems/fat/dosfs.h @@ -86,6 +86,7 @@ typedef struct vnode { uint32 mode; // dos-style attributes off_t st_size; // in bytes time_t st_time; + time_t st_ctim; uint32 end_cluster; // last cluster of the data diff --git a/src/add-ons/kernel/file_systems/fat/file.c b/src/add-ons/kernel/file_systems/fat/file.c index aa2ed8ca6c..4d2f385d97 100644 --- a/src/add-ons/kernel/file_systems/fat/file.c +++ b/src/add-ons/kernel/file_systems/fat/file.c @@ -95,6 +95,11 @@ status_t write_vnode_entry(nspace *vol, vnode *node) buffer[0x0b] = node->mode; // file attributes memset(buffer+0xc, 0, 0x16-0xc); + i = time_t2dos(node->st_ctim); + buffer[0x0e] = i & 0xff; + buffer[0x0f] = (i >> 8) & 0xff; + buffer[0x10] = (i >> 16) & 0xff; + buffer[0x11] = (i >> 24) & 0xff; i = time_t2dos(node->st_time); buffer[0x16] = i & 0xff; buffer[0x17] = (i >> 8) & 0xff; @@ -182,9 +187,10 @@ dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st) st->st_blocks = (node->st_size + 511) / 512; st->st_blksize = 0x10000; /* this value was chosen arbitrarily */ st->st_atim.tv_sec = st->st_mtim.tv_sec = st->st_ctim.tv_sec - = st->st_crtim.tv_sec = node->st_time; + = node->st_time; st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec = st->st_crtim.tv_nsec = 0; + st->st_crtim.tv_sec = node->st_ctim; UNLOCK_VOL(vol); @@ -258,6 +264,14 @@ dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st, dirty = true; } + if (mask & B_STAT_CREATION_TIME) { + DPRINTF(0, ("setting creation time\n")); + // As a file's modification time is also set when it is created, + // the archive bit should be set automatically. + node->st_ctim = st->st_crtime; + dirty = true; + } + if (dirty) { write_vnode_entry(vol, node); @@ -818,6 +832,7 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, dummy.mode = 0; dummy.st_size = 0; time(&(dummy.st_time)); + dummy.st_ctim = dummy.st_time; if ((result = create_dir_entry(vol, dir, &dummy, name, &(dummy.sindex), &(dummy.eindex))) != B_OK) { dprintf("dosfs_create: error creating directory entry for %s (%s)\n", name, strerror(result)); @@ -920,6 +935,7 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) } dummy.st_size = vol->bytes_per_sector*vol->sectors_per_cluster; time(&(dummy.st_time)); + dummy.st_ctim = dummy.st_time; dummy.vnid = GENERATE_DIR_CLUSTER_VNID(dummy.dir_vnid, dummy.cluster); // XXX: dangerous construct @@ -952,10 +968,19 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) buffer[0] = buffer[0x20] = buffer[0x21] = '.'; buffer[0x0b] = buffer[0x2b] = FAT_SUBDIR; i = time_t2dos(dummy.st_time); + buffer[0x0e] = i & 0xff; + buffer[0x0f] = (i >> 8) & 0xff; + buffer[0x10] = (i >> 16) & 0xff; + buffer[0x11] = (i >> 24) & 0xff; buffer[0x16] = i & 0xff; buffer[0x17] = (i >> 8) & 0xff; buffer[0x18] = (i >> 16) & 0xff; buffer[0x19] = (i >> 24) & 0xff; + i = time_t2dos(dir->st_ctim); + buffer[0x2e] = i & 0xff; + buffer[0x2f] = (i >> 8) & 0xff; + buffer[0x30] = (i >> 16) & 0xff; + buffer[0x31] = (i >> 24) & 0xff; i = time_t2dos(dir->st_time); buffer[0x36] = i & 0xff; buffer[0x37] = (i >> 8) & 0xff;