Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include <asm/unaligned.h>
0008 #include <linux/buffer_head.h>
0009 #include <linux/blkdev.h>
0010 
0011 #include "exfat_raw.h"
0012 #include "exfat_fs.h"
0013 
0014 static int exfat_mirror_bh(struct super_block *sb, sector_t sec,
0015         struct buffer_head *bh)
0016 {
0017     struct buffer_head *c_bh;
0018     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0019     sector_t sec2;
0020     int err = 0;
0021 
0022     if (sbi->FAT2_start_sector != sbi->FAT1_start_sector) {
0023         sec2 = sec - sbi->FAT1_start_sector + sbi->FAT2_start_sector;
0024         c_bh = sb_getblk(sb, sec2);
0025         if (!c_bh)
0026             return -ENOMEM;
0027         memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
0028         set_buffer_uptodate(c_bh);
0029         mark_buffer_dirty(c_bh);
0030         if (sb->s_flags & SB_SYNCHRONOUS)
0031             err = sync_dirty_buffer(c_bh);
0032         brelse(c_bh);
0033     }
0034 
0035     return err;
0036 }
0037 
0038 static int __exfat_ent_get(struct super_block *sb, unsigned int loc,
0039         unsigned int *content)
0040 {
0041     unsigned int off;
0042     sector_t sec;
0043     struct buffer_head *bh;
0044 
0045     sec = FAT_ENT_OFFSET_SECTOR(sb, loc);
0046     off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc);
0047 
0048     bh = sb_bread(sb, sec);
0049     if (!bh)
0050         return -EIO;
0051 
0052     *content = le32_to_cpu(*(__le32 *)(&bh->b_data[off]));
0053 
0054     /* remap reserved clusters to simplify code */
0055     if (*content > EXFAT_BAD_CLUSTER)
0056         *content = EXFAT_EOF_CLUSTER;
0057 
0058     brelse(bh);
0059     return 0;
0060 }
0061 
0062 int exfat_ent_set(struct super_block *sb, unsigned int loc,
0063         unsigned int content)
0064 {
0065     unsigned int off;
0066     sector_t sec;
0067     __le32 *fat_entry;
0068     struct buffer_head *bh;
0069 
0070     sec = FAT_ENT_OFFSET_SECTOR(sb, loc);
0071     off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc);
0072 
0073     bh = sb_bread(sb, sec);
0074     if (!bh)
0075         return -EIO;
0076 
0077     fat_entry = (__le32 *)&(bh->b_data[off]);
0078     *fat_entry = cpu_to_le32(content);
0079     exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
0080     exfat_mirror_bh(sb, sec, bh);
0081     brelse(bh);
0082     return 0;
0083 }
0084 
0085 int exfat_ent_get(struct super_block *sb, unsigned int loc,
0086         unsigned int *content)
0087 {
0088     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0089     int err;
0090 
0091     if (!is_valid_cluster(sbi, loc)) {
0092         exfat_fs_error(sb, "invalid access to FAT (entry 0x%08x)",
0093             loc);
0094         return -EIO;
0095     }
0096 
0097     err = __exfat_ent_get(sb, loc, content);
0098     if (err) {
0099         exfat_fs_error(sb,
0100             "failed to access to FAT (entry 0x%08x, err:%d)",
0101             loc, err);
0102         return err;
0103     }
0104 
0105     if (*content == EXFAT_FREE_CLUSTER) {
0106         exfat_fs_error(sb,
0107             "invalid access to FAT free cluster (entry 0x%08x)",
0108             loc);
0109         return -EIO;
0110     }
0111 
0112     if (*content == EXFAT_BAD_CLUSTER) {
0113         exfat_fs_error(sb,
0114             "invalid access to FAT bad cluster (entry 0x%08x)",
0115             loc);
0116         return -EIO;
0117     }
0118 
0119     if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, *content)) {
0120         exfat_fs_error(sb,
0121             "invalid access to FAT (entry 0x%08x) bogus content (0x%08x)",
0122             loc, *content);
0123         return -EIO;
0124     }
0125 
0126     return 0;
0127 }
0128 
0129 int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain,
0130         unsigned int len)
0131 {
0132     if (!len)
0133         return 0;
0134 
0135     while (len > 1) {
0136         if (exfat_ent_set(sb, chain, chain + 1))
0137             return -EIO;
0138         chain++;
0139         len--;
0140     }
0141 
0142     if (exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER))
0143         return -EIO;
0144     return 0;
0145 }
0146 
0147 /* This function must be called with bitmap_lock held */
0148 static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
0149 {
0150     struct super_block *sb = inode->i_sb;
0151     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0152     int cur_cmap_i, next_cmap_i;
0153     unsigned int num_clusters = 0;
0154     unsigned int clu;
0155 
0156     /* invalid cluster number */
0157     if (p_chain->dir == EXFAT_FREE_CLUSTER ||
0158         p_chain->dir == EXFAT_EOF_CLUSTER ||
0159         p_chain->dir < EXFAT_FIRST_CLUSTER)
0160         return 0;
0161 
0162     /* no cluster to truncate */
0163     if (p_chain->size == 0)
0164         return 0;
0165 
0166     /* check cluster validation */
0167     if (!is_valid_cluster(sbi, p_chain->dir)) {
0168         exfat_err(sb, "invalid start cluster (%u)", p_chain->dir);
0169         return -EIO;
0170     }
0171 
0172     clu = p_chain->dir;
0173 
0174     cur_cmap_i = next_cmap_i =
0175         BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu));
0176 
0177     if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0178         unsigned int last_cluster = p_chain->dir + p_chain->size - 1;
0179         do {
0180             bool sync = false;
0181 
0182             if (clu < last_cluster)
0183                 next_cmap_i =
0184                   BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1));
0185 
0186             /* flush bitmap only if index would be changed or for last cluster */
0187             if (clu == last_cluster || cur_cmap_i != next_cmap_i) {
0188                 sync = true;
0189                 cur_cmap_i = next_cmap_i;
0190             }
0191 
0192             exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
0193             clu++;
0194             num_clusters++;
0195         } while (num_clusters < p_chain->size);
0196     } else {
0197         do {
0198             bool sync = false;
0199             unsigned int n_clu = clu;
0200             int err = exfat_get_next_cluster(sb, &n_clu);
0201 
0202             if (err || n_clu == EXFAT_EOF_CLUSTER)
0203                 sync = true;
0204             else
0205                 next_cmap_i =
0206                   BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu));
0207 
0208             if (cur_cmap_i != next_cmap_i) {
0209                 sync = true;
0210                 cur_cmap_i = next_cmap_i;
0211             }
0212 
0213             exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
0214             clu = n_clu;
0215             num_clusters++;
0216 
0217             if (err)
0218                 goto dec_used_clus;
0219         } while (clu != EXFAT_EOF_CLUSTER);
0220     }
0221 
0222 dec_used_clus:
0223     sbi->used_clusters -= num_clusters;
0224     return 0;
0225 }
0226 
0227 int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
0228 {
0229     int ret = 0;
0230 
0231     mutex_lock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
0232     ret = __exfat_free_cluster(inode, p_chain);
0233     mutex_unlock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
0234 
0235     return ret;
0236 }
0237 
0238 int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
0239         unsigned int *ret_clu)
0240 {
0241     unsigned int clu, next;
0242     unsigned int count = 0;
0243 
0244     next = p_chain->dir;
0245     if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0246         *ret_clu = next + p_chain->size - 1;
0247         return 0;
0248     }
0249 
0250     do {
0251         count++;
0252         clu = next;
0253         if (exfat_ent_get(sb, clu, &next))
0254             return -EIO;
0255     } while (next != EXFAT_EOF_CLUSTER);
0256 
0257     if (p_chain->size != count) {
0258         exfat_fs_error(sb,
0259             "bogus directory size (clus : ondisk(%d) != counted(%d))",
0260             p_chain->size, count);
0261         return -EIO;
0262     }
0263 
0264     *ret_clu = clu;
0265     return 0;
0266 }
0267 
0268 int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
0269 {
0270     struct super_block *sb = dir->i_sb;
0271     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0272     struct buffer_head *bh;
0273     sector_t blknr, last_blknr, i;
0274 
0275     blknr = exfat_cluster_to_sector(sbi, clu);
0276     last_blknr = blknr + sbi->sect_per_clus;
0277 
0278     if (last_blknr > sbi->num_sectors && sbi->num_sectors > 0) {
0279         exfat_fs_error_ratelimit(sb,
0280             "%s: out of range(sect:%llu len:%u)",
0281             __func__, (unsigned long long)blknr,
0282             sbi->sect_per_clus);
0283         return -EIO;
0284     }
0285 
0286     /* Zeroing the unused blocks on this cluster */
0287     for (i = blknr; i < last_blknr; i++) {
0288         bh = sb_getblk(sb, i);
0289         if (!bh)
0290             return -ENOMEM;
0291 
0292         memset(bh->b_data, 0, sb->s_blocksize);
0293         set_buffer_uptodate(bh);
0294         mark_buffer_dirty(bh);
0295         brelse(bh);
0296     }
0297 
0298     if (IS_DIRSYNC(dir))
0299         return sync_blockdev_range(sb->s_bdev,
0300                 EXFAT_BLK_TO_B(blknr, sb),
0301                 EXFAT_BLK_TO_B(last_blknr, sb) - 1);
0302 
0303     return 0;
0304 }
0305 
0306 int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
0307         struct exfat_chain *p_chain, bool sync_bmap)
0308 {
0309     int ret = -ENOSPC;
0310     unsigned int num_clusters = 0, total_cnt;
0311     unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER;
0312     struct super_block *sb = inode->i_sb;
0313     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0314 
0315     total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi);
0316 
0317     if (unlikely(total_cnt < sbi->used_clusters)) {
0318         exfat_fs_error_ratelimit(sb,
0319             "%s: invalid used clusters(t:%u,u:%u)\n",
0320             __func__, total_cnt, sbi->used_clusters);
0321         return -EIO;
0322     }
0323 
0324     if (num_alloc > total_cnt - sbi->used_clusters)
0325         return -ENOSPC;
0326 
0327     mutex_lock(&sbi->bitmap_lock);
0328 
0329     hint_clu = p_chain->dir;
0330     /* find new cluster */
0331     if (hint_clu == EXFAT_EOF_CLUSTER) {
0332         if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) {
0333             exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)",
0334                   sbi->clu_srch_ptr);
0335             sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER;
0336         }
0337 
0338         hint_clu = exfat_find_free_bitmap(sb, sbi->clu_srch_ptr);
0339         if (hint_clu == EXFAT_EOF_CLUSTER) {
0340             ret = -ENOSPC;
0341             goto unlock;
0342         }
0343     }
0344 
0345     /* check cluster validation */
0346     if (!is_valid_cluster(sbi, hint_clu)) {
0347         exfat_err(sb, "hint_cluster is invalid (%u)",
0348             hint_clu);
0349         hint_clu = EXFAT_FIRST_CLUSTER;
0350         if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0351             if (exfat_chain_cont_cluster(sb, p_chain->dir,
0352                     num_clusters)) {
0353                 ret = -EIO;
0354                 goto unlock;
0355             }
0356             p_chain->flags = ALLOC_FAT_CHAIN;
0357         }
0358     }
0359 
0360     p_chain->dir = EXFAT_EOF_CLUSTER;
0361 
0362     while ((new_clu = exfat_find_free_bitmap(sb, hint_clu)) !=
0363            EXFAT_EOF_CLUSTER) {
0364         if (new_clu != hint_clu &&
0365             p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0366             if (exfat_chain_cont_cluster(sb, p_chain->dir,
0367                     num_clusters)) {
0368                 ret = -EIO;
0369                 goto free_cluster;
0370             }
0371             p_chain->flags = ALLOC_FAT_CHAIN;
0372         }
0373 
0374         /* update allocation bitmap */
0375         if (exfat_set_bitmap(inode, new_clu, sync_bmap)) {
0376             ret = -EIO;
0377             goto free_cluster;
0378         }
0379 
0380         num_clusters++;
0381 
0382         /* update FAT table */
0383         if (p_chain->flags == ALLOC_FAT_CHAIN) {
0384             if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) {
0385                 ret = -EIO;
0386                 goto free_cluster;
0387             }
0388         }
0389 
0390         if (p_chain->dir == EXFAT_EOF_CLUSTER) {
0391             p_chain->dir = new_clu;
0392         } else if (p_chain->flags == ALLOC_FAT_CHAIN) {
0393             if (exfat_ent_set(sb, last_clu, new_clu)) {
0394                 ret = -EIO;
0395                 goto free_cluster;
0396             }
0397         }
0398         last_clu = new_clu;
0399 
0400         if (--num_alloc == 0) {
0401             sbi->clu_srch_ptr = hint_clu;
0402             sbi->used_clusters += num_clusters;
0403 
0404             p_chain->size += num_clusters;
0405             mutex_unlock(&sbi->bitmap_lock);
0406             return 0;
0407         }
0408 
0409         hint_clu = new_clu + 1;
0410         if (hint_clu >= sbi->num_clusters) {
0411             hint_clu = EXFAT_FIRST_CLUSTER;
0412 
0413             if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0414                 if (exfat_chain_cont_cluster(sb, p_chain->dir,
0415                         num_clusters)) {
0416                     ret = -EIO;
0417                     goto free_cluster;
0418                 }
0419                 p_chain->flags = ALLOC_FAT_CHAIN;
0420             }
0421         }
0422     }
0423 free_cluster:
0424     if (num_clusters)
0425         __exfat_free_cluster(inode, p_chain);
0426 unlock:
0427     mutex_unlock(&sbi->bitmap_lock);
0428     return ret;
0429 }
0430 
0431 int exfat_count_num_clusters(struct super_block *sb,
0432         struct exfat_chain *p_chain, unsigned int *ret_count)
0433 {
0434     unsigned int i, count;
0435     unsigned int clu;
0436     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0437 
0438     if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) {
0439         *ret_count = 0;
0440         return 0;
0441     }
0442 
0443     if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
0444         *ret_count = p_chain->size;
0445         return 0;
0446     }
0447 
0448     clu = p_chain->dir;
0449     count = 0;
0450     for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) {
0451         count++;
0452         if (exfat_ent_get(sb, clu, &clu))
0453             return -EIO;
0454         if (clu == EXFAT_EOF_CLUSTER)
0455             break;
0456     }
0457 
0458     *ret_count = count;
0459     return 0;
0460 }