Android-x86
Fork
Spenden

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-exfat: Commit

external/exfat


Commit MetaInfo

Revision75f28b558a1a86b45308a3e7d0af222624bc2c61 (tree)
Zeit2019-04-21 03:14:49
AutorNathan Hunsperger <nathan@huns...>
Commiterrelan

Log Message

Add support for timezone offsets.

Timestamps are stored in local time. exFAT includes timezone offset
fields to allow timestamps to remain correct when mounted under a
different timezone. The timezone offset is now used to calculate the
correct timestamp on read, and set on write.

Ändern Zusammenfassung

Diff

--- a/libexfat/exfat.h
+++ b/libexfat/exfat.h
@@ -228,9 +228,10 @@ int exfat_set_label(struct exfat* ef, const char* label);
228228 int exfat_mount(struct exfat* ef, const char* spec, const char* options);
229229 void exfat_unmount(struct exfat* ef);
230230
231-time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec);
231+time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec,
232+ uint8_t tzoffset);
232233 void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
233- uint8_t* centisec);
234+ uint8_t* centisec, uint8_t* tzoffset);
234235 void exfat_tzset(void);
235236
236237 bool exfat_ask_to_fix(const struct exfat* ef);
--- a/libexfat/exfatfs.h
+++ b/libexfat/exfatfs.h
@@ -144,7 +144,8 @@ struct exfat_entry_meta1 /* file or directory info (part 1) */
144144 le16_t atime, adate; /* latest access date and time */
145145 uint8_t crtime_cs; /* creation time in cs (centiseconds) */
146146 uint8_t mtime_cs; /* latest modification time in cs */
147- uint8_t __unknown2[10];
147+ uint8_t crtime_tzo, mtime_tzo, atime_tzo; /* timezone offset encoded */
148+ uint8_t __unknown2[7];
148149 }
149150 PACKED;
150151 STATIC_ASSERT(sizeof(struct exfat_entry_meta1) == 32);
--- a/libexfat/node.c
+++ b/libexfat/node.c
@@ -135,9 +135,10 @@ static void init_node_meta1(struct exfat_node* node,
135135 node->attrib = le16_to_cpu(meta1->attrib);
136136 node->continuations = meta1->continuations;
137137 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
138- meta1->mtime_cs);
138+ meta1->mtime_cs, meta1->mtime_tzo);
139139 /* there is no centiseconds field for atime */
140- node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
140+ node->atime = exfat_exfat2unix(meta1->adate, meta1->atime,
141+ 0, meta1->atime_tzo);
141142 }
142143
143144 static void init_node_meta2(struct exfat_node* node,
@@ -646,8 +647,9 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
646647
647648 meta1->attrib = cpu_to_le16(node->attrib);
648649 exfat_unix2exfat(node->mtime, &meta1->mdate, &meta1->mtime,
649- &meta1->mtime_cs);
650- exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime, NULL);
650+ &meta1->mtime_cs, &meta1->mtime_tzo);
651+ exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime,
652+ NULL, &meta1->atime_tzo);
651653 meta2->size = meta2->valid_size = cpu_to_le64(node->size);
652654 meta2->start_cluster = cpu_to_le32(node->start_cluster);
653655 meta2->flags = EXFAT_FLAG_ALWAYS1;
@@ -895,10 +897,11 @@ static int commit_entry(struct exfat* ef, struct exfat_node* dir,
895897 meta1->continuations = 1 + name_entries;
896898 meta1->attrib = cpu_to_le16(attrib);
897899 exfat_unix2exfat(time(NULL), &meta1->crdate, &meta1->crtime,
898- &meta1->crtime_cs);
900+ &meta1->crtime_cs, &meta1->crtime_tzo);
899901 meta1->adate = meta1->mdate = meta1->crdate;
900902 meta1->atime = meta1->mtime = meta1->crtime;
901903 meta1->mtime_cs = meta1->crtime_cs; /* there is no atime_cs */
904+ meta1->atime_tzo = meta1->mtime_tzo = meta1->crtime_tzo;
902905
903906 meta2->type = EXFAT_ENTRY_FILE_INFO;
904907 meta2->flags = EXFAT_FLAG_ALWAYS1;
--- a/libexfat/time.c
+++ b/libexfat/time.c
@@ -53,7 +53,8 @@ static const time_t days_in_year[] =
5353 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
5454 };
5555
56-time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec)
56+time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec,
57+ uint8_t tzoffset)
5758 {
5859 time_t unix_time = EPOCH_DIFF_SEC;
5960 uint16_t ndate = le16_to_cpu(date);
@@ -100,13 +101,18 @@ time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec)
100101 unix_time += centisec / 100;
101102
102103 /* exFAT stores timestamps in local time, so we correct it to UTC */
103- unix_time += exfat_timezone;
104+ if (tzoffset & 0x80)
105+ /* lower 7 bits are signed timezone offset in 15 minute increments */
106+ unix_time -= (int8_t)(tzoffset << 1) * 15 * 60 / 2;
107+ else
108+ /* timezone offset not present, assume our local timezone */
109+ unix_time += exfat_timezone;
104110
105111 return unix_time;
106112 }
107113
108114 void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
109- uint8_t* centisec)
115+ uint8_t* centisec, uint8_t* tzoffset)
110116 {
111117 time_t shift = EPOCH_DIFF_SEC + exfat_timezone;
112118 uint16_t day, month, year;
@@ -146,6 +152,9 @@ void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
146152 *time = cpu_to_le16(twosec | (min << 5) | (hour << 11));
147153 if (centisec)
148154 *centisec = (unix_time % 2) * 100;
155+
156+ /* record our local timezone offset in exFAT (15 minute increment) format */
157+ *tzoffset = (uint8_t)(-exfat_timezone / 60 / 15) | 0x80;
149158 }
150159
151160 void exfat_tzset(void)
Show on old repository browser