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