Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }