From 0400457755e6b5267e730ab5163733edf58539fa Mon Sep 17 00:00:00 2001
From: Matej Horvat <matej.horvat@guest.arnes.si>
Date: Sat, 30 Aug 2014 20:02:56 +0200
Subject: [PATCH] Add support for creation times
---
src/add-ons/kernel/file_systems/fat/dir.c | 10 ++++++++++
src/add-ons/kernel/file_systems/fat/dosfs.c | 7 ++++---
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(+), 4 deletions(-)
diff --git a/src/add-ons/kernel/file_systems/fat/dir.c b/src/add-ons/kernel/file_systems/fat/dir.c
index 96753be..62eddab 100644
a
|
b
|
struct _dirent_info_ {
|
49 | 49 | uint32 cluster; |
50 | 50 | uint32 size; |
51 | 51 | uint32 time; |
| 52 | uint32 ctime; |
52 | 53 | }; |
53 | 54 | |
54 | 55 | |
… |
… |
_next_dirent_(struct diri *iter, struct _dirent_info_ *oinfo, char *filename,
|
195 | 196 | oinfo->cluster += 0x10000*read16(buffer,0x14); |
196 | 197 | oinfo->size = read32(buffer,0x1c); |
197 | 198 | oinfo->time = read32(buffer,0x16); |
| 199 | oinfo->ctime = read32(buffer,0x0e); |
198 | 200 | } |
199 | 201 | |
200 | 202 | diri_next_entry(iter); |
… |
… |
struct _entry_info_ {
|
578 | 580 | uint32 cluster; |
579 | 581 | uint32 size; |
580 | 582 | time_t time; |
| 583 | time_t ctime; |
581 | 584 | }; |
582 | 585 | |
583 | 586 | |
… |
… |
_create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info,
|
728 | 731 | memcpy(buffer, nshort, 11); |
729 | 732 | buffer[0x0b] = info->mode; |
730 | 733 | memset(buffer+0xc, 0, 0x16-0xc); |
| 734 | i = time_t2dos(info->ctime); |
| 735 | buffer[0x0e] = i & 0xff; |
| 736 | buffer[0x0f] = (i >> 8) & 0xff; |
| 737 | buffer[0x10] = (i >> 16) & 0xff; |
| 738 | buffer[0x11] = (i >> 24) & 0xff; |
731 | 739 | i = time_t2dos(info->time); |
732 | 740 | buffer[0x16] = i & 0xff; |
733 | 741 | buffer[0x17] = (i >> 8) & 0xff; |
… |
… |
create_dir_entry(nspace *vol, vnode *dir, vnode *node, const char *name,
|
905 | 913 | info.cluster = node->cluster; |
906 | 914 | info.size = node->st_size; |
907 | 915 | info.time = node->st_time; |
| 916 | info.ctime = node->st_ctim; |
908 | 917 | |
909 | 918 | return _create_dir_entry_(vol, dir, &info, (char *)nshort, |
910 | 919 | (char *)nlong, len, ns, ne); |
… |
… |
dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
|
1020 | 1029 | } else |
1021 | 1030 | entry->end_cluster = 0; |
1022 | 1031 | entry->st_time = dos2time_t(info.time); |
| 1032 | entry->st_ctim = dos2time_t(info.ctime); |
1023 | 1033 | #if TRACK_FILENAME |
1024 | 1034 | entry->filename = malloc(sizeof(filename) + 1); |
1025 | 1035 | 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 f088e3a..f89b182 100644
a
|
b
|
debug_dvnode(int argc, char **argv)
|
111 | 111 | kprintf("\nvnid %Lx, dir vnid %Lx\n", n->vnid, n->dir_vnid); |
112 | 112 | kprintf("iteration %lx, si=%lx, ei=%lx, cluster=%lx\n", |
113 | 113 | n->iteration, n->sindex, n->eindex, n->cluster); |
114 | | kprintf("mode %lx, size %Lx, time %lx\n", |
115 | | n->mode, n->st_size, n->st_time); |
| 114 | kprintf("mode %lx, size %Lx, time %lx, ctim %lx\n", |
| 115 | n->mode, n->st_size, n->st_time, n->st_ctim); |
116 | 116 | kprintf("end cluster = %lx\n", n->end_cluster); |
117 | 117 | if (n->mime) kprintf("mime type %s\n", n->mime); |
118 | 118 | } |
… |
… |
mount_fat_disk(const char *path, fs_volume *_vol, const int flags,
|
651 | 651 | vol->root_vnode.sindex = vol->root_vnode.eindex = 0xffffffff; |
652 | 652 | vol->root_vnode.mode = FAT_SUBDIR; |
653 | 653 | time(&(vol->root_vnode.st_time)); |
| 654 | vol->root_vnode.st_ctim = vol->root_vnode.st_time; |
654 | 655 | vol->root_vnode.mime = NULL; |
655 | 656 | vol->root_vnode.dirty = false; |
656 | 657 | dlist_add(vol, vol->root_vnode.vnid); |
… |
… |
dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, uint32 code,
|
1151 | 1152 | |
1152 | 1153 | switch (code) { |
1153 | 1154 | case 10002 : /* return real creation time */ |
1154 | | if (buf) *(bigtime_t *)buf = node->st_time; |
| 1155 | if (buf) *(bigtime_t *)buf = node->st_ctim; |
1155 | 1156 | break; |
1156 | 1157 | case 10003 : /* return real last modification time */ |
1157 | 1158 | 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 70fc386..0340ca3 100644
a
|
b
|
typedef struct vnode {
|
86 | 86 | uint32 mode; // dos-style attributes |
87 | 87 | off_t st_size; // in bytes |
88 | 88 | time_t st_time; |
| 89 | time_t st_ctim; |
89 | 90 | |
90 | 91 | uint32 end_cluster; // last cluster of the data |
91 | 92 | |
diff --git a/src/add-ons/kernel/file_systems/fat/file.c b/src/add-ons/kernel/file_systems/fat/file.c
index 5d5f028..51a2a7c 100644
a
|
b
|
status_t write_vnode_entry(nspace *vol, vnode *node)
|
94 | 94 | buffer[0x0b] = node->mode; // file attributes |
95 | 95 | |
96 | 96 | memset(buffer+0xc, 0, 0x16-0xc); |
| 97 | i = time_t2dos(node->st_ctim); |
| 98 | buffer[0x0e] = i & 0xff; |
| 99 | buffer[0x0f] = (i >> 8) & 0xff; |
| 100 | buffer[0x10] = (i >> 16) & 0xff; |
| 101 | buffer[0x11] = (i >> 24) & 0xff; |
97 | 102 | i = time_t2dos(node->st_time); |
98 | 103 | buffer[0x16] = i & 0xff; |
99 | 104 | buffer[0x17] = (i >> 8) & 0xff; |
… |
… |
dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st)
|
181 | 186 | st->st_blocks = (node->st_size + 511) / 512; |
182 | 187 | st->st_blksize = 0x10000; /* this value was chosen arbitrarily */ |
183 | 188 | st->st_atim.tv_sec = st->st_mtim.tv_sec = st->st_ctim.tv_sec |
184 | | = st->st_crtim.tv_sec = node->st_time; |
| 189 | = node->st_time; |
185 | 190 | st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec |
186 | 191 | = st->st_crtim.tv_nsec = 0; |
| 192 | st->st_crtim.tv_sec = node->st_ctim; |
187 | 193 | |
188 | 194 | UNLOCK_VOL(vol); |
189 | 195 | |
… |
… |
dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st,
|
254 | 260 | dirty = true; |
255 | 261 | } |
256 | 262 | |
| 263 | if (mask & B_STAT_CREATION_TIME) { |
| 264 | DPRINTF(0, ("setting creation time\n")); |
| 265 | // As a file's modification time is also set when it is created, |
| 266 | // the archive bit should be set automatically. |
| 267 | node->st_ctim = st->st_crtime; |
| 268 | dirty = true; |
| 269 | } |
| 270 | |
257 | 271 | if (dirty) { |
258 | 272 | write_vnode_entry(vol, node); |
259 | 273 | |
… |
… |
dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
|
806 | 820 | dummy.mode = 0; |
807 | 821 | dummy.st_size = 0; |
808 | 822 | time(&(dummy.st_time)); |
| 823 | dummy.st_ctim = dummy.st_time; |
809 | 824 | |
810 | 825 | if ((result = create_dir_entry(vol, dir, &dummy, name, &(dummy.sindex), &(dummy.eindex))) != B_OK) { |
811 | 826 | dprintf("dosfs_create: error creating directory entry for %s (%s)\n", name, strerror(result)); |
… |
… |
dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
|
906 | 921 | } |
907 | 922 | dummy.st_size = vol->bytes_per_sector*vol->sectors_per_cluster; |
908 | 923 | time(&(dummy.st_time)); |
| 924 | dummy.st_ctim = dummy.st_time; |
909 | 925 | |
910 | 926 | dummy.vnid = GENERATE_DIR_CLUSTER_VNID(dummy.dir_vnid, dummy.cluster); |
911 | 927 | // XXX: dangerous construct |
… |
… |
dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
|
938 | 954 | buffer[0] = buffer[0x20] = buffer[0x21] = '.'; |
939 | 955 | buffer[0x0b] = buffer[0x2b] = FAT_SUBDIR; |
940 | 956 | i = time_t2dos(dummy.st_time); |
| 957 | buffer[0x0e] = i & 0xff; |
| 958 | buffer[0x0f] = (i >> 8) & 0xff; |
| 959 | buffer[0x10] = (i >> 16) & 0xff; |
| 960 | buffer[0x11] = (i >> 24) & 0xff; |
941 | 961 | buffer[0x16] = i & 0xff; |
942 | 962 | buffer[0x17] = (i >> 8) & 0xff; |
943 | 963 | buffer[0x18] = (i >> 16) & 0xff; |
944 | 964 | buffer[0x19] = (i >> 24) & 0xff; |
| 965 | i = time_t2dos(dir->st_ctim); |
| 966 | buffer[0x2e] = i & 0xff; |
| 967 | buffer[0x2f] = (i >> 8) & 0xff; |
| 968 | buffer[0x30] = (i >> 16) & 0xff; |
| 969 | buffer[0x31] = (i >> 24) & 0xff; |
945 | 970 | i = time_t2dos(dir->st_time); |
946 | 971 | buffer[0x36] = i & 0xff; |
947 | 972 | buffer[0x37] = (i >> 8) & 0xff; |