misc.c (d9f4d94261d52a5fe31ad2ec00a06824a150af6f) misc.c (6bb885ecd746752aa70d146b58f2f83e5e21813d)
1/*
2 * linux/fs/fat/misc.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
6 * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
7 */
8
9#include "fat.h"
1/*
2 * linux/fs/fat/misc.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
6 * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
7 */
8
9#include "fat.h"
10#include <linux/iversion.h>
10
11/*
12 * fat_fs_error reports a file system problem that might indicate fa data
13 * corruption/inconsistency. Depending on 'errors' mount option the
14 * panic() is called, or error message is printed FAT and nothing is done,
15 * or filesystem is remounted read-only (default behavior).
16 * In case the file system is remounted read-only, it can be made writable
17 * again by remounting it.

--- 242 unchanged lines hidden (view full) ---

260
261 *time = cpu_to_le16(tm.tm_hour << 11 | tm.tm_min << 5 | tm.tm_sec);
262 *date = cpu_to_le16(tm.tm_year << 9 | tm.tm_mon << 5 | tm.tm_mday);
263 if (time_cs)
264 *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000;
265}
266EXPORT_SYMBOL_GPL(fat_time_unix2fat);
267
11
12/*
13 * fat_fs_error reports a file system problem that might indicate fa data
14 * corruption/inconsistency. Depending on 'errors' mount option the
15 * panic() is called, or error message is printed FAT and nothing is done,
16 * or filesystem is remounted read-only (default behavior).
17 * In case the file system is remounted read-only, it can be made writable
18 * again by remounting it.

--- 242 unchanged lines hidden (view full) ---

261
262 *time = cpu_to_le16(tm.tm_hour << 11 | tm.tm_min << 5 | tm.tm_sec);
263 *date = cpu_to_le16(tm.tm_year << 9 | tm.tm_mon << 5 | tm.tm_mday);
264 if (time_cs)
265 *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000;
266}
267EXPORT_SYMBOL_GPL(fat_time_unix2fat);
268
269static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
270{
271 return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
272}
273/*
274 * truncate the various times with appropriate granularity:
275 * root inode:
276 * all times always 0
277 * all other inodes:
278 * mtime - 2 seconds
279 * ctime
280 * msdos - 2 seconds
281 * vfat - 10 milliseconds
282 * atime - 24 hours (00:00:00 in local timezone)
283 */
284int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
285{
286 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
287 struct timespec64 ts;
288
289 if (inode->i_ino == MSDOS_ROOT_INO)
290 return 0;
291
292 if (now == NULL) {
293 now = &ts;
294 ts = current_time(inode);
295 }
296
297 if (flags & S_ATIME) {
298 /* to localtime */
299 time64_t seconds = now->tv_sec - fat_tz_offset(sbi);
300 s32 remainder;
301
302 div_s64_rem(seconds, SECS_PER_DAY, &remainder);
303 /* to day boundary, and back to unix time */
304 seconds = seconds + fat_tz_offset(sbi) - remainder;
305
306 inode->i_atime = (struct timespec64){ seconds, 0 };
307 }
308 if (flags & S_CTIME) {
309 if (sbi->options.isvfat)
310 inode->i_ctime = timespec64_trunc(*now, 10000000);
311 else
312 inode->i_ctime = fat_timespec64_trunc_2secs(*now);
313 }
314 if (flags & S_MTIME)
315 inode->i_mtime = fat_timespec64_trunc_2secs(*now);
316
317 return 0;
318}
319EXPORT_SYMBOL_GPL(fat_truncate_time);
320
321int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
322{
323 int iflags = I_DIRTY_TIME;
324 bool dirty = false;
325
326 if (inode->i_ino == MSDOS_ROOT_INO)
327 return 0;
328
329 fat_truncate_time(inode, now, flags);
330 if (flags & S_VERSION)
331 dirty = inode_maybe_inc_iversion(inode, false);
332 if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
333 !(inode->i_sb->s_flags & SB_LAZYTIME))
334 dirty = true;
335
336 if (dirty)
337 iflags |= I_DIRTY_SYNC;
338 __mark_inode_dirty(inode, iflags);
339 return 0;
340}
341EXPORT_SYMBOL_GPL(fat_update_time);
342
268int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
269{
270 int i, err = 0;
271
272 for (i = 0; i < nr_bhs; i++)
273 write_dirty_buffer(bhs[i], 0);
274
275 for (i = 0; i < nr_bhs; i++) {
276 wait_on_buffer(bhs[i]);
277 if (!err && !buffer_uptodate(bhs[i]))
278 err = -EIO;
279 }
280 return err;
281}
343int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
344{
345 int i, err = 0;
346
347 for (i = 0; i < nr_bhs; i++)
348 write_dirty_buffer(bhs[i], 0);
349
350 for (i = 0; i < nr_bhs; i++) {
351 wait_on_buffer(bhs[i]);
352 if (!err && !buffer_uptodate(bhs[i]))
353 err = -EIO;
354 }
355 return err;
356}