/[linux-patches]/genpatches-2.6/trunk/2.6.26/1900_UTC-timestamp-option.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.26/1900_UTC-timestamp-option.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1335 - (show annotations) (download)
Thu Jul 31 00:39:38 2008 UTC (9 years, 4 months ago) by mpagano
File size: 8652 byte(s)
Adding UTC timestamp option patch bug #233307
1 New mount option ("tz=UTC") for FAT (vfat/msdos) filesystems allowing
2 timestamps to be in coordinated universal time (UTC) rather than
3 local time in applications where doing this is advantageous (like
4 digital cameras, etc.)
5
6 Signed-off-by: Joe Peterson <joe@skyrush.com>
7 Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
8 ---
9
10 diff -puNr a/fs/fat/dir.c b/fs/fat/dir.c
11 --- a/fs/fat/dir.c 2008-06-25 08:53:35.676901351 -0600
12 +++ b/fs/fat/dir.c 2008-06-26 12:58:56.096272279 -0600
13 @@ -1082,7 +1082,7 @@ int fat_alloc_new_dir(struct inode *dir,
14 goto error_free;
15 }
16
17 - fat_date_unix2dos(ts->tv_sec, &time, &date);
18 + fat_date_unix2dos(ts->tv_sec, &time, &date, sbi->options.tz_utc);
19
20 de = (struct msdos_dir_entry *)bhs[0]->b_data;
21 /* filling the new directory slots ("." and ".." entries) */
22 diff -puNr a/fs/fat/inode.c b/fs/fat/inode.c
23 --- a/fs/fat/inode.c 2008-06-25 08:53:35.676901351 -0600
24 +++ b/fs/fat/inode.c 2008-06-26 14:57:07.087942764 -0600
25 @@ -382,17 +382,20 @@ static int fat_fill_inode(struct inode *
26 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
27 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
28 inode->i_mtime.tv_sec =
29 - date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
30 + date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date),
31 + sbi->options.tz_utc);
32 inode->i_mtime.tv_nsec = 0;
33 if (sbi->options.isvfat) {
34 int secs = de->ctime_cs / 100;
35 int csecs = de->ctime_cs % 100;
36 inode->i_ctime.tv_sec =
37 date_dos2unix(le16_to_cpu(de->ctime),
38 - le16_to_cpu(de->cdate)) + secs;
39 + le16_to_cpu(de->cdate),
40 + sbi->options.tz_utc) + secs;
41 inode->i_ctime.tv_nsec = csecs * 10000000;
42 inode->i_atime.tv_sec =
43 - date_dos2unix(0, le16_to_cpu(de->adate));
44 + date_dos2unix(0, le16_to_cpu(de->adate),
45 + sbi->options.tz_utc);
46 inode->i_atime.tv_nsec = 0;
47 } else
48 inode->i_ctime = inode->i_atime = inode->i_mtime;
49 @@ -592,11 +595,14 @@ retry:
50 raw_entry->attr = fat_attr(inode);
51 raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
52 raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
53 - fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
54 + fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time,
55 + &raw_entry->date, sbi->options.tz_utc);
56 if (sbi->options.isvfat) {
57 __le16 atime;
58 - fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
59 - fat_date_unix2dos(inode->i_atime.tv_sec,&atime,&raw_entry->adate);
60 + fat_date_unix2dos(inode->i_ctime.tv_sec, &raw_entry->ctime,
61 + &raw_entry->cdate, sbi->options.tz_utc);
62 + fat_date_unix2dos(inode->i_atime.tv_sec, &atime,
63 + &raw_entry->adate, sbi->options.tz_utc);
64 raw_entry->ctime_cs = (inode->i_ctime.tv_sec & 1) * 100 +
65 inode->i_ctime.tv_nsec / 10000000;
66 }
67 @@ -836,6 +842,8 @@ static int fat_show_options(struct seq_f
68 }
69 if (sbi->options.flush)
70 seq_puts(m, ",flush");
71 + if (opts->tz_utc)
72 + seq_puts(m, ",tz=UTC");
73
74 return 0;
75 }
76 @@ -848,7 +856,7 @@ enum {
77 Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
78 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
79 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
80 - Opt_obsolate, Opt_flush, Opt_err,
81 + Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_err,
82 };
83
84 static match_table_t fat_tokens = {
85 @@ -883,6 +891,7 @@ static match_table_t fat_tokens = {
86 {Opt_obsolate, "cvf_options=%100s"},
87 {Opt_obsolate, "posix"},
88 {Opt_flush, "flush"},
89 + {Opt_tz_utc, "tz=UTC"},
90 {Opt_err, NULL},
91 };
92 static match_table_t msdos_tokens = {
93 @@ -947,6 +956,7 @@ static int parse_options(char *options,
94 opts->utf8 = opts->unicode_xlate = 0;
95 opts->numtail = 1;
96 opts->usefree = opts->nocase = 0;
97 + opts->tz_utc = 0;
98 *debug = 0;
99
100 if (!options)
101 @@ -1036,6 +1046,9 @@ static int parse_options(char *options,
102 case Opt_flush:
103 opts->flush = 1;
104 break;
105 + case Opt_tz_utc:
106 + opts->tz_utc = 1;
107 + break;
108
109 /* msdos specific */
110 case Opt_dots:
111 diff -puNr a/fs/fat/misc.c b/fs/fat/misc.c
112 --- a/fs/fat/misc.c 2008-06-25 08:53:35.676901351 -0600
113 +++ b/fs/fat/misc.c 2008-06-26 12:59:08.627376422 -0600
114 @@ -142,7 +142,7 @@ static int day_n[] = {
115 };
116
117 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
118 -int date_dos2unix(unsigned short time, unsigned short date)
119 +int date_dos2unix(unsigned short time, unsigned short date, int tz_utc)
120 {
121 int month, year, secs;
122
123 @@ -156,16 +156,18 @@ int date_dos2unix(unsigned short time, u
124 ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
125 month < 2 ? 1 : 0)+3653);
126 /* days since 1.1.70 plus 80's leap day */
127 - secs += sys_tz.tz_minuteswest*60;
128 + if (!tz_utc)
129 + secs += sys_tz.tz_minuteswest*60;
130 return secs;
131 }
132
133 /* Convert linear UNIX date to a MS-DOS time/date pair. */
134 -void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
135 +void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date, int tz_utc)
136 {
137 int day, year, nl_day, month;
138
139 - unix_date -= sys_tz.tz_minuteswest*60;
140 + if (!tz_utc)
141 + unix_date -= sys_tz.tz_minuteswest*60;
142
143 /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
144 if (unix_date < 315532800)
145 diff -puNr a/fs/msdos/namei.c b/fs/msdos/namei.c
146 --- a/fs/msdos/namei.c 2008-06-25 08:53:35.696902410 -0600
147 +++ b/fs/msdos/namei.c 2008-06-26 12:58:42.255055811 -0600
148 @@ -243,6 +243,7 @@ static int msdos_add_entry(struct inode
149 int is_dir, int is_hid, int cluster,
150 struct timespec *ts, struct fat_slot_info *sinfo)
151 {
152 + struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
153 struct msdos_dir_entry de;
154 __le16 time, date;
155 int err;
156 @@ -252,7 +253,7 @@ static int msdos_add_entry(struct inode
157 if (is_hid)
158 de.attr |= ATTR_HIDDEN;
159 de.lcase = 0;
160 - fat_date_unix2dos(ts->tv_sec, &time, &date);
161 + fat_date_unix2dos(ts->tv_sec, &time, &date, sbi->options.tz_utc);
162 de.cdate = de.adate = 0;
163 de.ctime = 0;
164 de.ctime_cs = 0;
165 diff -puNr a/fs/vfat/namei.c b/fs/vfat/namei.c
166 --- a/fs/vfat/namei.c 2008-06-25 08:53:35.686902663 -0600
167 +++ b/fs/vfat/namei.c 2008-06-26 12:58:27.073724049 -0600
168 @@ -621,7 +621,7 @@ shortname:
169 memcpy(de->name, msdos_name, MSDOS_NAME);
170 de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
171 de->lcase = lcase;
172 - fat_date_unix2dos(ts->tv_sec, &time, &date);
173 + fat_date_unix2dos(ts->tv_sec, &time, &date, sbi->options.tz_utc);
174 de->time = de->ctime = time;
175 de->date = de->cdate = de->adate = date;
176 de->ctime_cs = 0;
177 diff -puNr a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
178 --- a/include/linux/msdos_fs.h 2008-06-25 08:53:17.435303045 -0600
179 +++ b/include/linux/msdos_fs.h 2008-06-26 14:58:40.626135522 -0600
180 @@ -205,7 +205,8 @@ struct fat_mount_options {
181 atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
182 flush:1, /* write things quickly */
183 nocase:1, /* Does this need case conversion? 0=need case conversion*/
184 - usefree:1; /* Use free_clusters for FAT32 */
185 + usefree:1, /* Use free_clusters for FAT32 */
186 + tz_utc:1; /* Filesystem timestamps are in UTC */
187 };
188
189 #define FAT_HASH_BITS 8
190 @@ -428,8 +429,9 @@ extern int fat_flush_inodes(struct super
191 extern void fat_fs_panic(struct super_block *s, const char *fmt, ...);
192 extern void fat_clusters_flush(struct super_block *sb);
193 extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
194 -extern int date_dos2unix(unsigned short time, unsigned short date);
195 -extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date);
196 +extern int date_dos2unix(unsigned short time, unsigned short date, int tz_utc);
197 +extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date,
198 + int tz_utc);
199 extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
200
201 int fat_cache_init(void);
202
203 diff -puN Documentation/filesystems/vfat.txt~utc-timestamp-option-for-fat-filesystems-fix Documentation/filesystems/vfat.txt
204 --- a/Documentation/filesystems/vfat.txt~utc-timestamp-option-for-fat-filesystems-fix
205 +++ a/Documentation/filesystems/vfat.txt
206 @@ -96,6 +96,14 @@ shortname=lower|win95|winnt|mixed
207 emulate the Windows 95 rule for create.
208 Default setting is `lower'.
209
210 +tz=UTC -- Interpret timestamps as UTC rather than local time.
211 + This option disables the conversion of timestamps
212 + between local time (as used by Windows on FAT) and UTC
213 + (which Linux uses internally). This is particuluarly
214 + useful when mounting devices (like digital cameras)
215 + that are set to UTC in order to avoid the pitfalls of
216 + local time.
217 +
218 <bool>: 0,1,yes,no,true,false
219
220 TODO
221

  ViewVC Help
Powered by ViewVC 1.1.20