Re: [PATCH] fat: Provide option for setting timezone offset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jan Kara <jack@xxxxxxx> writes:

> So far FAT either offsets time stamps by sys_tz.minuteswest or leaves them
> as they are (when tz=UTC mount option is used). However in some cases it
> is useful if one can specify time stamp offset on his own (e.g. when time
> zone of the camera connected is different from time zone of the computer,
> or when HW clock is in UTC and thus sys_tz.minuteswest == 0).
>
> So provide a mount option tz= which allows user to specify offset in minutes
> that should be applied to time stamps on the filesystem.

What is in some cases? tz_minuteswest style timezone is known as it
doesn't work. E.g. summer time.

And tz= is reserved for true solution. E.g. load timezone database to
kernel and use it for time conversion. So, if we really want this hack,
it should be different option name.

> Signed-off-by: Jan Kara <jack@xxxxxxx>
> ---
>  fs/fat/fat.h   |    3 ++-
>  fs/fat/inode.c |   20 +++++++++++++++-----
>  fs/fat/misc.c  |    9 ++++++---
>  3 files changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/fs/fat/fat.h b/fs/fat/fat.h
> index 2deeeb8..5f19eac 100644
> --- a/fs/fat/fat.h
> +++ b/fs/fat/fat.h
> @@ -28,6 +28,7 @@ struct fat_mount_options {
>  	unsigned short fs_fmask;
>  	unsigned short fs_dmask;
>  	unsigned short codepage;  /* Codepage for shortname conversions */
> +	short tz_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 */
> @@ -44,7 +45,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 */
>  };
> diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> index 05e897f..23c29a2 100644
> --- a/fs/fat/inode.c
> +++ b/fs/fat/inode.c
> @@ -850,8 +850,8 @@ 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)
> +		seq_printf(m, ",tz=%d", opts->tz_offset);
>  	if (opts->errors == FAT_ERRORS_CONT)
>  		seq_puts(m, ",errors=continue");
>  	else if (opts->errors == FAT_ERRORS_PANIC)
> @@ -872,7 +872,7 @@ enum {
>  	Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
>  	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_obsolete, Opt_flush, Opt_tz_utc, Opt_tz, Opt_rodir, Opt_err_cont,
>  	Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err,
>  };
>  
> @@ -898,6 +898,7 @@ static const match_table_t fat_tokens = {
>  	{Opt_immutable, "sys_immutable"},
>  	{Opt_flush, "flush"},
>  	{Opt_tz_utc, "tz=UTC"},
> +	{Opt_tz, "tz=%d"},
>  	{Opt_err_cont, "errors=continue"},
>  	{Opt_err_panic, "errors=panic"},
>  	{Opt_err_ro, "errors=remount-ro"},
> @@ -981,7 +982,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->errors = FAT_ERRORS_RO;
>  	*debug = 0;
>  
> @@ -1072,8 +1073,17 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
>  		case Opt_flush:
>  			opts->flush = 1;
>  			break;
> +		case Opt_tz:
> +			if (match_int(&args[0], &option))
> +				return 0;
> +			if (option < -12 * 60 || option > 12 * 60)
> +				return 0;
> +			opts->tz_set = 1;
> +			opts->tz_offset = option;
> +			break;
>  		case Opt_tz_utc:
> -			opts->tz_utc = 1;
> +			opts->tz_set = 1;
> +			opts->tz_offset = 0;
>  			break;
>  		case Opt_err_cont:
>  			opts->errors = FAT_ERRORS_CONT;
> diff --git a/fs/fat/misc.c b/fs/fat/misc.c
> index 6d93360..cc20a78 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,
>  		   + 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.tz_offset * SECS_PER_MIN;
>  
>  	if (time_cs) {
>  		ts->tv_sec = second + (time_cs / 100);
> @@ -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.tz_offset :
> +		   -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);
>  
>  	/*  FAT can only support year between 1980 to 2107 */
>  	if (tm.tm_year < 1980 - 1900) {

-- 
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux