^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/fat/misc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written 1992,1993 by Werner Almesberger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "fat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * fat_fs_error reports a file system problem that might indicate fa data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * corruption/inconsistency. Depending on 'errors' mount option the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * panic() is called, or error message is printed FAT and nothing is done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * or filesystem is remounted read-only (default behavior).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * In case the file system is remounted read-only, it can be made writable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * again by remounting it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct fat_mount_options *opts = &MSDOS_SB(sb)->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (report) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) fat_msg(sb, KERN_ERR, "error, %pV", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (opts->errors == FAT_ERRORS_PANIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) panic("FAT-fs (%s): fs panic from previous error\n", sb->s_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) else if (opts->errors == FAT_ERRORS_RO && !sb_rdonly(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) sb->s_flags |= SB_RDONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) fat_msg(sb, KERN_ERR, "Filesystem has been set read-only");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) EXPORT_SYMBOL_GPL(__fat_fs_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * fat_msg() - print preformated FAT specific messages. Every thing what is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * not fat_fs_error() should be fat_msg().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Flushes the number of free clusters on FAT32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* XXX: Need to write one per FSINFO block. Currently only writes 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int fat_clusters_flush(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct msdos_sb_info *sbi = MSDOS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct fat_boot_fsinfo *fsinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!is_fat32(sbi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bh = sb_bread(sb, sbi->fsinfo_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (bh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) fat_msg(sb, KERN_ERR, "bread failed in fat_clusters_flush");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!IS_FSINFO(fsinfo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) fat_msg(sb, KERN_ERR, "Invalid FSINFO signature: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "0x%08x, 0x%08x (sector = %lu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) le32_to_cpu(fsinfo->signature1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) le32_to_cpu(fsinfo->signature2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) sbi->fsinfo_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (sbi->free_clusters != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) fsinfo->free_clusters = cpu_to_le32(sbi->free_clusters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (sbi->prev_free != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mark_buffer_dirty(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * fat_chain_add() adds a new cluster to the chain of clusters represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * by inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct msdos_sb_info *sbi = MSDOS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int ret, new_fclus, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * We must locate the last cluster of the file to add this new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * one (new_dclus) to the end of the link list (the FAT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) last = new_fclus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (MSDOS_I(inode)->i_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int fclus, dclus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) new_fclus = fclus + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) last = dclus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* add new one to the last of the cluster chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct fat_entry fatent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) fatent_init(&fatent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = fat_ent_read(inode, &fatent, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int wait = inode_needs_sync(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = fat_ent_write(inode, &fatent, new_dclus, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) fatent_brelse(&fatent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * FIXME:Although we can add this cache, fat_cache_add() is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * assuming to be called after linear search with fat_cache_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) // fat_cache_add(inode, new_fclus, new_dclus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) MSDOS_I(inode)->i_start = new_dclus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MSDOS_I(inode)->i_logstart = new_dclus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Since generic_write_sync() synchronizes regular files later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * we sync here only directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ret = fat_sync_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (new_fclus != (inode->i_blocks >> (sbi->cluster_bits - 9))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fat_fs_error(sb, "clusters badly computed (%d != %llu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) new_fclus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) (llu)(inode->i_blocks >> (sbi->cluster_bits - 9)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fat_cache_inval_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) inode->i_blocks += nr_cluster << (sbi->cluster_bits - 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * The epoch of FAT timestamp is 1980.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * : bits : value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * date: 0 - 4: day (1 - 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * date: 5 - 8: month (1 - 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * date: 9 - 15: year (0 - 127) from 1980
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * time: 0 - 4: sec (0 - 29) 2sec counts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * time: 5 - 10: min (0 - 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * time: 11 - 15: hour (0 - 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define SECS_PER_MIN 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define SECS_PER_HOUR (60 * 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define SECS_PER_DAY (SECS_PER_HOUR * 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* days between 1.1.70 and 1.1.80 (2 leap days) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define DAYS_DELTA (365 * 10 + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* 120 (2100 - 1980) isn't leap year */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define YEAR_2100 120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != YEAR_2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Linear day numbers of the respective 1sts in non-leap years. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static long days_in_year[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static inline int fat_tz_offset(struct msdos_sb_info *sbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return (sbi->options.tz_set ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) -sbi->options.time_offset :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) sys_tz.tz_minuteswest) * SECS_PER_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __le16 __time, __le16 __date, u8 time_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) time64_t second;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) long day, leap_day, month, year;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) year = date >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) month = max(1, (date >> 5) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) day = max(1, date & 0x1f) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) leap_day = (year + 3) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (year > YEAR_2100) /* 2100 isn't leap year */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) leap_day--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (IS_LEAP_YEAR(year) && month > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) leap_day++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) second = (time & 0x1f) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) second += ((time >> 5) & 0x3f) * SECS_PER_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) second += (time >> 11) * SECS_PER_HOUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) second += (time64_t)(year * 365 + leap_day
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) + days_in_year[month] + day
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) + DAYS_DELTA) * SECS_PER_DAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) second += fat_tz_offset(sbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (time_cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ts->tv_sec = second + (time_cs / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ts->tv_nsec = (time_cs % 100) * 10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ts->tv_sec = second;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ts->tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Convert linear UNIX date to a FAT time/date pair. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) __le16 *time, __le16 *date, u8 *time_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct tm tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) time64_to_tm(ts->tv_sec, -fat_tz_offset(sbi), &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* FAT can only support year between 1980 to 2107 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (tm.tm_year < 1980 - 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *date = cpu_to_le16((0 << 9) | (1 << 5) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (time_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *time_cs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (tm.tm_year > 2107 - 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *time = cpu_to_le16((23 << 11) | (59 << 5) | 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *date = cpu_to_le16((127 << 9) | (12 << 5) | 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (time_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *time_cs = 199;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* from 1900 -> from 1980 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) tm.tm_year -= 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* 0~11 -> 1~12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) tm.tm_mon++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* 0~59 -> 0~29(2sec counts) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) tm.tm_sec >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *time = cpu_to_le16(tm.tm_hour << 11 | tm.tm_min << 5 | tm.tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *date = cpu_to_le16(tm.tm_year << 9 | tm.tm_mon << 5 | tm.tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (time_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) EXPORT_SYMBOL_GPL(fat_time_unix2fat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static inline struct timespec64 fat_timespec64_trunc_10ms(struct timespec64 ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ts.tv_nsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ts.tv_nsec -= ts.tv_nsec % 10000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * truncate the various times with appropriate granularity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * root inode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * all times always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * all other inodes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * mtime - 2 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * ctime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * msdos - 2 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * vfat - 10 milliseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * atime - 24 hours (00:00:00 in local timezone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (inode->i_ino == MSDOS_ROOT_INO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (now == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) now = &ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ts = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (flags & S_ATIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* to localtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) time64_t seconds = now->tv_sec - fat_tz_offset(sbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) s32 remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) div_s64_rem(seconds, SECS_PER_DAY, &remainder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* to day boundary, and back to unix time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) seconds = seconds + fat_tz_offset(sbi) - remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) inode->i_atime = (struct timespec64){ seconds, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (flags & S_CTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (sbi->options.isvfat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) inode->i_ctime = fat_timespec64_trunc_10ms(*now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) inode->i_ctime = fat_timespec64_trunc_2secs(*now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (flags & S_MTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) inode->i_mtime = fat_timespec64_trunc_2secs(*now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) EXPORT_SYMBOL_GPL(fat_truncate_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int iflags = I_DIRTY_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) bool dirty = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (inode->i_ino == MSDOS_ROOT_INO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) fat_truncate_time(inode, now, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (flags & S_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dirty = inode_maybe_inc_iversion(inode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) !(inode->i_sb->s_flags & SB_LAZYTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) dirty = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (dirty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) iflags |= I_DIRTY_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) __mark_inode_dirty(inode, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) EXPORT_SYMBOL_GPL(fat_update_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (i = 0; i < nr_bhs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) write_dirty_buffer(bhs[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) for (i = 0; i < nr_bhs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) wait_on_buffer(bhs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!err && !buffer_uptodate(bhs[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }