diff options
-rw-r--r-- | fs/exfat/dir.c | 29 | ||||
-rw-r--r-- | fs/exfat/exfat_fs.h | 4 | ||||
-rw-r--r-- | fs/exfat/file.c | 4 | ||||
-rw-r--r-- | fs/exfat/inode.c | 5 | ||||
-rw-r--r-- | fs/exfat/namei.c | 153 | ||||
-rw-r--r-- | fs/exfat/nls.c | 2 | ||||
-rw-r--r-- | fs/exfat/super.c | 1 |
7 files changed, 71 insertions, 127 deletions
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 573659bfbc55..916797077aad 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -59,9 +59,9 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, } /* read a directory entry from the opened directory */ -static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) +static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) { - int i, dentries_per_clu, dentries_per_clu_bits = 0; + int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext; unsigned int type, clu_offset; sector_t sector; struct exfat_chain dir, clu; @@ -70,7 +70,7 @@ static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_inode_info *ei = EXFAT_I(inode); - unsigned int dentry = ei->rwoffset & 0xFFFFFFFF; + unsigned int dentry = EXFAT_B_TO_DEN(*cpos) & 0xFFFFFFFF; struct buffer_head *bh; /* check if the given file ID is opened */ @@ -127,6 +127,7 @@ static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) continue; } + num_ext = ep->dentry.file.num_ext; dir_entry->attr = le16_to_cpu(ep->dentry.file.attr); exfat_get_entry_time(sbi, &dir_entry->crtime, ep->dentry.file.create_tz, @@ -157,12 +158,13 @@ static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) return -EIO; dir_entry->size = le64_to_cpu(ep->dentry.stream.valid_size); + dir_entry->entry = dentry; brelse(bh); ei->hint_bmap.off = dentry >> dentries_per_clu_bits; ei->hint_bmap.clu = clu.dir; - ei->rwoffset = ++dentry; + *cpos = EXFAT_DEN_TO_B(dentry + 1 + num_ext); return 0; } @@ -178,7 +180,7 @@ static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) } dir_entry->namebuf.lfn[0] = '\0'; - ei->rwoffset = dentry; + *cpos = EXFAT_DEN_TO_B(dentry); return 0; } @@ -242,12 +244,10 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx) if (err) goto unlock; get_new: - ei->rwoffset = EXFAT_B_TO_DEN(cpos); - if (cpos >= i_size_read(inode)) goto end_of_dir; - err = exfat_readdir(inode, &de); + err = exfat_readdir(inode, &cpos, &de); if (err) { /* * At least we tried to read a sector. Move cpos to next sector @@ -262,13 +262,10 @@ get_new: goto end_of_dir; } - cpos = EXFAT_DEN_TO_B(ei->rwoffset); - if (!nb->lfn[0]) goto end_of_dir; - i_pos = ((loff_t)ei->start_clu << 32) | - ((ei->rwoffset - 1) & 0xffffffff); + i_pos = ((loff_t)ei->start_clu << 32) | (de.entry & 0xffffffff); tmp = exfat_iget(sb, i_pos); if (tmp) { inum = tmp->i_ino; @@ -911,7 +908,6 @@ enum { /* * return values: * >= 0 : return dir entiry position with the name in dir - * -EEXIST : (root dir, ".") it is the root dir itself * -ENOENT : entry with the name does not exist * -EIO : I/O error */ @@ -979,11 +975,8 @@ rewind: if (ei->hint_femp.eidx == EXFAT_HINT_NONE || candi_empty.eidx <= - ei->hint_femp.eidx) { - memcpy(&ei->hint_femp, - &candi_empty, - sizeof(candi_empty)); - } + ei->hint_femp.eidx) + ei->hint_femp = candi_empty; } brelse(bh); diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index c013fe931d9c..b8f0e829ecbd 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -128,7 +128,7 @@ enum { struct exfat_dentry_namebuf { char *lfn; - int lfnbuf_len; /* usally MAX_UNINAME_BUF_SIZE */ + int lfnbuf_len; /* usually MAX_UNINAME_BUF_SIZE */ }; /* unicode name structure */ @@ -265,8 +265,6 @@ struct exfat_inode_info { * the validation of hint_stat. */ unsigned int version; - /* file offset or dentry index for readdir */ - loff_t rwoffset; /* hint for cluster last accessed */ struct exfat_hint hint_bmap; diff --git a/fs/exfat/file.c b/fs/exfat/file.c index f41f523a58ad..a92478eabfa4 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -208,8 +208,6 @@ int __exfat_truncate(struct inode *inode, loff_t new_size) /* hint information */ ei->hint_bmap.off = EXFAT_EOF_CLUSTER; ei->hint_bmap.clu = EXFAT_EOF_CLUSTER; - if (ei->rwoffset > new_size) - ei->rwoffset = new_size; /* hint_stat will be used if this is directory. */ ei->hint_stat.eidx = 0; @@ -229,7 +227,7 @@ void exfat_truncate(struct inode *inode, loff_t size) { struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); - unsigned int blocksize = 1 << inode->i_blkbits; + unsigned int blocksize = i_blocksize(inode); loff_t aligned_size; int err; diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index a6de17cac3df..730373e0965a 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -114,8 +114,6 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, unsigned int local_clu_offset = clu_offset; unsigned int num_to_be_allocated = 0, num_clusters = 0; - ei->rwoffset = EXFAT_CLU_TO_B(clu_offset, sbi); - if (EXFAT_I(inode)->i_size_ondisk > 0) num_clusters = EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, @@ -556,7 +554,7 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info) struct exfat_inode_info *ei = EXFAT_I(inode); loff_t size = info->size; - memcpy(&ei->dir, &info->dir, sizeof(struct exfat_chain)); + ei->dir = info->dir; ei->entry = info->entry; ei->attr = info->attr; ei->start_clu = info->start_clu; @@ -567,7 +565,6 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info) ei->hint_stat.eidx = 0; ei->hint_stat.clu = info->start_clu; ei->hint_femp.eidx = EXFAT_HINT_NONE; - ei->rwoffset = 0; ei->hint_bmap.off = EXFAT_EOF_CLUSTER; ei->i_pos = 0; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index c94ac239f740..2932b23a3b6c 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -290,7 +290,7 @@ static int exfat_check_max_dentries(struct inode *inode) { if (EXFAT_B_TO_DEN(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) { /* - * exFAT spec allows a dir to grow upto 8388608(256MB) + * exFAT spec allows a dir to grow up to 8388608(256MB) * dentries */ return -ENOSPC; @@ -318,8 +318,7 @@ static int exfat_find_empty_entry(struct inode *inode, hint_femp.eidx = EXFAT_HINT_NONE; if (ei->hint_femp.eidx != EXFAT_HINT_NONE) { - memcpy(&hint_femp, &ei->hint_femp, - sizeof(struct exfat_hint_femp)); + hint_femp = ei->hint_femp; ei->hint_femp.eidx = EXFAT_HINT_NONE; } @@ -519,7 +518,7 @@ static int exfat_add_entry(struct inode *inode, const char *path, if (ret) goto out; - memcpy(&info->dir, p_dir, sizeof(struct exfat_chain)); + info->dir = *p_dir; info->entry = dentry; info->flags = ALLOC_NO_FAT_CHAIN; info->type = type; @@ -530,19 +529,10 @@ static int exfat_add_entry(struct inode *inode, const char *path, info->size = 0; info->num_subdirs = 0; } else { - int count; - struct exfat_chain cdir; - info->attr = ATTR_SUBDIR; info->start_clu = start_clu; info->size = clu_size; - - exfat_chain_set(&cdir, info->start_clu, - EXFAT_B_TO_CLU(info->size, sbi), info->flags); - count = exfat_count_dir_entries(sb, &cdir); - if (count < 0) - return -EIO; - info->num_subdirs = count + EXFAT_MIN_SUBDIR; + info->num_subdirs = EXFAT_MIN_SUBDIR; } memset(&info->crtime, 0, sizeof(info->crtime)); memset(&info->mtime, 0, sizeof(info->mtime)); @@ -604,6 +594,8 @@ static int exfat_find(struct inode *dir, struct qstr *qname, struct super_block *sb = dir->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_inode_info *ei = EXFAT_I(dir); + struct exfat_dentry *ep, *ep2; + struct exfat_entry_set_cache *es; if (qname->len == 0) return -ENOENT; @@ -629,91 +621,63 @@ static int exfat_find(struct inode *dir, struct qstr *qname, dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, num_entries, TYPE_ALL); - if ((dentry < 0) && (dentry != -EEXIST)) + if (dentry < 0) return dentry; /* -error value */ - memcpy(&info->dir, &cdir.dir, sizeof(struct exfat_chain)); + info->dir = cdir; info->entry = dentry; info->num_subdirs = 0; - /* root directory itself */ - if (unlikely(dentry == -EEXIST)) { - int num_clu = 0; + es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); + if (!es) + return -EIO; + ep = exfat_get_dentry_cached(es, 0); + ep2 = exfat_get_dentry_cached(es, 1); + + info->type = exfat_get_entry_type(ep); + info->attr = le16_to_cpu(ep->dentry.file.attr); + info->size = le64_to_cpu(ep2->dentry.stream.valid_size); + if ((info->type == TYPE_FILE) && (info->size == 0)) { + info->flags = ALLOC_NO_FAT_CHAIN; + info->start_clu = EXFAT_EOF_CLUSTER; + } else { + info->flags = ep2->dentry.stream.flags; + info->start_clu = + le32_to_cpu(ep2->dentry.stream.start_clu); + } - info->type = TYPE_DIR; - info->attr = ATTR_SUBDIR; - info->flags = ALLOC_FAT_CHAIN; - info->start_clu = sbi->root_dir; - memset(&info->crtime, 0, sizeof(info->crtime)); - memset(&info->mtime, 0, sizeof(info->mtime)); - memset(&info->atime, 0, sizeof(info->atime)); - - exfat_chain_set(&cdir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); - if (exfat_count_num_clusters(sb, &cdir, &num_clu)) - return -EIO; - info->size = num_clu << sbi->cluster_size_bits; + exfat_get_entry_time(sbi, &info->crtime, + ep->dentry.file.create_tz, + ep->dentry.file.create_time, + ep->dentry.file.create_date, + ep->dentry.file.create_time_cs); + exfat_get_entry_time(sbi, &info->mtime, + ep->dentry.file.modify_tz, + ep->dentry.file.modify_time, + ep->dentry.file.modify_date, + ep->dentry.file.modify_time_cs); + exfat_get_entry_time(sbi, &info->atime, + ep->dentry.file.access_tz, + ep->dentry.file.access_time, + ep->dentry.file.access_date, + 0); + exfat_free_dentry_set(es, false); + + if (ei->start_clu == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)", + i_size_read(dir), ei->dir.dir, ei->entry); + return -EIO; + } + if (info->type == TYPE_DIR) { + exfat_chain_set(&cdir, info->start_clu, + EXFAT_B_TO_CLU(info->size, sbi), info->flags); count = exfat_count_dir_entries(sb, &cdir); if (count < 0) return -EIO; - info->num_subdirs = count; - } else { - struct exfat_dentry *ep, *ep2; - struct exfat_entry_set_cache *es; - - es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); - if (!es) - return -EIO; - ep = exfat_get_dentry_cached(es, 0); - ep2 = exfat_get_dentry_cached(es, 1); - - info->type = exfat_get_entry_type(ep); - info->attr = le16_to_cpu(ep->dentry.file.attr); - info->size = le64_to_cpu(ep2->dentry.stream.valid_size); - if ((info->type == TYPE_FILE) && (info->size == 0)) { - info->flags = ALLOC_NO_FAT_CHAIN; - info->start_clu = EXFAT_EOF_CLUSTER; - } else { - info->flags = ep2->dentry.stream.flags; - info->start_clu = - le32_to_cpu(ep2->dentry.stream.start_clu); - } - - if (ei->start_clu == EXFAT_FREE_CLUSTER) { - exfat_fs_error(sb, - "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)", - i_size_read(dir), ei->dir.dir, ei->entry); - exfat_free_dentry_set(es, false); - return -EIO; - } - - exfat_get_entry_time(sbi, &info->crtime, - ep->dentry.file.create_tz, - ep->dentry.file.create_time, - ep->dentry.file.create_date, - ep->dentry.file.create_time_cs); - exfat_get_entry_time(sbi, &info->mtime, - ep->dentry.file.modify_tz, - ep->dentry.file.modify_time, - ep->dentry.file.modify_date, - ep->dentry.file.modify_time_cs); - exfat_get_entry_time(sbi, &info->atime, - ep->dentry.file.access_tz, - ep->dentry.file.access_time, - ep->dentry.file.access_date, - 0); - exfat_free_dentry_set(es, false); - - if (info->type == TYPE_DIR) { - exfat_chain_set(&cdir, info->start_clu, - EXFAT_B_TO_CLU(info->size, sbi), info->flags); - count = exfat_count_dir_entries(sb, &cdir); - if (count < 0) - return -EIO; - - info->num_subdirs = count + EXFAT_MIN_SUBDIR; - } + info->num_subdirs = count + EXFAT_MIN_SUBDIR; } return 0; } @@ -1065,7 +1029,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir, if (!epnew) return -EIO; - memcpy(epnew, epold, DENTRY_SIZE); + *epnew = *epold; if (exfat_get_entry_type(epnew) == TYPE_FILE) { epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE); ei->attr |= ATTR_ARCHIVE; @@ -1085,7 +1049,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir, return -EIO; } - memcpy(epnew, epold, DENTRY_SIZE); + *epnew = *epold; exfat_update_bh(new_bh, sync); brelse(old_bh); brelse(new_bh); @@ -1130,11 +1094,6 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, if (!epmov) return -EIO; - /* check if the source and target directory is the same */ - if (exfat_get_entry_type(epmov) == TYPE_DIR && - le32_to_cpu(epmov->dentry.stream.start_clu) == p_newdir->dir) - return -EINVAL; - num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry, epmov); if (num_old_entries < 0) @@ -1153,7 +1112,7 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, if (!epnew) return -EIO; - memcpy(epnew, epmov, DENTRY_SIZE); + *epnew = *epmov; if (exfat_get_entry_type(epnew) == TYPE_FILE) { epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE); ei->attr |= ATTR_ARCHIVE; @@ -1173,7 +1132,7 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, return -EIO; } - memcpy(epnew, epmov, DENTRY_SIZE); + *epnew = *epmov; exfat_update_bh(new_bh, IS_DIRSYNC(inode)); brelse(mov_bh); brelse(new_bh); diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c index a3c927501e67..675d0e7058c5 100644 --- a/fs/exfat/nls.c +++ b/fs/exfat/nls.c @@ -11,7 +11,7 @@ #include "exfat_raw.h" #include "exfat_fs.h" -/* Upcase tabel macro */ +/* Upcase table macro */ #define EXFAT_NUM_UPCASE (2918) #define UTBL_COUNT (0x10000) diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 60b941ba557b..3ffdce5c7384 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -342,7 +342,6 @@ static int exfat_read_root(struct inode *inode) ei->flags = ALLOC_FAT_CHAIN; ei->type = TYPE_DIR; ei->version = 0; - ei->rwoffset = 0; ei->hint_bmap.off = EXFAT_EOF_CLUSTER; ei->hint_stat.eidx = 0; ei->hint_stat.clu = sbi->root_dir; |