@@ -193,7 +193,7 @@ static long days_in_year[] = {
193193 0 , 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 , 0 , 0 , 0 ,
194194};
195195
196- static inline int fat_tz_offset (struct msdos_sb_info * sbi )
196+ static inline int fat_tz_offset (const struct msdos_sb_info * sbi )
197197{
198198 return (sbi -> options .tz_set ?
199199 - sbi -> options .time_offset :
@@ -288,16 +288,49 @@ static inline struct timespec64 fat_timespec64_trunc_10ms(struct timespec64 ts)
288288 return ts ;
289289}
290290
291+ /*
292+ * truncate atime to 24 hour granularity (00:00:00 in local timezone)
293+ */
294+ struct timespec64 fat_truncate_atime (const struct msdos_sb_info * sbi ,
295+ const struct timespec64 * ts )
296+ {
297+ /* to localtime */
298+ time64_t seconds = ts -> tv_sec - fat_tz_offset (sbi );
299+ s32 remainder ;
300+
301+ div_s64_rem (seconds , SECS_PER_DAY , & remainder );
302+ /* to day boundary, and back to unix time */
303+ seconds = seconds + fat_tz_offset (sbi ) - remainder ;
304+
305+ return (struct timespec64 ){ seconds , 0 };
306+ }
307+
308+ /*
309+ * truncate creation time with appropriate granularity:
310+ * msdos - 2 seconds
311+ * vfat - 10 milliseconds
312+ */
313+ struct timespec64 fat_truncate_crtime (const struct msdos_sb_info * sbi ,
314+ const struct timespec64 * ts )
315+ {
316+ if (sbi -> options .isvfat )
317+ return fat_timespec64_trunc_10ms (* ts );
318+ else
319+ return fat_timespec64_trunc_2secs (* ts );
320+ }
321+
322+ /*
323+ * truncate mtime to 2 second granularity
324+ */
325+ struct timespec64 fat_truncate_mtime (const struct msdos_sb_info * sbi ,
326+ const struct timespec64 * ts )
327+ {
328+ return fat_timespec64_trunc_2secs (* ts );
329+ }
330+
291331/*
292332 * truncate the various times with appropriate granularity:
293- * root inode:
294- * all times always 0
295- * all other inodes:
296- * mtime - 2 seconds
297- * ctime
298- * msdos - 2 seconds
299- * vfat - 10 milliseconds
300- * atime - 24 hours (00:00:00 in local timezone)
333+ * all times in root node are always 0
301334 */
302335int fat_truncate_time (struct inode * inode , struct timespec64 * now , int flags )
303336{
@@ -312,25 +345,12 @@ int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
312345 ts = current_time (inode );
313346 }
314347
315- if (flags & S_ATIME ) {
316- /* to localtime */
317- time64_t seconds = now -> tv_sec - fat_tz_offset (sbi );
318- s32 remainder ;
319-
320- div_s64_rem (seconds , SECS_PER_DAY , & remainder );
321- /* to day boundary, and back to unix time */
322- seconds = seconds + fat_tz_offset (sbi ) - remainder ;
323-
324- inode -> i_atime = (struct timespec64 ){ seconds , 0 };
325- }
326- if (flags & S_CTIME ) {
327- if (sbi -> options .isvfat )
328- inode -> i_ctime = fat_timespec64_trunc_10ms (* now );
329- else
330- inode -> i_ctime = fat_timespec64_trunc_2secs (* now );
331- }
348+ if (flags & S_ATIME )
349+ inode -> i_atime = fat_truncate_atime (sbi , now );
350+ if (flags & S_CTIME )
351+ inode -> i_ctime = fat_truncate_crtime (sbi , now );
332352 if (flags & S_MTIME )
333- inode -> i_mtime = fat_timespec64_trunc_2secs ( * now );
353+ inode -> i_mtime = fat_truncate_mtime ( sbi , now );
334354
335355 return 0 ;
336356}
0 commit comments