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