diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fat/fat.h | 3 | ||||
-rw-r--r-- | fs/fat/inode.c | 25 | ||||
-rw-r--r-- | fs/fat/misc.c | 9 |
3 files changed, 28 insertions, 9 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 623f36f0423..12701a56775 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -29,6 +29,7 @@ struct fat_mount_options { | |||
29 | unsigned short fs_fmask; | 29 | unsigned short fs_fmask; |
30 | unsigned short fs_dmask; | 30 | unsigned short fs_dmask; |
31 | unsigned short codepage; /* Codepage for shortname conversions */ | 31 | unsigned short codepage; /* Codepage for shortname conversions */ |
32 | int time_offset; /* Offset of timestamps from UTC (in minutes) */ | ||
32 | char *iocharset; /* Charset used for filename input/display */ | 33 | char *iocharset; /* Charset used for filename input/display */ |
33 | unsigned short shortname; /* flags for shortname display/create rule */ | 34 | unsigned short shortname; /* flags for shortname display/create rule */ |
34 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ | 35 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ |
@@ -45,7 +46,7 @@ struct fat_mount_options { | |||
45 | flush:1, /* write things quickly */ | 46 | flush:1, /* write things quickly */ |
46 | nocase:1, /* Does this need case conversion? 0=need case conversion*/ | 47 | nocase:1, /* Does this need case conversion? 0=need case conversion*/ |
47 | usefree:1, /* Use free_clusters for FAT32 */ | 48 | usefree:1, /* Use free_clusters for FAT32 */ |
48 | tz_utc:1, /* Filesystem timestamps are in UTC */ | 49 | tz_set:1, /* Filesystem timestamps' offset set */ |
49 | rodir:1, /* allow ATTR_RO for directory */ | 50 | rodir:1, /* allow ATTR_RO for directory */ |
50 | discard:1, /* Issue discard requests on deletions */ | 51 | discard:1, /* Issue discard requests on deletions */ |
51 | nfs:1; /* Do extra work needed for NFS export */ | 52 | nfs:1; /* Do extra work needed for NFS export */ |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 7b186a5d51b..59ac83be2d5 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -778,8 +778,12 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
778 | } | 778 | } |
779 | if (opts->flush) | 779 | if (opts->flush) |
780 | seq_puts(m, ",flush"); | 780 | seq_puts(m, ",flush"); |
781 | if (opts->tz_utc) | 781 | if (opts->tz_set) { |
782 | seq_puts(m, ",tz=UTC"); | 782 | if (opts->time_offset) |
783 | seq_printf(m, ",time_offset=%d", opts->time_offset); | ||
784 | else | ||
785 | seq_puts(m, ",tz=UTC"); | ||
786 | } | ||
783 | if (opts->errors == FAT_ERRORS_CONT) | 787 | if (opts->errors == FAT_ERRORS_CONT) |
784 | seq_puts(m, ",errors=continue"); | 788 | seq_puts(m, ",errors=continue"); |
785 | else if (opts->errors == FAT_ERRORS_PANIC) | 789 | else if (opts->errors == FAT_ERRORS_PANIC) |
@@ -801,7 +805,8 @@ enum { | |||
801 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 805 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, |
802 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 806 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
803 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, | 807 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, |
804 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err, | 808 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, |
809 | Opt_err, | ||
805 | }; | 810 | }; |
806 | 811 | ||
807 | static const match_table_t fat_tokens = { | 812 | static const match_table_t fat_tokens = { |
@@ -826,6 +831,7 @@ static const match_table_t fat_tokens = { | |||
826 | {Opt_immutable, "sys_immutable"}, | 831 | {Opt_immutable, "sys_immutable"}, |
827 | {Opt_flush, "flush"}, | 832 | {Opt_flush, "flush"}, |
828 | {Opt_tz_utc, "tz=UTC"}, | 833 | {Opt_tz_utc, "tz=UTC"}, |
834 | {Opt_time_offset, "time_offset=%d"}, | ||
829 | {Opt_err_cont, "errors=continue"}, | 835 | {Opt_err_cont, "errors=continue"}, |
830 | {Opt_err_panic, "errors=panic"}, | 836 | {Opt_err_panic, "errors=panic"}, |
831 | {Opt_err_ro, "errors=remount-ro"}, | 837 | {Opt_err_ro, "errors=remount-ro"}, |
@@ -910,7 +916,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
910 | opts->utf8 = opts->unicode_xlate = 0; | 916 | opts->utf8 = opts->unicode_xlate = 0; |
911 | opts->numtail = 1; | 917 | opts->numtail = 1; |
912 | opts->usefree = opts->nocase = 0; | 918 | opts->usefree = opts->nocase = 0; |
913 | opts->tz_utc = 0; | 919 | opts->tz_set = 0; |
914 | opts->nfs = 0; | 920 | opts->nfs = 0; |
915 | opts->errors = FAT_ERRORS_RO; | 921 | opts->errors = FAT_ERRORS_RO; |
916 | *debug = 0; | 922 | *debug = 0; |
@@ -1006,8 +1012,17 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1006 | case Opt_flush: | 1012 | case Opt_flush: |
1007 | opts->flush = 1; | 1013 | opts->flush = 1; |
1008 | break; | 1014 | break; |
1015 | case Opt_time_offset: | ||
1016 | if (match_int(&args[0], &option)) | ||
1017 | return 0; | ||
1018 | if (option < -12 * 60 || option > 12 * 60) | ||
1019 | return 0; | ||
1020 | opts->tz_set = 1; | ||
1021 | opts->time_offset = option; | ||
1022 | break; | ||
1009 | case Opt_tz_utc: | 1023 | case Opt_tz_utc: |
1010 | opts->tz_utc = 1; | 1024 | opts->tz_set = 1; |
1025 | opts->time_offset = 0; | ||
1011 | break; | 1026 | break; |
1012 | case Opt_err_cont: | 1027 | case Opt_err_cont: |
1013 | opts->errors = FAT_ERRORS_CONT; | 1028 | opts->errors = FAT_ERRORS_CONT; |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 6d93360ca0c..5eb600dc43a 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
@@ -212,8 +212,10 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, | |||
212 | + days_in_year[month] + day | 212 | + days_in_year[month] + day |
213 | + DAYS_DELTA) * SECS_PER_DAY; | 213 | + DAYS_DELTA) * SECS_PER_DAY; |
214 | 214 | ||
215 | if (!sbi->options.tz_utc) | 215 | if (!sbi->options.tz_set) |
216 | second += sys_tz.tz_minuteswest * SECS_PER_MIN; | 216 | second += sys_tz.tz_minuteswest * SECS_PER_MIN; |
217 | else | ||
218 | second -= sbi->options.time_offset * SECS_PER_MIN; | ||
217 | 219 | ||
218 | if (time_cs) { | 220 | if (time_cs) { |
219 | ts->tv_sec = second + (time_cs / 100); | 221 | ts->tv_sec = second + (time_cs / 100); |
@@ -229,8 +231,9 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, | |||
229 | __le16 *time, __le16 *date, u8 *time_cs) | 231 | __le16 *time, __le16 *date, u8 *time_cs) |
230 | { | 232 | { |
231 | struct tm tm; | 233 | struct tm tm; |
232 | time_to_tm(ts->tv_sec, sbi->options.tz_utc ? 0 : | 234 | time_to_tm(ts->tv_sec, |
233 | -sys_tz.tz_minuteswest * 60, &tm); | 235 | (sbi->options.tz_set ? sbi->options.time_offset : |
236 | -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm); | ||
234 | 237 | ||
235 | /* FAT can only support year between 1980 to 2107 */ | 238 | /* FAT can only support year between 1980 to 2107 */ |
236 | if (tm.tm_year < 1980 - 1900) { | 239 | if (tm.tm_year < 1980 - 1900) { |