diff options
author | Jan Kara <jack@suse.cz> | 2017-06-14 03:51:20 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2017-06-14 05:21:02 -0400 |
commit | 3c399fa40fd13c5749386695e71f5f747a634f21 (patch) | |
tree | e0c45b2c241eb8f3e6c4df347f172a54c175455e | |
parent | f2e95355891153f66d4156bf3a142c6489cd78c6 (diff) |
udf: Use time64_to_tm for timestamp conversion
UDF on-disk time stamp is stored in a form very similar to struct tm.
Use time64_to_tm() for conversion of seconds since epoch to year, month,
... format and then just copy this as necessary to UDF on-disk
structure to simplify the code.
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | fs/udf/udftime.c | 45 |
1 files changed, 11 insertions, 34 deletions
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index 77c331f1a770..b9dadc7e5c35 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
41 | #include <linux/time.h> | ||
41 | 42 | ||
42 | #define EPOCH_YEAR 1970 | 43 | #define EPOCH_YEAR 1970 |
43 | 44 | ||
@@ -81,9 +82,6 @@ static time_t year_seconds[MAX_YEAR_SECONDS] = { | |||
81 | /*2038*/ SPY(68, 17, 0) | 82 | /*2038*/ SPY(68, 17, 0) |
82 | }; | 83 | }; |
83 | 84 | ||
84 | #define SECS_PER_HOUR (60 * 60) | ||
85 | #define SECS_PER_DAY (SECS_PER_HOUR * 24) | ||
86 | |||
87 | struct timespec * | 85 | struct timespec * |
88 | udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src) | 86 | udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src) |
89 | { | 87 | { |
@@ -119,9 +117,9 @@ udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src) | |||
119 | struct timestamp * | 117 | struct timestamp * |
120 | udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts) | 118 | udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts) |
121 | { | 119 | { |
122 | long int days, rem, y; | 120 | long seconds; |
123 | const unsigned short int *ip; | ||
124 | int16_t offset; | 121 | int16_t offset; |
122 | struct tm tm; | ||
125 | 123 | ||
126 | offset = -sys_tz.tz_minuteswest; | 124 | offset = -sys_tz.tz_minuteswest; |
127 | 125 | ||
@@ -130,35 +128,14 @@ udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts) | |||
130 | 128 | ||
131 | dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF)); | 129 | dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF)); |
132 | 130 | ||
133 | ts.tv_sec += offset * 60; | 131 | seconds = ts.tv_sec + offset * 60; |
134 | days = ts.tv_sec / SECS_PER_DAY; | 132 | time64_to_tm(seconds, 0, &tm); |
135 | rem = ts.tv_sec % SECS_PER_DAY; | 133 | dest->year = cpu_to_le16(tm.tm_year + 1900); |
136 | dest->hour = rem / SECS_PER_HOUR; | 134 | dest->month = tm.tm_mon + 1; |
137 | rem %= SECS_PER_HOUR; | 135 | dest->day = tm.tm_mday; |
138 | dest->minute = rem / 60; | 136 | dest->hour = tm.tm_hour; |
139 | dest->second = rem % 60; | 137 | dest->minute = tm.tm_min; |
140 | y = 1970; | 138 | dest->second = tm.tm_sec; |
141 | |||
142 | #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) | ||
143 | #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) | ||
144 | |||
145 | while (days < 0 || days >= (__isleap(y) ? 366 : 365)) { | ||
146 | long int yg = y + days / 365 - (days % 365 < 0); | ||
147 | |||
148 | /* Adjust DAYS and Y to match the guessed year. */ | ||
149 | days -= ((yg - y) * 365 | ||
150 | + LEAPS_THRU_END_OF(yg - 1) | ||
151 | - LEAPS_THRU_END_OF(y - 1)); | ||
152 | y = yg; | ||
153 | } | ||
154 | dest->year = cpu_to_le16(y); | ||
155 | ip = __mon_yday[__isleap(y)]; | ||
156 | for (y = 11; days < (long int)ip[y]; --y) | ||
157 | continue; | ||
158 | days -= ip[y]; | ||
159 | dest->month = y + 1; | ||
160 | dest->day = days + 1; | ||
161 | |||
162 | dest->centiseconds = ts.tv_nsec / 10000000; | 139 | dest->centiseconds = ts.tv_nsec / 10000000; |
163 | dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - | 140 | dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - |
164 | dest->centiseconds * 10000) / 100; | 141 | dest->centiseconds * 10000) / 100; |