VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   1) // SPDX-License-Identifier: GPL-2.0-or-later
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   2) /*
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   3)  * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   4)  */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   5) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   6) #include <linux/slab.h>
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   7) #include <asm/unaligned.h>
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   8) #include <linux/buffer_head.h>
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900   9) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  10) #include "exfat_raw.h"
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  11) #include "exfat_fs.h"
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  12) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  13) static int exfat_mirror_bh(struct super_block *sb, sector_t sec,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  14) 		struct buffer_head *bh)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  15) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  16) 	struct buffer_head *c_bh;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  17) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  18) 	sector_t sec2;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  19) 	int err = 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  20) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  21) 	if (sbi->FAT2_start_sector != sbi->FAT1_start_sector) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  22) 		sec2 = sec - sbi->FAT1_start_sector + sbi->FAT2_start_sector;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  23) 		c_bh = sb_getblk(sb, sec2);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  24) 		if (!c_bh)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  25) 			return -ENOMEM;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  26) 		memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  27) 		set_buffer_uptodate(c_bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  28) 		mark_buffer_dirty(c_bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  29) 		if (sb->s_flags & SB_SYNCHRONOUS)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  30) 			err = sync_dirty_buffer(c_bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  31) 		brelse(c_bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  32) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  33) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  34) 	return err;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  35) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  36) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  37) static int __exfat_ent_get(struct super_block *sb, unsigned int loc,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  38) 		unsigned int *content)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  39) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  40) 	unsigned int off;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  41) 	sector_t sec;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  42) 	struct buffer_head *bh;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  43) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  44) 	sec = FAT_ENT_OFFSET_SECTOR(sb, loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  45) 	off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  46) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  47) 	bh = sb_bread(sb, sec);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  48) 	if (!bh)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  49) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  50) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  51) 	*content = le32_to_cpu(*(__le32 *)(&bh->b_data[off]));
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  52) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  53) 	/* remap reserved clusters to simplify code */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  54) 	if (*content > EXFAT_BAD_CLUSTER)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  55) 		*content = EXFAT_EOF_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  56) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  57) 	brelse(bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  58) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  59) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  60) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  61) int exfat_ent_set(struct super_block *sb, unsigned int loc,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  62) 		unsigned int content)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  63) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  64) 	unsigned int off;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  65) 	sector_t sec;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  66) 	__le32 *fat_entry;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  67) 	struct buffer_head *bh;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  68) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  69) 	sec = FAT_ENT_OFFSET_SECTOR(sb, loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  70) 	off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  71) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  72) 	bh = sb_bread(sb, sec);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  73) 	if (!bh)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  74) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  75) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  76) 	fat_entry = (__le32 *)&(bh->b_data[off]);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  77) 	*fat_entry = cpu_to_le32(content);
2c7f8937ef915 (Tetsuhiro Kohada 2020-06-16 11:18:07 +0900  78) 	exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  79) 	exfat_mirror_bh(sb, sec, bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  80) 	brelse(bh);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  81) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  82) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  83) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  84) static inline bool is_valid_cluster(struct exfat_sb_info *sbi,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  85) 		unsigned int clus)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  86) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  87) 	if (clus < EXFAT_FIRST_CLUSTER || sbi->num_clusters <= clus)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  88) 		return false;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  89) 	return true;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  90) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  91) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  92) int exfat_ent_get(struct super_block *sb, unsigned int loc,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  93) 		unsigned int *content)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  94) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  95) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  96) 	int err;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  97) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  98) 	if (!is_valid_cluster(sbi, loc)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900  99) 		exfat_fs_error(sb, "invalid access to FAT (entry 0x%08x)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 100) 			loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 101) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 102) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 103) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 104) 	err = __exfat_ent_get(sb, loc, content);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 105) 	if (err) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 106) 		exfat_fs_error(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 107) 			"failed to access to FAT (entry 0x%08x, err:%d)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 108) 			loc, err);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 109) 		return err;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 110) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 111) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 112) 	if (*content == EXFAT_FREE_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 113) 		exfat_fs_error(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 114) 			"invalid access to FAT free cluster (entry 0x%08x)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 115) 			loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 116) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 117) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 118) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 119) 	if (*content == EXFAT_BAD_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 120) 		exfat_fs_error(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 121) 			"invalid access to FAT bad cluster (entry 0x%08x)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 122) 			loc);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 123) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 124) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 125) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 126) 	if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, *content)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 127) 		exfat_fs_error(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 128) 			"invalid access to FAT (entry 0x%08x) bogus content (0x%08x)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 129) 			loc, *content);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 130) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 131) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 132) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 133) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 134) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 135) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 136) int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 137) 		unsigned int len)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 138) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 139) 	if (!len)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 140) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 141) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 142) 	while (len > 1) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 143) 		if (exfat_ent_set(sb, chain, chain + 1))
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 144) 			return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 145) 		chain++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 146) 		len--;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 147) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 148) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 149) 	if (exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER))
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 150) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 151) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 152) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 153) 
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 154) /* This function must be called with bitmap_lock held */
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 155) static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 156) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 157) 	struct super_block *sb = inode->i_sb;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 158) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 159) 	int cur_cmap_i, next_cmap_i;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 160) 	unsigned int num_clusters = 0;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 161) 	unsigned int clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 162) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 163) 	/* invalid cluster number */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 164) 	if (p_chain->dir == EXFAT_FREE_CLUSTER ||
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 165) 	    p_chain->dir == EXFAT_EOF_CLUSTER ||
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 166) 	    p_chain->dir < EXFAT_FIRST_CLUSTER)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 167) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 168) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 169) 	/* no cluster to truncate */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 170) 	if (p_chain->size == 0)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 171) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 172) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 173) 	/* check cluster validation */
a949824f01f3b (hyeongseok.kim   2020-06-04 13:54:28 +0900 174) 	if (!is_valid_cluster(sbi, p_chain->dir)) {
d1727d55c0327 (Joe Perches      2020-04-24 13:31:12 +0900 175) 		exfat_err(sb, "invalid start cluster (%u)", p_chain->dir);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 176) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 177) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 178) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 179) 	clu = p_chain->dir;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 180) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 181) 	cur_cmap_i = next_cmap_i =
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 182) 		BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu));
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 183) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 184) 	if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 185) 		unsigned int last_cluster = p_chain->dir + p_chain->size - 1;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 186) 		do {
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 187) 			bool sync = false;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 188) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 189) 			if (clu < last_cluster)
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 190) 				next_cmap_i =
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 191) 				  BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1));
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 192) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 193) 			/* flush bitmap only if index would be changed or for last cluster */
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 194) 			if (clu == last_cluster || cur_cmap_i != next_cmap_i) {
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 195) 				sync = true;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 196) 				cur_cmap_i = next_cmap_i;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 197) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 198) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 199) 			exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 200) 			clu++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 201) 			num_clusters++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 202) 		} while (num_clusters < p_chain->size);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 203) 	} else {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 204) 		do {
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 205) 			bool sync = false;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 206) 			unsigned int n_clu = clu;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 207) 			int err = exfat_get_next_cluster(sb, &n_clu);
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 208) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 209) 			if (err || n_clu == EXFAT_EOF_CLUSTER)
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 210) 				sync = true;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 211) 			else
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 212) 				next_cmap_i =
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 213) 				  BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu));
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 214) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 215) 			if (cur_cmap_i != next_cmap_i) {
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 216) 				sync = true;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 217) 				cur_cmap_i = next_cmap_i;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 218) 			}
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 219) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 220) 			exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 221) 			clu = n_clu;
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 222) 			num_clusters++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 223) 
f728760aa923f (Hyeongseok Kim   2021-02-01 10:02:46 +0900 224) 			if (err)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 225) 				goto dec_used_clus;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 226) 		} while (clu != EXFAT_EOF_CLUSTER);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 227) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 228) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 229) dec_used_clus:
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 230) 	sbi->used_clusters -= num_clusters;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 231) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 232) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 233) 
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 234) int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 235) {
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 236) 	int ret = 0;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 237) 
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 238) 	mutex_lock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 239) 	ret = __exfat_free_cluster(inode, p_chain);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 240) 	mutex_unlock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 241) 
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 242) 	return ret;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 243) }
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 244) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 245) int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 246) 		unsigned int *ret_clu)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 247) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 248) 	unsigned int clu, next;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 249) 	unsigned int count = 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 250) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 251) 	next = p_chain->dir;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 252) 	if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 253) 		*ret_clu = next + p_chain->size - 1;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 254) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 255) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 256) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 257) 	do {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 258) 		count++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 259) 		clu = next;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 260) 		if (exfat_ent_get(sb, clu, &next))
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 261) 			return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 262) 	} while (next != EXFAT_EOF_CLUSTER);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 263) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 264) 	if (p_chain->size != count) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 265) 		exfat_fs_error(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 266) 			"bogus directory size (clus : ondisk(%d) != counted(%d))",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 267) 			p_chain->size, count);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 268) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 269) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 270) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 271) 	*ret_clu = clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 272) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 273) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 274) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 275) int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 276) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 277) 	struct super_block *sb = dir->i_sb;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 278) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 279) 	struct buffer_head *bhs[MAX_BUF_PER_PAGE];
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 280) 	int nr_bhs = MAX_BUF_PER_PAGE;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 281) 	sector_t blknr, last_blknr;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 282) 	int err, i, n;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 283) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 284) 	blknr = exfat_cluster_to_sector(sbi, clu);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 285) 	last_blknr = blknr + sbi->sect_per_clus;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 286) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 287) 	if (last_blknr > sbi->num_sectors && sbi->num_sectors > 0) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 288) 		exfat_fs_error_ratelimit(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 289) 			"%s: out of range(sect:%llu len:%u)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 290) 			__func__, (unsigned long long)blknr,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 291) 			sbi->sect_per_clus);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 292) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 293) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 294) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 295) 	/* Zeroing the unused blocks on this cluster */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 296) 	while (blknr < last_blknr) {
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 297) 		for (n = 0; n < nr_bhs && blknr < last_blknr; n++, blknr++) {
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 298) 			bhs[n] = sb_getblk(sb, blknr);
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 299) 			if (!bhs[n]) {
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 300) 				err = -ENOMEM;
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 301) 				goto release_bhs;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 302) 			}
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 303) 			memset(bhs[n]->b_data, 0, sb->s_blocksize);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 304) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 305) 
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 306) 		err = exfat_update_bhs(bhs, n, IS_DIRSYNC(dir));
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 307) 		if (err)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 308) 			goto release_bhs;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 309) 
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 310) 		for (i = 0; i < n; i++)
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 311) 			brelse(bhs[i]);
4dc7d35e09ba7 (Tetsuhiro Kohada 2020-06-24 11:30:40 +0900 312) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 313) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 314) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 315) release_bhs:
d1727d55c0327 (Joe Perches      2020-04-24 13:31:12 +0900 316) 	exfat_err(sb, "failed zeroed sect %llu\n", (unsigned long long)blknr);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 317) 	for (i = 0; i < n; i++)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 318) 		bforget(bhs[i]);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 319) 	return err;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 320) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 321) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 322) int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
23befe490ba88 (Hyeongseok Kim   2021-03-15 13:12:55 +0900 323) 		struct exfat_chain *p_chain, bool sync_bmap)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 324) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 325) 	int ret = -ENOSPC;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 326) 	unsigned int num_clusters = 0, total_cnt;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 327) 	unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 328) 	struct super_block *sb = inode->i_sb;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 329) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 330) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 331) 	total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 332) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 333) 	if (unlikely(total_cnt < sbi->used_clusters)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 334) 		exfat_fs_error_ratelimit(sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 335) 			"%s: invalid used clusters(t:%u,u:%u)\n",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 336) 			__func__, total_cnt, sbi->used_clusters);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 337) 		return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 338) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 339) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 340) 	if (num_alloc > total_cnt - sbi->used_clusters)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 341) 		return -ENOSPC;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 342) 
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 343) 	mutex_lock(&sbi->bitmap_lock);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 344) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 345) 	hint_clu = p_chain->dir;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 346) 	/* find new cluster */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 347) 	if (hint_clu == EXFAT_EOF_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 348) 		if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) {
d1727d55c0327 (Joe Perches      2020-04-24 13:31:12 +0900 349) 			exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)\n",
d1727d55c0327 (Joe Perches      2020-04-24 13:31:12 +0900 350) 				  sbi->clu_srch_ptr);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 351) 			sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 352) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 353) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 354) 		hint_clu = exfat_find_free_bitmap(sb, sbi->clu_srch_ptr);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 355) 		if (hint_clu == EXFAT_EOF_CLUSTER) {
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 356) 			ret = -ENOSPC;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 357) 			goto unlock;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 358) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 359) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 360) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 361) 	/* check cluster validation */
a949824f01f3b (hyeongseok.kim   2020-06-04 13:54:28 +0900 362) 	if (!is_valid_cluster(sbi, hint_clu)) {
d1727d55c0327 (Joe Perches      2020-04-24 13:31:12 +0900 363) 		exfat_err(sb, "hint_cluster is invalid (%u)",
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 364) 			hint_clu);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 365) 		hint_clu = EXFAT_FIRST_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 366) 		if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 367) 			if (exfat_chain_cont_cluster(sb, p_chain->dir,
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 368) 					num_clusters)) {
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 369) 				ret = -EIO;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 370) 				goto unlock;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 371) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 372) 			p_chain->flags = ALLOC_FAT_CHAIN;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 373) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 374) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 375) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 376) 	p_chain->dir = EXFAT_EOF_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 377) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 378) 	while ((new_clu = exfat_find_free_bitmap(sb, hint_clu)) !=
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 379) 	       EXFAT_EOF_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 380) 		if (new_clu != hint_clu &&
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 381) 		    p_chain->flags == ALLOC_NO_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 382) 			if (exfat_chain_cont_cluster(sb, p_chain->dir,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 383) 					num_clusters)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 384) 				ret = -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 385) 				goto free_cluster;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 386) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 387) 			p_chain->flags = ALLOC_FAT_CHAIN;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 388) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 389) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 390) 		/* update allocation bitmap */
23befe490ba88 (Hyeongseok Kim   2021-03-15 13:12:55 +0900 391) 		if (exfat_set_bitmap(inode, new_clu, sync_bmap)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 392) 			ret = -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 393) 			goto free_cluster;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 394) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 395) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 396) 		num_clusters++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 397) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 398) 		/* update FAT table */
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 399) 		if (p_chain->flags == ALLOC_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 400) 			if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 401) 				ret = -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 402) 				goto free_cluster;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 403) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 404) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 405) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 406) 		if (p_chain->dir == EXFAT_EOF_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 407) 			p_chain->dir = new_clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 408) 		} else if (p_chain->flags == ALLOC_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 409) 			if (exfat_ent_set(sb, last_clu, new_clu)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 410) 				ret = -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 411) 				goto free_cluster;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 412) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 413) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 414) 		last_clu = new_clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 415) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 416) 		if (--num_alloc == 0) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 417) 			sbi->clu_srch_ptr = hint_clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 418) 			sbi->used_clusters += num_clusters;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 419) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 420) 			p_chain->size += num_clusters;
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 421) 			mutex_unlock(&sbi->bitmap_lock);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 422) 			return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 423) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 424) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 425) 		hint_clu = new_clu + 1;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 426) 		if (hint_clu >= sbi->num_clusters) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 427) 			hint_clu = EXFAT_FIRST_CLUSTER;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 428) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 429) 			if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 430) 				if (exfat_chain_cont_cluster(sb, p_chain->dir,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 431) 						num_clusters)) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 432) 					ret = -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 433) 					goto free_cluster;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 434) 				}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 435) 				p_chain->flags = ALLOC_FAT_CHAIN;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 436) 			}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 437) 		}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 438) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 439) free_cluster:
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 440) 	if (num_clusters)
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 441) 		__exfat_free_cluster(inode, p_chain);
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 442) unlock:
5c2d728507299 (Hyeongseok Kim   2021-03-02 14:05:20 +0900 443) 	mutex_unlock(&sbi->bitmap_lock);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 444) 	return ret;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 445) }
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 446) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 447) int exfat_count_num_clusters(struct super_block *sb,
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 448) 		struct exfat_chain *p_chain, unsigned int *ret_count)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 449) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 450) 	unsigned int i, count;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 451) 	unsigned int clu;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 452) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 453) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 454) 	if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 455) 		*ret_count = 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 456) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 457) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 458) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 459) 	if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 460) 		*ret_count = p_chain->size;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 461) 		return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 462) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 463) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 464) 	clu = p_chain->dir;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 465) 	count = 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 466) 	for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) {
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 467) 		count++;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 468) 		if (exfat_ent_get(sb, clu, &clu))
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 469) 			return -EIO;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 470) 		if (clu == EXFAT_EOF_CLUSTER)
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 471) 			break;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 472) 	}
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 473) 
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 474) 	*ret_count = count;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 475) 	return 0;
31023864e67a5 (Namjae Jeon      2020-03-02 15:21:37 +0900 476) }