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) }