Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346450
b: refs/heads/master
c: 58156c8
h: refs/heads/master
v: v3
  • Loading branch information
Jan Kara authored and Linus Torvalds committed Dec 18, 2012
1 parent 1bb41e6 commit 1045c64
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f562146a3daf6aa0bbf2a1bc4b6b7da031ed5dcd
refs/heads/master: 58156c8fbf43e71dd091848d4dbfd780d04016e6
9 changes: 9 additions & 0 deletions trunk/Documentation/filesystems/vfat.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ tz=UTC -- Interpret timestamps as UTC rather than local time.
useful when mounting devices (like digital cameras)
that are set to UTC in order to avoid the pitfalls of
local time.
time_offset=minutes
-- Set offset for conversion of timestamps from local time
used by FAT to UTC. I.e. <minutes> minutes will be subtracted
from each timestamp to convert it to UTC used internally by
Linux. This is useful when time zone set in sys_tz is
not the time zone used by the filesystem. Note that this
option still does not provide correct time stamps in all
cases in presence of DST - time stamps in a different DST
setting will be off by one hour.

showexec -- If set, the execute permission bits of the file will be
allowed only if the extension part of the name is .EXE,
Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/fat/fat.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct fat_mount_options {
unsigned short fs_fmask;
unsigned short fs_dmask;
unsigned short codepage; /* Codepage for shortname conversions */
int time_offset; /* Offset of timestamps from UTC (in minutes) */
char *iocharset; /* Charset used for filename input/display */
unsigned short shortname; /* flags for shortname display/create rule */
unsigned char name_check; /* r = relaxed, n = normal, s = strict */
Expand All @@ -45,7 +46,7 @@ struct fat_mount_options {
flush:1, /* write things quickly */
nocase:1, /* Does this need case conversion? 0=need case conversion*/
usefree:1, /* Use free_clusters for FAT32 */
tz_utc:1, /* Filesystem timestamps are in UTC */
tz_set:1, /* Filesystem timestamps' offset set */
rodir:1, /* allow ATTR_RO for directory */
discard:1, /* Issue discard requests on deletions */
nfs:1; /* Do extra work needed for NFS export */
Expand Down
25 changes: 20 additions & 5 deletions trunk/fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,12 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
}
if (opts->flush)
seq_puts(m, ",flush");
if (opts->tz_utc)
seq_puts(m, ",tz=UTC");
if (opts->tz_set) {
if (opts->time_offset)
seq_printf(m, ",time_offset=%d", opts->time_offset);
else
seq_puts(m, ",tz=UTC");
}
if (opts->errors == FAT_ERRORS_CONT)
seq_puts(m, ",errors=continue");
else if (opts->errors == FAT_ERRORS_PANIC)
Expand All @@ -801,7 +805,8 @@ enum {
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err,
Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
Opt_err,
};

static const match_table_t fat_tokens = {
Expand All @@ -826,6 +831,7 @@ static const match_table_t fat_tokens = {
{Opt_immutable, "sys_immutable"},
{Opt_flush, "flush"},
{Opt_tz_utc, "tz=UTC"},
{Opt_time_offset, "time_offset=%d"},
{Opt_err_cont, "errors=continue"},
{Opt_err_panic, "errors=panic"},
{Opt_err_ro, "errors=remount-ro"},
Expand Down Expand Up @@ -910,7 +916,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
opts->utf8 = opts->unicode_xlate = 0;
opts->numtail = 1;
opts->usefree = opts->nocase = 0;
opts->tz_utc = 0;
opts->tz_set = 0;
opts->nfs = 0;
opts->errors = FAT_ERRORS_RO;
*debug = 0;
Expand Down Expand Up @@ -1006,8 +1012,17 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
case Opt_flush:
opts->flush = 1;
break;
case Opt_time_offset:
if (match_int(&args[0], &option))
return 0;
if (option < -12 * 60 || option > 12 * 60)
return 0;
opts->tz_set = 1;
opts->time_offset = option;
break;
case Opt_tz_utc:
opts->tz_utc = 1;
opts->tz_set = 1;
opts->time_offset = 0;
break;
case Opt_err_cont:
opts->errors = FAT_ERRORS_CONT;
Expand Down
9 changes: 6 additions & 3 deletions trunk/fs/fat/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,10 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
+ days_in_year[month] + day
+ DAYS_DELTA) * SECS_PER_DAY;

if (!sbi->options.tz_utc)
if (!sbi->options.tz_set)
second += sys_tz.tz_minuteswest * SECS_PER_MIN;
else
second -= sbi->options.time_offset * SECS_PER_MIN;

if (time_cs) {
ts->tv_sec = second + (time_cs / 100);
Expand All @@ -229,8 +231,9 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts,
__le16 *time, __le16 *date, u8 *time_cs)
{
struct tm tm;
time_to_tm(ts->tv_sec, sbi->options.tz_utc ? 0 :
-sys_tz.tz_minuteswest * 60, &tm);
time_to_tm(ts->tv_sec,
(sbi->options.tz_set ? sbi->options.time_offset :
-sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);

/* FAT can only support year between 1980 to 2107 */
if (tm.tm_year < 1980 - 1900) {
Expand Down

0 comments on commit 1045c64

Please sign in to comment.