aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/fat/fat.h3
-rw-r--r--fs/fat/inode.c25
-rw-r--r--fs/fat/misc.c9
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
807static const match_table_t fat_tokens = { 812static 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) {