Merge tag 'trace-v6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[linux-block.git] / fs / exfat / fatent.c
index 41ae4cce1f4203c1d8ecd6e4bd92e23fc42f7366..56b870d9cc0deffd26169bb915179851655d33f8 100644 (file)
@@ -307,7 +307,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
                struct exfat_chain *p_chain, bool sync_bmap)
 {
        int ret = -ENOSPC;
-       unsigned int num_clusters = 0, total_cnt;
+       unsigned int total_cnt;
        unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER;
        struct super_block *sb = inode->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -344,17 +344,11 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
 
        /* check cluster validation */
        if (!is_valid_cluster(sbi, hint_clu)) {
-               exfat_err(sb, "hint_cluster is invalid (%u)",
-                       hint_clu);
+               if (hint_clu != sbi->num_clusters)
+                       exfat_err(sb, "hint_cluster is invalid (%u), rewind to the first cluster",
+                                       hint_clu);
                hint_clu = EXFAT_FIRST_CLUSTER;
-               if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
-                       if (exfat_chain_cont_cluster(sb, p_chain->dir,
-                                       num_clusters)) {
-                               ret = -EIO;
-                               goto unlock;
-                       }
-                       p_chain->flags = ALLOC_FAT_CHAIN;
-               }
+               p_chain->flags = ALLOC_FAT_CHAIN;
        }
 
        p_chain->dir = EXFAT_EOF_CLUSTER;
@@ -364,7 +358,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
                if (new_clu != hint_clu &&
                    p_chain->flags == ALLOC_NO_FAT_CHAIN) {
                        if (exfat_chain_cont_cluster(sb, p_chain->dir,
-                                       num_clusters)) {
+                                       p_chain->size)) {
                                ret = -EIO;
                                goto free_cluster;
                        }
@@ -377,8 +371,6 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
                        goto free_cluster;
                }
 
-               num_clusters++;
-
                /* update FAT table */
                if (p_chain->flags == ALLOC_FAT_CHAIN) {
                        if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) {
@@ -395,13 +387,14 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
                                goto free_cluster;
                        }
                }
+               p_chain->size++;
+
                last_clu = new_clu;
 
-               if (--num_alloc == 0) {
+               if (p_chain->size == num_alloc) {
                        sbi->clu_srch_ptr = hint_clu;
-                       sbi->used_clusters += num_clusters;
+                       sbi->used_clusters += num_alloc;
 
-                       p_chain->size += num_clusters;
                        mutex_unlock(&sbi->bitmap_lock);
                        return 0;
                }
@@ -412,7 +405,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
 
                        if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
                                if (exfat_chain_cont_cluster(sb, p_chain->dir,
-                                               num_clusters)) {
+                                               p_chain->size)) {
                                        ret = -EIO;
                                        goto free_cluster;
                                }
@@ -421,8 +414,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
                }
        }
 free_cluster:
-       if (num_clusters)
-               __exfat_free_cluster(inode, p_chain);
+       __exfat_free_cluster(inode, p_chain);
 unlock:
        mutex_unlock(&sbi->bitmap_lock);
        return ret;