]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/staging/exfat/exfat_super.c
staging: exfat: fix multiple definition error of `rename_file'
[mirror_ubuntu-jammy-kernel.git] / drivers / staging / exfat / exfat_super.c
index 3b2b0ceb7297a0bcd932306d64f2189de486eaef..9f91853b189b01ee71143b1932ac1424bce6a15d 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/sched.h>
 #include <linux/fs_struct.h>
 #include <linux/namei.h>
-
+#include <linux/random.h>
 #include <linux/string.h>
 #include <linux/nls.h>
 #include <linux/mutex.h>
@@ -284,12 +284,12 @@ static const struct dentry_operations exfat_dentry_ops = {
        .d_compare      = exfat_cmp,
 };
 
-static DEFINE_SEMAPHORE(z_sem);
+static DEFINE_MUTEX(z_mutex);
 
 static inline void fs_sync(struct super_block *sb, bool do_sync)
 {
        if (do_sync)
-               bdev_sync(sb);
+               exfat_bdev_sync(sb);
 }
 
 /*
@@ -353,26 +353,28 @@ static int ffsMountVol(struct super_block *sb)
 
        pr_info("[EXFAT] trying to mount...\n");
 
-       down(&z_sem);
+       mutex_lock(&z_mutex);
 
-       buf_init(sb);
+       exfat_buf_init(sb);
 
-       sema_init(&p_fs->v_sem, 1);
+       mutex_init(&p_fs->v_mutex);
        p_fs->dev_ejected = 0;
 
        /* open the block device */
-       bdev_open(sb);
+       exfat_bdev_open(sb);
 
        if (p_bd->sector_size < sb->s_blocksize) {
-               ret = FFS_MEDIAERR;
+               printk(KERN_INFO "EXFAT: mount failed - sector size %d less than blocksize %ld\n",
+                       p_bd->sector_size,  sb->s_blocksize);
+               ret = -EINVAL;
                goto out;
        }
        if (p_bd->sector_size > sb->s_blocksize)
                sb_set_blocksize(sb, p_bd->sector_size);
 
        /* read Sector 0 */
-       if (sector_read(sb, 0, &tmp_bh, 1) != FFS_SUCCESS) {
-               ret = FFS_MEDIAERR;
+       if (sector_read(sb, 0, &tmp_bh, 1) != 0) {
+               ret = -EIO;
                goto out;
        }
 
@@ -383,8 +385,8 @@ static int ffsMountVol(struct super_block *sb)
        /* check the validity of PBR */
        if (GET16_A(p_pbr->signature) != PBR_SIGNATURE) {
                brelse(tmp_bh);
-               bdev_close(sb);
-               ret = FFS_FORMATERR;
+               exfat_bdev_close(sb);
+               ret = -EFSCORRUPTED;
                goto out;
        }
 
@@ -394,16 +396,10 @@ static int ffsMountVol(struct super_block *sb)
                        break;
 
        if (i < 53) {
-#ifdef CONFIG_EXFAT_DONT_MOUNT_VFAT
+               /* Not sure how we'd get here, but complain if it does */
                ret = -EINVAL;
-               printk(KERN_INFO "EXFAT: Attempted to mount VFAT filesystem\n");
+               pr_info("EXFAT: Attempted to mount VFAT filesystem\n");
                goto out;
-#else
-               if (GET16(p_pbr->bpb + 11)) /* num_fat_sectors */
-                       ret = fat16_mount(sb, p_pbr);
-               else
-                       ret = fat32_mount(sb, p_pbr);
-#endif
        } else {
                ret = exfat_mount(sb, p_pbr);
        }
@@ -411,38 +407,34 @@ static int ffsMountVol(struct super_block *sb)
        brelse(tmp_bh);
 
        if (ret) {
-               bdev_close(sb);
+               exfat_bdev_close(sb);
                goto out;
        }
 
-       if (p_fs->vol_type == EXFAT) {
-               ret = load_alloc_bitmap(sb);
-               if (ret) {
-                       bdev_close(sb);
-                       goto out;
-               }
-               ret = load_upcase_table(sb);
-               if (ret) {
-                       free_alloc_bitmap(sb);
-                       bdev_close(sb);
-                       goto out;
-               }
+       ret = load_alloc_bitmap(sb);
+       if (ret) {
+               exfat_bdev_close(sb);
+               goto out;
+       }
+       ret = load_upcase_table(sb);
+       if (ret) {
+               free_alloc_bitmap(sb);
+               exfat_bdev_close(sb);
+               goto out;
        }
 
        if (p_fs->dev_ejected) {
-               if (p_fs->vol_type == EXFAT) {
-                       free_upcase_table(sb);
-                       free_alloc_bitmap(sb);
-               }
-               bdev_close(sb);
-               ret = FFS_MEDIAERR;
+               free_upcase_table(sb);
+               free_alloc_bitmap(sb);
+               exfat_bdev_close(sb);
+               ret = -EIO;
                goto out;
        }
 
        pr_info("[EXFAT] mounted successfully\n");
 
 out:
-       up(&z_sem);
+       mutex_unlock(&z_mutex);
 
        return ret;
 }
@@ -450,39 +442,37 @@ out:
 static int ffsUmountVol(struct super_block *sb)
 {
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       int err = FFS_SUCCESS;
+       int err = 0;
 
        pr_info("[EXFAT] trying to unmount...\n");
 
-       down(&z_sem);
+       mutex_lock(&z_mutex);
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
-       fs_sync(sb, false);
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 
-       if (p_fs->vol_type == EXFAT) {
-               free_upcase_table(sb);
-               free_alloc_bitmap(sb);
-       }
+       free_upcase_table(sb);
+       free_alloc_bitmap(sb);
 
-       FAT_release_all(sb);
-       buf_release_all(sb);
+       exfat_fat_release_all(sb);
+       exfat_buf_release_all(sb);
 
        /* close the block device */
-       bdev_close(sb);
+       exfat_bdev_close(sb);
 
        if (p_fs->dev_ejected) {
                pr_info("[EXFAT] unmounted with media errors. Device is already ejected.\n");
-               err = FFS_MEDIAERR;
+               err = -EIO;
        }
 
-       buf_shutdown(sb);
+       exfat_buf_shutdown(sb);
 
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
-       up(&z_sem);
+       mutex_unlock(&p_fs->v_mutex);
+       mutex_unlock(&z_mutex);
 
        pr_info("[EXFAT] unmounted successfully\n");
 
@@ -491,15 +481,15 @@ static int ffsUmountVol(struct super_block *sb)
 
 static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info)
 {
-       int err = FFS_SUCCESS;
+       int err = 0;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        /* check the validity of pointer parameters */
        if (!info)
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        if (p_fs->used_clusters == UINT_MAX)
                p_fs->used_clusters = p_fs->fs_func->count_used_clusters(sb);
@@ -511,31 +501,31 @@ static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info)
        info->FreeClusters = info->NumClusters - info->UsedClusters;
 
        if (p_fs->dev_ejected)
-               err = FFS_MEDIAERR;
+               err = -EIO;
 
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return err;
 }
 
 static int ffsSyncVol(struct super_block *sb, bool do_sync)
 {
-       int err = FFS_SUCCESS;
+       int err = 0;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* synchronize the file system */
        fs_sync(sb, do_sync);
        fs_set_vol_flags(sb, VOL_CLEAN);
 
        if (p_fs->dev_ejected)
-               err = FFS_MEDIAERR;
+               err = -EIO;
 
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return err;
 }
@@ -559,10 +549,10 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
 
        /* check the validity of pointer parameters */
        if (!fid || !path || (*path == '\0'))
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check the validity of directory name in the given pathname */
        ret = resolve_path(inode, path, &dir, &uni_name);
@@ -578,7 +568,7 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
        dentry = p_fs->fs_func->find_dir_entry(sb, &dir, &uni_name, num_entries,
                                               &dos_name, TYPE_ALL);
        if (dentry < -1) {
-               ret = FFS_NOTFOUND;
+               ret = -ENOENT;
                goto out;
        }
 
@@ -597,22 +587,13 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
                fid->size = 0;
                fid->start_clu = p_fs->root_dir;
        } else {
-               if (p_fs->vol_type == EXFAT) {
-                       es = get_entry_set_in_dir(sb, &dir, dentry,
-                                                 ES_2_ENTRIES, &ep);
-                       if (!es) {
-                               ret =  FFS_MEDIAERR;
-                               goto out;
-                       }
-                       ep2 = ep + 1;
-               } else {
-                       ep = get_entry_in_dir(sb, &dir, dentry, NULL);
-                       if (!ep) {
-                               ret =  FFS_MEDIAERR;
-                               goto out;
-                       }
-                       ep2 = ep;
+               es = get_entry_set_in_dir(sb, &dir, dentry,
+                                         ES_2_ENTRIES, &ep);
+               if (!es) {
+                       ret =  -ENOENT;
+                       goto out;
                }
+               ep2 = ep + 1;
 
                fid->type = p_fs->fs_func->get_entry_type(ep);
                fid->rwoffset = 0;
@@ -628,15 +609,14 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
                        fid->start_clu = p_fs->fs_func->get_entry_clu0(ep2);
                }
 
-               if (p_fs->vol_type == EXFAT)
-                       release_entry_set(es);
+               release_entry_set(es);
        }
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -648,14 +628,14 @@ static int ffsCreateFile(struct inode *inode, char *path, u8 mode,
        struct uni_name_t uni_name;
        struct super_block *sb = inode->i_sb;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       int ret;
+       int ret = 0;
 
        /* check the validity of pointer parameters */
        if (!fid || !path || (*path == '\0'))
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check the validity of directory name in the given pathname */
        ret = resolve_path(inode, path, &dir, &uni_name);
@@ -667,17 +647,17 @@ static int ffsCreateFile(struct inode *inode, char *path, u8 mode,
        /* create a new file */
        ret = create_file(inode, &dir, &uni_name, mode, fid);
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -697,18 +677,18 @@ static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer,
 
        /* check the validity of the given file id */
        if (!fid)
-               return FFS_INVALIDFID;
+               return -EINVAL;
 
        /* check the validity of pointer parameters */
        if (!buffer)
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check if the given file ID is opened */
        if (fid->type != TYPE_FILE) {
-               ret = FFS_PERMISSIONERR;
+               ret = -EPERM;
                goto out;
        }
 
@@ -721,7 +701,7 @@ static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer,
        if (count == 0) {
                if (rcount)
                        *rcount = 0;
-               ret = FFS_EOF;
+               ret = 0;
                goto out;
        }
 
@@ -742,9 +722,11 @@ static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer,
                        }
 
                        while (clu_offset > 0) {
-                               /* clu = FAT_read(sb, clu); */
-                               if (FAT_read(sb, clu, &clu) == -1)
-                                       return FFS_MEDIAERR;
+                               /* clu = exfat_fat_read(sb, clu); */
+                               if (exfat_fat_read(sb, clu, &clu) == -1) {
+                                       ret = -EIO;
+                                       goto out;
+                               }
 
                                clu_offset--;
                        }
@@ -772,13 +754,13 @@ static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer,
 
                if ((offset == 0) && (oneblkread == p_bd->sector_size)) {
                        if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-                           FFS_SUCCESS)
+                           0)
                                goto err_out;
                        memcpy((char *)buffer + read_bytes,
                               (char *)tmp_bh->b_data, (s32)oneblkread);
                } else {
                        if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-                           FFS_SUCCESS)
+                           0)
                                goto err_out;
                        memcpy((char *)buffer + read_bytes,
                               (char *)tmp_bh->b_data + offset,
@@ -797,11 +779,11 @@ err_out:
                *rcount = read_bytes;
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -814,7 +796,7 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
        s32 num_clusters, num_alloc, num_alloced = (s32)~0;
        int ret = 0;
        u32 clu, last_clu;
-       sector_t LogSector, sector = 0;
+       sector_t LogSector;
        u64 oneblkwrite, write_bytes;
        struct chain_t new_clu;
        struct timestamp_t tm;
@@ -827,18 +809,18 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
 
        /* check the validity of the given file id */
        if (!fid)
-               return FFS_INVALIDFID;
+               return -EINVAL;
 
        /* check the validity of pointer parameters */
        if (!buffer)
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check if the given file ID is opened */
        if (fid->type != TYPE_FILE) {
-               ret = FFS_PERMISSIONERR;
+               ret = -EPERM;
                goto out;
        }
 
@@ -848,7 +830,7 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
        if (count == 0) {
                if (wcount)
                        *wcount = 0;
-               ret = FFS_SUCCESS;
+               ret = 0;
                goto out;
        }
 
@@ -864,7 +846,8 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
 
        while (count > 0) {
                clu_offset = (s32)(fid->rwoffset >> p_fs->cluster_size_bits);
-               clu = last_clu = fid->start_clu;
+               clu = fid->start_clu;
+               last_clu = fid->start_clu;
 
                if (fid->flags == 0x03) {
                        if ((clu_offset > 0) && (clu != CLUSTER_32(~0))) {
@@ -885,9 +868,9 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
 
                        while ((clu_offset > 0) && (clu != CLUSTER_32(~0))) {
                                last_clu = clu;
-                               /* clu = FAT_read(sb, clu); */
-                               if (FAT_read(sb, clu, &clu) == -1) {
-                                       ret = FFS_MEDIAERR;
+                               /* clu = exfat_fat_read(sb, clu); */
+                               if (exfat_fat_read(sb, clu, &clu) == -1) {
+                                       ret = -EIO;
                                        goto out;
                                }
                                clu_offset--;
@@ -909,7 +892,7 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
                        if (num_alloced == 0)
                                break;
                        if (num_alloced < 0) {
-                               ret = FFS_MEDIAERR;
+                               ret = num_alloced;
                                goto out;
                        }
 
@@ -928,7 +911,7 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
                                        modified = true;
                                }
                                if (new_clu.flags == 0x01)
-                                       FAT_write(sb, last_clu, new_clu.dir);
+                                       exfat_fat_write(sb, last_clu, new_clu.dir);
                        }
 
                        num_clusters += num_alloced;
@@ -957,12 +940,12 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
 
                if ((offset == 0) && (oneblkwrite == p_bd->sector_size)) {
                        if (sector_read(sb, LogSector, &tmp_bh, 0) !=
-                           FFS_SUCCESS)
+                           0)
                                goto err_out;
                        memcpy((char *)tmp_bh->b_data,
                               (char *)buffer + write_bytes, (s32)oneblkwrite);
                        if (sector_write(sb, LogSector, tmp_bh, 0) !=
-                           FFS_SUCCESS) {
+                           0) {
                                brelse(tmp_bh);
                                goto err_out;
                        }
@@ -970,18 +953,18 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
                        if ((offset > 0) ||
                            ((fid->rwoffset + oneblkwrite) < fid->size)) {
                                if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-                                   FFS_SUCCESS)
+                                   0)
                                        goto err_out;
                        } else {
                                if (sector_read(sb, LogSector, &tmp_bh, 0) !=
-                                   FFS_SUCCESS)
+                                   0)
                                        goto err_out;
                        }
 
                        memcpy((char *)tmp_bh->b_data + offset,
                               (char *)buffer + write_bytes, (s32)oneblkwrite);
                        if (sector_write(sb, LogSector, tmp_bh, 0) !=
-                           FFS_SUCCESS) {
+                           0) {
                                brelse(tmp_bh);
                                goto err_out;
                        }
@@ -1002,25 +985,15 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
        brelse(tmp_bh);
 
        /* (3) update the direcoty entry */
-       if (p_fs->vol_type == EXFAT) {
-               es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-                                         ES_ALL_ENTRIES, &ep);
-               if (!es)
-                       goto err_out;
-               ep2 = ep + 1;
-       } else {
-               ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-               if (!ep)
-                       goto err_out;
-               ep2 = ep;
-       }
+       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                 ES_ALL_ENTRIES, &ep);
+       if (!es)
+               goto err_out;
+       ep2 = ep + 1;
 
        p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
        p_fs->fs_func->set_entry_attr(ep, fid->attr);
 
-       if (p_fs->vol_type != EXFAT)
-               buf_modify(sb, sector);
-
        if (modified) {
                if (p_fs->fs_func->get_entry_flag(ep2) != fid->flags)
                        p_fs->fs_func->set_entry_flag(ep2, fid->flags);
@@ -1030,18 +1003,13 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
 
                if (p_fs->fs_func->get_entry_clu0(ep2) != fid->start_clu)
                        p_fs->fs_func->set_entry_clu0(ep2, fid->start_clu);
-
-               if (p_fs->vol_type != EXFAT)
-                       buf_modify(sb, sector);
        }
 
-       if (p_fs->vol_type == EXFAT) {
-               update_dir_checksum_with_entry_set(sb, es);
-               release_entry_set(es);
-       }
+       update_dir_checksum_with_entry_set(sb, es);
+       release_entry_set(es);
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
@@ -1051,14 +1019,14 @@ err_out:
                *wcount = write_bytes;
 
        if (num_alloced == 0)
-               ret = FFS_FULL;
+               ret = -ENOSPC;
 
        else if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1068,7 +1036,6 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
        s32 num_clusters;
        u32 last_clu = CLUSTER_32(0);
        int ret = 0;
-       sector_t sector = 0;
        struct chain_t clu;
        struct timestamp_t tm;
        struct dentry_t *ep, *ep2;
@@ -1081,11 +1048,11 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
                 new_size);
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check if the given file ID is opened */
        if (fid->type != TYPE_FILE) {
-               ret = FFS_PERMISSIONERR;
+               ret = -EPERM;
                goto out;
        }
 
@@ -1095,7 +1062,7 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
        }
 
        if (old_size <= new_size) {
-               ret = FFS_SUCCESS;
+               ret = 0;
                goto out;
        }
 
@@ -1114,8 +1081,8 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
                } else {
                        while (num_clusters > 0) {
                                last_clu = clu.dir;
-                               if (FAT_read(sb, clu.dir, &clu.dir) == -1) {
-                                       ret = FFS_MEDIAERR;
+                               if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) {
+                                       ret = -EIO;
                                        goto out;
                                }
                                num_clusters--;
@@ -1133,22 +1100,13 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
        }
 
        /* (1) update the directory entry */
-       if (p_fs->vol_type == EXFAT) {
-               es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
-                                         ES_ALL_ENTRIES, &ep);
-               if (!es) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-                       }
-               ep2 = ep + 1;
-       } else {
-               ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-               if (!ep) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
+       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                 ES_ALL_ENTRIES, &ep);
+       if (!es) {
+               ret = -ENOENT;
+               goto out;
                }
-               ep2 = ep;
-       }
+       ep2 = ep + 1;
 
        p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
        p_fs->fs_func->set_entry_attr(ep, fid->attr);
@@ -1159,17 +1117,13 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
                p_fs->fs_func->set_entry_clu0(ep2, CLUSTER_32(0));
        }
 
-       if (p_fs->vol_type != EXFAT) {
-               buf_modify(sb, sector);
-       } else {
-               update_dir_checksum_with_entry_set(sb, es);
-               release_entry_set(es);
-       }
+       update_dir_checksum_with_entry_set(sb, es);
+       release_entry_set(es);
 
        /* (2) cut off from the FAT chain */
        if (last_clu != CLUSTER_32(0)) {
                if (fid->flags == 0x01)
-                       FAT_write(sb, last_clu, CLUSTER_32(~0));
+                       exfat_fat_write(sb, last_clu, CLUSTER_32(~0));
        }
 
        /* (3) free the clusters */
@@ -1180,18 +1134,18 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
        if (fid->rwoffset > fid->size)
                fid->rwoffset = fid->size;
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        pr_debug("%s exited (%d)\n", __func__, ret);
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1232,14 +1186,14 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
 
        /* check the validity of the given file id */
        if (!fid)
-               return FFS_INVALIDFID;
+               return -EINVAL;
 
        /* check the validity of pointer parameters */
        if (!new_path || (*new_path == '\0'))
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        update_parent_info(fid, old_parent_inode);
 
@@ -1252,19 +1206,19 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
        /* check if the old file is "." or ".." */
        if (p_fs->vol_type != EXFAT) {
                if ((olddir.dir != p_fs->root_dir) && (dentry < 2)) {
-                       ret = FFS_PERMISSIONERR;
+                       ret = -EPERM;
                        goto out2;
                }
        }
 
        ep = get_entry_in_dir(sb, &olddir, dentry, NULL);
        if (!ep) {
-               ret = FFS_MEDIAERR;
+               ret = -ENOENT;
                goto out2;
        }
 
        if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
-               ret = FFS_PERMISSIONERR;
+               ret = -EPERM;
                goto out2;
        }
 
@@ -1272,12 +1226,12 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
        if (new_inode) {
                u32 entry_type;
 
-               ret = FFS_MEDIAERR;
+               ret = -ENOENT;
                new_fid = &EXFAT_I(new_inode)->fid;
 
                update_parent_info(new_fid, new_parent_inode);
 
-               p_dir = &(new_fid->dir);
+               p_dir = &new_fid->dir;
                new_entry = new_fid->entry;
                ep = get_entry_in_dir(sb, p_dir, new_entry, NULL);
                if (!ep)
@@ -1294,7 +1248,7 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
                        new_clu.flags = new_fid->flags;
 
                        if (!is_dir_empty(sb, &new_clu)) {
-                               ret = FFS_FILEEXIST;
+                               ret = -EEXIST;
                                goto out;
                        }
                }
@@ -1308,13 +1262,13 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
        fs_set_vol_flags(sb, VOL_DIRTY);
 
        if (olddir.dir == newdir.dir)
-               ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name,
-                                 fid);
+               ret = exfat_rename_file(new_parent_inode, &olddir, dentry,
+                                       &uni_name, fid);
        else
                ret = move_file(new_parent_inode, &olddir, dentry, &newdir,
                                &uni_name, fid);
 
-       if ((ret == FFS_SUCCESS) && new_inode) {
+       if ((ret == 0) && new_inode) {
                /* delete entries of new_dir */
                ep = get_entry_in_dir(sb, p_dir, new_entry, NULL);
                if (!ep)
@@ -1328,16 +1282,16 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
                                                num_entries + 1);
        }
 out:
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 out2:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1345,7 +1299,7 @@ out2:
 static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
 {
        s32 dentry;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        struct chain_t dir, clu_to_free;
        struct dentry_t *ep;
        struct super_block *sb = inode->i_sb;
@@ -1353,10 +1307,10 @@ static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
 
        /* check the validity of the given file id */
        if (!fid)
-               return FFS_INVALIDFID;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        dir.dir = fid->dir.dir;
        dir.size = fid->dir.size;
@@ -1366,12 +1320,12 @@ static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
 
        ep = get_entry_in_dir(sb, &dir, dentry, NULL);
        if (!ep) {
-               ret = FFS_MEDIAERR;
+               ret = -ENOENT;
                goto out;
        }
 
        if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
-               ret = FFS_PERMISSIONERR;
+               ret = -EPERM;
                goto out;
        }
        fs_set_vol_flags(sb, VOL_DIRTY);
@@ -1390,16 +1344,16 @@ static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
        fid->start_clu = CLUSTER_32(~0);
        fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1409,7 +1363,7 @@ out:
 static int ffsSetAttr(struct inode *inode, u32 attr)
 {
        u32 type;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        sector_t sector = 0;
        struct dentry_t *ep;
        struct super_block *sb = inode->i_sb;
@@ -1420,36 +1374,28 @@ static int ffsSetAttr(struct inode *inode, u32 attr)
 
        if (fid->attr == attr) {
                if (p_fs->dev_ejected)
-                       return FFS_MEDIAERR;
-               return FFS_SUCCESS;
+                       return -EIO;
+               return 0;
        }
 
        if (is_dir) {
                if ((fid->dir.dir == p_fs->root_dir) &&
                    (fid->entry == -1)) {
                        if (p_fs->dev_ejected)
-                               return FFS_MEDIAERR;
-                       return FFS_SUCCESS;
+                               return -EIO;
+                       return 0;
                }
        }
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* get the directory entry of given file */
-       if (p_fs->vol_type == EXFAT) {
-               es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-                                         ES_ALL_ENTRIES, &ep);
-               if (!es) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
-       } else {
-               ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-               if (!ep) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
+       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                 ES_ALL_ENTRIES, &ep);
+       if (!es) {
+               ret = -ENOENT;
+               goto out;
        }
 
        type = p_fs->fs_func->get_entry_type(ep);
@@ -1457,12 +1403,11 @@ static int ffsSetAttr(struct inode *inode, u32 attr)
        if (((type == TYPE_FILE) && (attr & ATTR_SUBDIR)) ||
            ((type == TYPE_DIR) && (!(attr & ATTR_SUBDIR)))) {
                if (p_fs->dev_ejected)
-                       ret = FFS_MEDIAERR;
+                       ret = -EIO;
                else
-                       ret = FFS_ERROR;
+                       ret = -EINVAL;
 
-               if (p_fs->vol_type == EXFAT)
-                       release_entry_set(es);
+               release_entry_set(es);
                goto out;
        }
 
@@ -1472,23 +1417,19 @@ static int ffsSetAttr(struct inode *inode, u32 attr)
        fid->attr = attr;
        p_fs->fs_func->set_entry_attr(ep, attr);
 
-       if (p_fs->vol_type != EXFAT) {
-               buf_modify(sb, sector);
-       } else {
-               update_dir_checksum_with_entry_set(sb, es);
-               release_entry_set(es);
-       }
+       update_dir_checksum_with_entry_set(sb, es);
+       release_entry_set(es);
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1496,9 +1437,8 @@ out:
 
 static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
 {
-       sector_t sector = 0;
        s32 count;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        struct chain_t dir;
        struct uni_name_t uni_name;
        struct timestamp_t tm;
@@ -1512,7 +1452,7 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
        pr_debug("%s entered\n", __func__);
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        if (is_dir) {
                if ((fid->dir.dir == p_fs->root_dir) &&
@@ -1541,35 +1481,25 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
 
                        count = count_dos_name_entries(sb, &dir, TYPE_DIR);
                        if (count < 0) {
-                               ret = FFS_MEDIAERR;
+                               ret = count; /* propogate error upward */
                                goto out;
                        }
                        info->NumSubdirs = count;
 
                        if (p_fs->dev_ejected)
-                               ret = FFS_MEDIAERR;
+                               ret = -EIO;
                        goto out;
                }
        }
 
        /* get the directory entry of given file or directory */
-       if (p_fs->vol_type == EXFAT) {
-               es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-                                         ES_2_ENTRIES, &ep);
-               if (!es) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
-               ep2 = ep + 1;
-       } else {
-               ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-               if (!ep) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
-               ep2 = ep;
-               buf_lock(sb, sector);
+       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                 ES_2_ENTRIES, &ep);
+       if (!es) {
+               ret = -ENOENT;
+               goto out;
        }
+       ep2 = ep + 1;
 
        /* set FILE_INFO structure using the acquired struct dentry_t */
        info->Attr = p_fs->fs_func->get_entry_attr(ep);
@@ -1594,31 +1524,19 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
 
        memset((char *)&info->AccessTimestamp, 0, sizeof(struct date_time_t));
 
-       *(uni_name.name) = 0x0;
+       *uni_name.name = 0x0;
        /* XXX this is very bad for exfat cuz name is already included in es.
         * API should be revised
         */
-       p_fs->fs_func->get_uni_name_from_ext_entry(sb, &(fid->dir), fid->entry,
+       p_fs->fs_func->get_uni_name_from_ext_entry(sb, &fid->dir, fid->entry,
                                                   uni_name.name);
-       if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT)
-               get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep,
-                                           &uni_name, 0x1);
        nls_uniname_to_cstring(sb, info->Name, &uni_name);
 
-       if (p_fs->vol_type == EXFAT) {
-               info->NumSubdirs = 2;
-       } else {
-               buf_unlock(sb, sector);
-               get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep,
-                                           &uni_name, 0x0);
-               nls_uniname_to_cstring(sb, info->ShortName, &uni_name);
-               info->NumSubdirs = 0;
-       }
+       info->NumSubdirs = 2;
 
        info->Size = p_fs->fs_func->get_entry_size(ep2);
 
-       if (p_fs->vol_type == EXFAT)
-               release_entry_set(es);
+       release_entry_set(es);
 
        if (is_dir) {
                dir.dir = fid->start_clu;
@@ -1630,18 +1548,18 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
 
                count = count_dos_name_entries(sb, &dir, TYPE_DIR);
                if (count < 0) {
-                       ret = FFS_MEDIAERR;
+                       ret = count; /* propogate error upward */
                        goto out;
                }
                info->NumSubdirs += count;
        }
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        pr_debug("%s exited successfully\n", __func__);
        return ret;
@@ -1649,8 +1567,7 @@ out:
 
 static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
 {
-       sector_t sector = 0;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        struct timestamp_t tm;
        struct dentry_t *ep, *ep2;
        struct entry_set_cache_t *es = NULL;
@@ -1662,14 +1579,14 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
        pr_debug("%s entered (inode %p info %p\n", __func__, inode, info);
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        if (is_dir) {
                if ((fid->dir.dir == p_fs->root_dir) &&
                    (fid->entry == -1)) {
                        if (p_fs->dev_ejected)
-                               ret = FFS_MEDIAERR;
-                       ret = FFS_SUCCESS;
+                               ret = -EIO;
+                       ret = 0;
                        goto out;
                }
        }
@@ -1677,23 +1594,13 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
        fs_set_vol_flags(sb, VOL_DIRTY);
 
        /* get the directory entry of given file or directory */
-       if (p_fs->vol_type == EXFAT) {
-               es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-                                         ES_ALL_ENTRIES, &ep);
-               if (!es) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
-               ep2 = ep + 1;
-       } else {
-               /* for other than exfat */
-               ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-               if (!ep) {
-                       ret = FFS_MEDIAERR;
-                       goto out;
-               }
-               ep2 = ep;
+       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                 ES_ALL_ENTRIES, &ep);
+       if (!es) {
+               ret = -ENOENT;
+               goto out;
        }
+       ep2 = ep + 1;
 
        p_fs->fs_func->set_entry_attr(ep, info->Attr);
 
@@ -1716,19 +1623,15 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
 
        p_fs->fs_func->set_entry_size(ep2, info->Size);
 
-       if (p_fs->vol_type != EXFAT) {
-               buf_modify(sb, sector);
-       } else {
-               update_dir_checksum_with_entry_set(sb, es);
-               release_entry_set(es);
-       }
+       update_dir_checksum_with_entry_set(sb, es);
+       release_entry_set(es);
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        pr_debug("%s exited (%d)\n", __func__, ret);
 
@@ -1740,8 +1643,7 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
        s32 num_clusters, num_alloced;
        bool modified = false;
        u32 last_clu;
-       int ret = FFS_SUCCESS;
-       sector_t sector = 0;
+       int ret = 0;
        struct chain_t new_clu;
        struct dentry_t *ep;
        struct entry_set_cache_t *es = NULL;
@@ -1751,10 +1653,10 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
 
        /* check the validity of pointer parameters */
        if (!clu)
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        fid->rwoffset = (s64)(clu_offset) << p_fs->cluster_size_bits;
 
@@ -1785,8 +1687,8 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
 
                while ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) {
                        last_clu = *clu;
-                       if (FAT_read(sb, *clu, clu) == -1) {
-                               ret = FFS_MEDIAERR;
+                       if (exfat_fat_read(sb, *clu, clu) == -1) {
+                               ret = -EIO;
                                goto out;
                        }
                        clu_offset--;
@@ -1804,10 +1706,10 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
                /* (1) allocate a cluster */
                num_alloced = p_fs->fs_func->alloc_cluster(sb, 1, &new_clu);
                if (num_alloced < 0) {
-                       ret = FFS_MEDIAERR;
+                       ret = -EIO;
                        goto out;
                } else if (num_alloced == 0) {
-                       ret = FFS_FULL;
+                       ret = -ENOSPC;
                        goto out;
                }
 
@@ -1825,34 +1727,23 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
                                modified = true;
                        }
                        if (new_clu.flags == 0x01)
-                               FAT_write(sb, last_clu, new_clu.dir);
+                               exfat_fat_write(sb, last_clu, new_clu.dir);
                }
 
                num_clusters += num_alloced;
                *clu = new_clu.dir;
 
-               if (p_fs->vol_type == EXFAT) {
-                       es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
-                                                 ES_ALL_ENTRIES, &ep);
-                       if (!es) {
-                               ret = FFS_MEDIAERR;
-                               goto out;
-                       }
-                       /* get stream entry */
-                       ep++;
+               es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
+                                         ES_ALL_ENTRIES, &ep);
+               if (!es) {
+                       ret = -ENOENT;
+                       goto out;
                }
+               /* get stream entry */
+               ep++;
 
                /* (3) update directory entry */
                if (modified) {
-                       if (p_fs->vol_type != EXFAT) {
-                               ep = get_entry_in_dir(sb, &(fid->dir),
-                                                     fid->entry, &sector);
-                               if (!ep) {
-                                       ret = FFS_MEDIAERR;
-                                       goto out;
-                               }
-                       }
-
                        if (p_fs->fs_func->get_entry_flag(ep) != fid->flags)
                                p_fs->fs_func->set_entry_flag(ep, fid->flags);
 
@@ -1860,14 +1751,10 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
                                p_fs->fs_func->set_entry_clu0(ep,
                                                              fid->start_clu);
 
-                       if (p_fs->vol_type != EXFAT)
-                               buf_modify(sb, sector);
                }
 
-               if (p_fs->vol_type == EXFAT) {
-                       update_dir_checksum_with_entry_set(sb, es);
-                       release_entry_set(es);
-               }
+               update_dir_checksum_with_entry_set(sb, es);
+               release_entry_set(es);
 
                /* add number of new blocks to inode */
                inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9);
@@ -1878,11 +1765,11 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
        fid->hint_last_clu = *clu;
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1893,7 +1780,7 @@ out:
 
 static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid)
 {
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        struct chain_t dir;
        struct uni_name_t uni_name;
        struct super_block *sb = inode->i_sb;
@@ -1903,10 +1790,10 @@ static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid)
 
        /* check the validity of pointer parameters */
        if (!fid || !path || (*path == '\0'))
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        /* check the validity of directory name in the given old pathname */
        ret = resolve_path(inode, path, &dir, &uni_name);
@@ -1917,16 +1804,16 @@ static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid)
 
        ret = create_dir(inode, &dir, &uni_name, fid);
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -1934,7 +1821,7 @@ out:
 static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
 {
        int i, dentry, clu_offset;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        s32 dentries_per_clu, dentries_per_clu_bits = 0;
        u32 type;
        sector_t sector;
@@ -1949,14 +1836,14 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
 
        /* check the validity of pointer parameters */
        if (!dir_entry)
-               return FFS_ERROR;
+               return -EINVAL;
 
        /* check if the given file ID is opened */
        if (fid->type != TYPE_DIR)
-               return FFS_PERMISSIONERR;
+               return -ENOTDIR;
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        if (fid->entry == -1) {
                dir.dir = p_fs->root_dir;
@@ -2001,9 +1888,9 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        }
 
                        while (clu_offset > 0) {
-                               /* clu.dir = FAT_read(sb, clu.dir); */
-                               if (FAT_read(sb, clu.dir, &clu.dir) == -1) {
-                                       ret = FFS_MEDIAERR;
+                               /* clu.dir = exfat_fat_read(sb, clu.dir); */
+                               if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) {
+                                       ret = -EIO;
                                        goto out;
                                }
                                clu_offset--;
@@ -2023,7 +1910,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                for ( ; i < dentries_per_clu; i++, dentry++) {
                        ep = get_entry_in_dir(sb, &clu, i, &sector);
                        if (!ep) {
-                               ret = FFS_MEDIAERR;
+                               ret = -ENOENT;
                                goto out;
                        }
                        type = fs_func->get_entry_type(ep);
@@ -2034,7 +1921,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        if ((type != TYPE_FILE) && (type != TYPE_DIR))
                                continue;
 
-                       buf_lock(sb, sector);
+                       exfat_buf_lock(sb, sector);
                        dir_entry->Attr = fs_func->get_entry_attr(ep);
 
                        fs_func->get_entry_time(ep, &tm, TM_CREATE);
@@ -2058,28 +1945,16 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        memset((char *)&dir_entry->AccessTimestamp, 0,
                               sizeof(struct date_time_t));
 
-                       *(uni_name.name) = 0x0;
+                       *uni_name.name = 0x0;
                        fs_func->get_uni_name_from_ext_entry(sb, &dir, dentry,
                                                             uni_name.name);
-                       if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT)
-                               get_uni_name_from_dos_entry(sb,
-                                               (struct dos_dentry_t *)ep,
-                                               &uni_name, 0x1);
                        nls_uniname_to_cstring(sb, dir_entry->Name, &uni_name);
-                       buf_unlock(sb, sector);
+                       exfat_buf_unlock(sb, sector);
 
-                       if (p_fs->vol_type == EXFAT) {
-                               ep = get_entry_in_dir(sb, &clu, i + 1, NULL);
-                               if (!ep) {
-                                       ret = FFS_MEDIAERR;
-                                       goto out;
-                               }
-                       } else {
-                               get_uni_name_from_dos_entry(sb,
-                                               (struct dos_dentry_t *)ep,
-                                               &uni_name, 0x0);
-                               nls_uniname_to_cstring(sb, dir_entry->ShortName,
-                                                      &uni_name);
+                       ep = get_entry_in_dir(sb, &clu, i + 1, NULL);
+                       if (!ep) {
+                               ret = -ENOENT;
+                               goto out;
                        }
 
                        dir_entry->Size = fs_func->get_entry_size(ep);
@@ -2095,7 +1970,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        fid->rwoffset = (s64)(++dentry);
 
                        if (p_fs->dev_ejected)
-                               ret = FFS_MEDIAERR;
+                               ret = -EIO;
                        goto out;
                }
 
@@ -2108,24 +1983,24 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        else
                                clu.dir = CLUSTER_32(~0);
                } else {
-                       /* clu.dir = FAT_read(sb, clu.dir); */
-                       if (FAT_read(sb, clu.dir, &clu.dir) == -1) {
-                               ret = FFS_MEDIAERR;
+                       /* clu.dir = exfat_fat_read(sb, clu.dir); */
+                       if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) {
+                               ret = -EIO;
                                goto out;
                        }
                }
        }
 
-       *(dir_entry->Name) = '\0';
+       *dir_entry->Name = '\0';
 
        fid->rwoffset = (s64)(++dentry);
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -2133,14 +2008,14 @@ out:
 static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid)
 {
        s32 dentry;
-       int ret = FFS_SUCCESS;
+       int ret = 0;
        struct chain_t dir, clu_to_free;
        struct super_block *sb = inode->i_sb;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        /* check the validity of the given file id */
        if (!fid)
-               return FFS_INVALIDFID;
+               return -EINVAL;
 
        dir.dir = fid->dir.dir;
        dir.size = fid->dir.size;
@@ -2151,18 +2026,18 @@ static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid)
        /* check if the file is "." or ".." */
        if (p_fs->vol_type != EXFAT) {
                if ((dir.dir != p_fs->root_dir) && (dentry < 2))
-                       return FFS_PERMISSIONERR;
+                       return -EPERM;
        }
 
        /* acquire the lock for file system critical section */
-       down(&p_fs->v_sem);
+       mutex_lock(&p_fs->v_mutex);
 
        clu_to_free.dir = fid->start_clu;
        clu_to_free.size = (s32)((fid->size - 1) >> p_fs->cluster_size_bits) + 1;
        clu_to_free.flags = fid->flags;
 
        if (!is_dir_empty(sb, &clu_to_free)) {
-               ret = FFS_FILEEXIST;
+               ret = -ENOTEMPTY;
                goto out;
        }
 
@@ -2178,17 +2053,17 @@ static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid)
        fid->start_clu = CLUSTER_32(~0);
        fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
 
-#ifdef CONFIG_EXFAT_DELAYED_SYNC
-       fs_sync(sb, false);
+#ifndef CONFIG_EXFAT_DELAYED_SYNC
+       fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
 
        if (p_fs->dev_ejected)
-               ret = FFS_MEDIAERR;
+               ret = -EIO;
 
 out:
        /* release the lock for file system critical section */
-       up(&p_fs->v_sem);
+       mutex_unlock(&p_fs->v_mutex);
 
        return ret;
 }
@@ -2202,7 +2077,7 @@ static int exfat_readdir(struct file *filp, struct dir_context *ctx)
        struct inode *inode = file_inode(filp);
        struct super_block *sb = inode->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
        struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
        struct dir_entry_t de;
        unsigned long inum;
@@ -2244,12 +2119,11 @@ get_new:
                /* at least we tried to read a sector
                 * move cpos to next sector position (should be aligned)
                 */
-               if (err == FFS_MEDIAERR) {
+               if (err == -EIO) {
                        cpos += 1 << p_bd->sector_size_bits;
                        cpos &= ~((1 << p_bd->sector_size_bits) - 1);
                }
 
-               err = -EIO;
                goto end_of_dir;
        }
 
@@ -2293,7 +2167,7 @@ static int exfat_ioctl_volume_id(struct inode *dir)
 {
        struct super_block *sb = dir->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
 
        return p_fs->vol_id;
 }
@@ -2301,7 +2175,7 @@ static int exfat_ioctl_volume_id(struct inode *dir)
 static long exfat_generic_ioctl(struct file *filp, unsigned int cmd,
                                unsigned long arg)
 {
-struct inode *inode = filp->f_path.dentry->d_inode;
+       struct inode *inode = filp->f_path.dentry->d_inode;
 #ifdef CONFIG_EXFAT_KERNEL_DEBUG
        unsigned int flags;
 #endif /* CONFIG_EXFAT_KERNEL_DEBUG */
@@ -2351,6 +2225,7 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
                        bool excl)
 {
        struct super_block *sb = dir->i_sb;
+       struct timespec64 curtime;
        struct inode *inode;
        struct file_id_t fid;
        loff_t i_pos;
@@ -2361,21 +2236,14 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        pr_debug("%s entered\n", __func__);
 
        err = ffsCreateFile(dir, (u8 *)dentry->d_name.name, FM_REGULAR, &fid);
-       if (err) {
-               if (err == FFS_INVALIDPATH)
-                       err = -EINVAL;
-               else if (err == FFS_FILEEXIST)
-                       err = -EEXIST;
-               else if (err == FFS_FULL)
-                       err = -ENOSPC;
-               else if (err == FFS_NAMETOOLONG)
-                       err = -ENAMETOOLONG;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
        INC_IVERSION(dir);
-       dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
+       curtime = current_time(dir);
+       dir->i_ctime = curtime;
+       dir->i_mtime = curtime;
+       dir->i_atime = curtime;
        if (IS_DIRSYNC(dir))
                (void)exfat_sync_inode(dir);
        else
@@ -2389,7 +2257,10 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
                goto out;
        }
        INC_IVERSION(inode);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
+       inode->i_ctime = curtime;
        /*
         * timestamp is already written, so mark_inode_dirty() is unnecessary.
         */
@@ -2522,6 +2393,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
 {
        struct inode *inode = dentry->d_inode;
        struct super_block *sb = dir->i_sb;
+       struct timespec64 curtime;
        int err;
 
        __lock_super(sb);
@@ -2531,22 +2403,22 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
        EXFAT_I(inode)->fid.size = i_size_read(inode);
 
        err = ffsRemoveFile(dir, &(EXFAT_I(inode)->fid));
-       if (err) {
-               if (err == FFS_PERMISSIONERR)
-                       err = -EPERM;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
        INC_IVERSION(dir);
-       dir->i_mtime = dir->i_atime = current_time(dir);
+       curtime = current_time(dir);
+       dir->i_mtime = curtime;
+       dir->i_atime = curtime;
        if (IS_DIRSYNC(dir))
                (void)exfat_sync_inode(dir);
        else
                mark_inode_dirty(dir);
 
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
        exfat_detach(inode);
        remove_inode_hash(inode);
 
@@ -2560,6 +2432,7 @@ static int exfat_symlink(struct inode *dir, struct dentry *dentry,
                         const char *target)
 {
        struct super_block *sb = dir->i_sb;
+       struct timespec64 curtime;
        struct inode *inode;
        struct file_id_t fid;
        loff_t i_pos;
@@ -2572,32 +2445,22 @@ static int exfat_symlink(struct inode *dir, struct dentry *dentry,
        pr_debug("%s entered\n", __func__);
 
        err = ffsCreateFile(dir, (u8 *)dentry->d_name.name, FM_SYMLINK, &fid);
-       if (err) {
-               if (err == FFS_INVALIDPATH)
-                       err = -EINVAL;
-               else if (err == FFS_FILEEXIST)
-                       err = -EEXIST;
-               else if (err == FFS_FULL)
-                       err = -ENOSPC;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
 
        err = ffsWriteFile(dir, &fid, (char *)target, len, &ret);
 
        if (err) {
                ffsRemoveFile(dir, &fid);
-
-               if (err == FFS_FULL)
-                       err = -ENOSPC;
-               else
-                       err = -EIO;
                goto out;
        }
 
        INC_IVERSION(dir);
-       dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
+       curtime = current_time(dir);
+       dir->i_ctime = curtime;
+       dir->i_mtime = curtime;
+       dir->i_atime = curtime;
        if (IS_DIRSYNC(dir))
                (void)exfat_sync_inode(dir);
        else
@@ -2611,7 +2474,10 @@ static int exfat_symlink(struct inode *dir, struct dentry *dentry,
                goto out;
        }
        INC_IVERSION(inode);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
+       inode->i_ctime = curtime;
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        EXFAT_I(inode)->target = kmemdup(target, len + 1, GFP_KERNEL);
@@ -2632,6 +2498,7 @@ out:
 static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
        struct super_block *sb = dir->i_sb;
+       struct timespec64 curtime;
        struct inode *inode;
        struct file_id_t fid;
        loff_t i_pos;
@@ -2642,21 +2509,14 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        pr_debug("%s entered\n", __func__);
 
        err = ffsCreateDir(dir, (u8 *)dentry->d_name.name, &fid);
-       if (err) {
-               if (err == FFS_INVALIDPATH)
-                       err = -EINVAL;
-               else if (err == FFS_FILEEXIST)
-                       err = -EEXIST;
-               else if (err == FFS_FULL)
-                       err = -ENOSPC;
-               else if (err == FFS_NAMETOOLONG)
-                       err = -ENAMETOOLONG;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
        INC_IVERSION(dir);
-       dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
+       curtime = current_time(dir);
+       dir->i_ctime = curtime;
+       dir->i_mtime = curtime;
+       dir->i_atime = curtime;
        if (IS_DIRSYNC(dir))
                (void)exfat_sync_inode(dir);
        else
@@ -2671,7 +2531,10 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
                goto out;
        }
        INC_IVERSION(inode);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
+       inode->i_ctime = curtime;
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
@@ -2687,6 +2550,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 {
        struct inode *inode = dentry->d_inode;
        struct super_block *sb = dir->i_sb;
+       struct timespec64 curtime;
        int err;
 
        __lock_super(sb);
@@ -2696,21 +2560,13 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
        EXFAT_I(inode)->fid.size = i_size_read(inode);
 
        err = ffsRemoveDir(dir, &(EXFAT_I(inode)->fid));
-       if (err) {
-               if (err == FFS_INVALIDPATH)
-                       err = -EINVAL;
-               else if (err == FFS_FILEEXIST)
-                       err = -ENOTEMPTY;
-               else if (err == FFS_NOTFOUND)
-                       err = -ENOENT;
-               else if (err == FFS_DIRBUSY)
-                       err = -EBUSY;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
        INC_IVERSION(dir);
-       dir->i_mtime = dir->i_atime = current_time(dir);
+       curtime = current_time(dir);
+       dir->i_mtime = curtime;
+       dir->i_atime = curtime;
        if (IS_DIRSYNC(dir))
                (void)exfat_sync_inode(dir);
        else
@@ -2718,7 +2574,9 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
        drop_nlink(dir);
 
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
        exfat_detach(inode);
        remove_inode_hash(inode);
 
@@ -2734,6 +2592,7 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 {
        struct inode *old_inode, *new_inode;
        struct super_block *sb = old_dir->i_sb;
+       struct timespec64 curtime;
        loff_t i_pos;
        int err;
 
@@ -2751,24 +2610,15 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        err = ffsMoveFile(old_dir, &(EXFAT_I(old_inode)->fid), new_dir,
                          new_dentry);
-       if (err) {
-               if (err == FFS_PERMISSIONERR)
-                       err = -EPERM;
-               else if (err == FFS_INVALIDPATH)
-                       err = -EINVAL;
-               else if (err == FFS_FILEEXIST)
-                       err = -EEXIST;
-               else if (err == FFS_NOTFOUND)
-                       err = -ENOENT;
-               else if (err == FFS_FULL)
-                       err = -ENOSPC;
-               else
-                       err = -EIO;
+       if (err)
                goto out;
-       }
+
        INC_IVERSION(new_dir);
-       new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
-                               current_time(new_dir);
+       curtime = current_time(new_dir);
+       new_dir->i_ctime = curtime;
+       new_dir->i_mtime = curtime;
+       new_dir->i_atime = curtime;
+
        if (IS_DIRSYNC(new_dir))
                (void)exfat_sync_inode(new_dir);
        else
@@ -2790,7 +2640,9 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                        inc_nlink(new_dir);
        }
        INC_IVERSION(old_dir);
-       old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
+       curtime = current_time(old_dir);
+       old_dir->i_ctime = curtime;
+       old_dir->i_mtime = curtime;
        if (IS_DIRSYNC(old_dir))
                (void)exfat_sync_inode(old_dir);
        else
@@ -2814,13 +2666,16 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
 {
        struct address_space *mapping = inode->i_mapping;
        loff_t start = i_size_read(inode), count = size - i_size_read(inode);
+       struct timespec64 curtime;
        int err, err2;
 
        err = generic_cont_expand_simple(inode, size);
        if (err != 0)
                return err;
 
-       inode->i_ctime = inode->i_mtime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_ctime = curtime;
+       inode->i_mtime = curtime;
        mark_inode_dirty(inode);
 
        if (IS_SYNC(inode)) {
@@ -2895,7 +2750,8 @@ static void exfat_truncate(struct inode *inode, loff_t old_size)
 {
        struct super_block *sb = inode->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
+       struct timespec64 curtime;
        int err;
 
        __lock_super(sb);
@@ -2914,7 +2770,9 @@ static void exfat_truncate(struct inode *inode, loff_t old_size)
        if (err)
                goto out;
 
-       inode->i_ctime = inode->i_mtime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_ctime = curtime;
+       inode->i_mtime = curtime;
        if (IS_DIRSYNC(inode))
                (void)exfat_sync_inode(inode);
        else
@@ -2936,8 +2794,8 @@ static int exfat_setattr(struct dentry *dentry, struct iattr *attr)
 
        pr_debug("%s entered\n", __func__);
 
-       if ((attr->ia_valid & ATTR_SIZE)
-               && (attr->ia_size > i_size_read(inode))) {
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size > i_size_read(inode)) {
                error = exfat_cont_expand(inode, attr->ia_size);
                if (error || attr->ia_valid == ATTR_SIZE)
                        return error;
@@ -2946,8 +2804,8 @@ static int exfat_setattr(struct dentry *dentry, struct iattr *attr)
 
        ia_valid = attr->ia_valid;
 
-       if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET))
-               && exfat_allow_set_time(sbi, inode)) {
+       if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) &&
+           exfat_allow_set_time(sbi, inode)) {
                attr->ia_valid &= ~(ATTR_MTIME_SET |
                                    ATTR_ATIME_SET |
                                    ATTR_TIMES_SET);
@@ -3073,8 +2931,7 @@ static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
 {
        struct super_block *sb = inode->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
-       struct bd_info_t *p_bd = &(sbi->bd_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
        const unsigned long blocksize = sb->s_blocksize;
        const unsigned char blocksize_bits = sb->s_blocksize_bits;
        sector_t last_block;
@@ -3084,18 +2941,6 @@ static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
        *phys = 0;
        *mapped_blocks = 0;
 
-       if ((p_fs->vol_type == FAT12) || (p_fs->vol_type == FAT16)) {
-               if (inode->i_ino == EXFAT_ROOT_INO) {
-                       if (sector <
-                           (p_fs->dentries_in_root >>
-                            (p_bd->sector_size_bits - DENTRY_SIZE_BITS))) {
-                               *phys = sector + p_fs->root_start_sector;
-                               *mapped_blocks = 1;
-                       }
-                       return 0;
-               }
-       }
-
        last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
        if (sector >= last_block) {
                if (*create == 0)
@@ -3114,12 +2959,7 @@ static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
 
        err = ffsMapCluster(inode, clu_offset, &cluster);
 
-       if (err) {
-               if (err == FFS_FULL)
-                       return -ENOSPC;
-               else
-                       return -EIO;
-       } else if (cluster != CLUSTER_32(~0)) {
+       if (!err && (cluster != CLUSTER_32(~0))) {
                *phys = START_SECTOR(cluster) + sec_offset;
                *mapped_blocks = p_fs->sectors_per_clu - sec_offset;
        }
@@ -3215,6 +3055,7 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,
 {
        struct inode *inode = mapping->host;
        struct file_id_t *fid = &(EXFAT_I(inode)->fid);
+       struct timespec64 curtime;
        int err;
 
        err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
@@ -3223,7 +3064,9 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,
                exfat_write_failed(mapping, pos + len);
 
        if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) {
-               inode->i_mtime = inode->i_ctime = current_time(inode);
+               curtime = current_time(inode);
+               inode->i_mtime = curtime;
+               inode->i_ctime = curtime;
                fid->attr |= ATTR_ARCHIVE;
                mark_inode_dirty(inode);
        }
@@ -3302,7 +3145,7 @@ static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos)
 static int exfat_fill_inode(struct inode *inode, struct file_id_t *fid)
 {
        struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
        struct dir_entry_t info;
 
        memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(struct file_id_t));
@@ -3314,7 +3157,7 @@ static int exfat_fill_inode(struct inode *inode, struct file_id_t *fid)
        inode->i_uid = sbi->options.fs_uid;
        inode->i_gid = sbi->options.fs_gid;
        INC_IVERSION(inode);
-       inode->i_generation = get_seconds();
+       inode->i_generation = prandom_u32();
 
        if (info.Attr & ATTR_SUBDIR) { /* directory */
                inode->i_generation &= ~1;
@@ -3501,7 +3344,7 @@ static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct vol_info_t info;
 
        if (p_fs->used_clusters == UINT_MAX) {
-               if (ffsGetVolInfo(sb, &info) == FFS_MEDIAERR)
+               if (ffsGetVolInfo(sb, &info) == -EIO)
                        return -EIO;
 
        } else {
@@ -3674,7 +3517,8 @@ static int parse_options(char *options, int silent, int *debug,
 
        opts->fs_uid = current_uid();
        opts->fs_gid = current_gid();
-       opts->fs_fmask = opts->fs_dmask = current->fs->umask;
+       opts->fs_fmask = current->fs->umask;
+       opts->fs_dmask = current->fs->umask;
        opts->allow_utime = U16_MAX;
        opts->codepage = exfat_default_codepage;
        opts->iocharset = exfat_default_iocharset;
@@ -3787,7 +3631,8 @@ static int exfat_read_root(struct inode *inode)
 {
        struct super_block *sb = inode->i_sb;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct fs_info_t *p_fs = &(sbi->fs_info);
+       struct fs_info_t *p_fs = &sbi->fs_info;
+       struct timespec64 curtime;
        struct dir_entry_t info;
 
        EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir;
@@ -3818,7 +3663,10 @@ static int exfat_read_root(struct inode *inode)
        EXFAT_I(inode)->mmu_private = i_size_read(inode);
 
        exfat_save_attr(inode, ATTR_SUBDIR);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+       curtime = current_time(inode);
+       inode->i_mtime = curtime;
+       inode->i_atime = curtime;
+       inode->i_ctime = curtime;
        set_nlink(inode, info.NumSubdirs + 2);
 
        return 0;
@@ -3838,7 +3686,6 @@ static int exfat_fill_super(struct super_block *sb, void *data, int silent)
        struct exfat_sb_info *sbi;
        int debug, ret;
        long error;
-       char buf[50];
 
        /*
         * GFP_KERNEL is ok here, because while we do hold the
@@ -3885,17 +3732,6 @@ static int exfat_fill_super(struct super_block *sb, void *data, int silent)
         * if (FAT_FIRST_ENT(sb, media) != first)
         */
 
-       /* codepage is not meaningful in exfat */
-       if (sbi->fs_info.vol_type != EXFAT) {
-               error = -EINVAL;
-               sprintf(buf, "cp%d", sbi->options.codepage);
-               sbi->nls_disk = load_nls(buf);
-               if (!sbi->nls_disk) {
-                       pr_err("[EXFAT] Codepage %s not found\n", buf);
-                       goto out_fail2;
-               }
-       }
-
        sbi->nls_io = load_nls(sbi->options.iocharset);
 
        error = -ENOMEM;
@@ -3984,10 +3820,10 @@ static void exfat_debug_kill_sb(struct super_block *sb)
                         * invalidate_bdev drops all device cache include
                         * dirty. We use this to simulate device removal.
                         */
-                       down(&p_fs->v_sem);
-                       FAT_release_all(sb);
-                       buf_release_all(sb);
-                       up(&p_fs->v_sem);
+                       mutex_lock(&p_fs->v_mutex);
+                       exfat_fat_release_all(sb);
+                       exfat_buf_release_all(sb);
+                       mutex_unlock(&p_fs->v_mutex);
 
                        invalidate_bdev(bdev);
                }