exfat: reuse __exfat_write_inode() to update directory entry
__exfat_write_inode() is used to update file and stream directory entries, except for file->start_clu and stream->flags. This commit moves update file->start_clu and stream->flags to __exfat_write_inode() and reuse __exfat_write_inode() to update directory entries. Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Reviewed-by: Andy Wu <Andy.Wu@sony.com> Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com> Reviewed-by: Daniel Palmer <daniel.palmer@sony.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
c509458c27
commit
56a5afdffa
@ -515,6 +515,7 @@ struct inode *exfat_build_inode(struct super_block *sb,
|
||||
void exfat_hash_inode(struct inode *inode, loff_t i_pos);
|
||||
void exfat_unhash_inode(struct inode *inode);
|
||||
struct inode *exfat_iget(struct super_block *sb, loff_t i_pos);
|
||||
int __exfat_write_inode(struct inode *inode, int sync);
|
||||
int exfat_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||
void exfat_evict_inode(struct inode *inode);
|
||||
int exfat_block_truncate_page(struct inode *inode, loff_t from);
|
||||
|
53
file.c
53
file.c
@ -108,7 +108,6 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||
struct exfat_inode_info *ei = EXFAT_I(inode);
|
||||
int evict = (ei->dir.dir == DIR_DELETED) ? 1 : 0;
|
||||
|
||||
/* check if the given file ID is opened */
|
||||
if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
|
||||
@ -157,57 +156,13 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
||||
ei->attr |= ATTR_ARCHIVE;
|
||||
|
||||
/* update the directory entry */
|
||||
if (!evict) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
struct timespec64 ts;
|
||||
#else
|
||||
struct timespec ts;
|
||||
#endif
|
||||
struct exfat_dentry *ep, *ep2;
|
||||
struct exfat_entry_set_cache *es;
|
||||
int err;
|
||||
|
||||
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
|
||||
ES_ALL_ENTRIES);
|
||||
if (!es)
|
||||
return -EIO;
|
||||
ep = exfat_get_dentry_cached(es, 0);
|
||||
ep2 = exfat_get_dentry_cached(es, 1);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
|
||||
ts = current_time(inode);
|
||||
inode->i_mtime = current_time(inode);
|
||||
#else
|
||||
ts = CURRENT_TIME_SEC;
|
||||
inode->i_mtime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_set_entry_time(sbi, &ts,
|
||||
&ep->dentry.file.modify_tz,
|
||||
&ep->dentry.file.modify_time,
|
||||
&ep->dentry.file.modify_date,
|
||||
&ep->dentry.file.modify_time_cs);
|
||||
ep->dentry.file.attr = cpu_to_le16(ei->attr);
|
||||
|
||||
/* File size should be zero if there is no cluster allocated */
|
||||
if (ei->start_clu == EXFAT_EOF_CLUSTER) {
|
||||
ep2->dentry.stream.valid_size = 0;
|
||||
ep2->dentry.stream.size = 0;
|
||||
} else {
|
||||
ep2->dentry.stream.valid_size = cpu_to_le64(new_size);
|
||||
ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
|
||||
}
|
||||
|
||||
if (new_size == 0) {
|
||||
/* Any directory can not be truncated to zero */
|
||||
WARN_ON(ei->type != TYPE_FILE);
|
||||
|
||||
ep2->dentry.stream.flags = ALLOC_FAT_CHAIN;
|
||||
ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER;
|
||||
}
|
||||
|
||||
exfat_update_dir_chksum_with_entry_set(es);
|
||||
err = exfat_free_dentry_set(es, inode_needs_sync(inode));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
|
||||
return -EIO;
|
||||
|
||||
/* cut off from the FAT chain */
|
||||
if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
|
||||
|
37
inode.c
37
inode.c
@ -19,7 +19,7 @@
|
||||
#include "exfat_raw.h"
|
||||
#include "exfat_fs.h"
|
||||
|
||||
static int __exfat_write_inode(struct inode *inode, int sync)
|
||||
int __exfat_write_inode(struct inode *inode, int sync)
|
||||
{
|
||||
unsigned long long on_disk_size;
|
||||
struct exfat_dentry *ep, *ep2;
|
||||
@ -77,6 +77,13 @@ static int __exfat_write_inode(struct inode *inode, int sync)
|
||||
|
||||
ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size);
|
||||
ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
|
||||
if (on_disk_size) {
|
||||
ep2->dentry.stream.flags = ei->flags;
|
||||
ep2->dentry.stream.start_clu = cpu_to_le32(ei->start_clu);
|
||||
} else {
|
||||
ep2->dentry.stream.flags = ALLOC_FAT_CHAIN;
|
||||
ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER;
|
||||
}
|
||||
|
||||
exfat_update_dir_chksum_with_entry_set(es);
|
||||
return exfat_free_dentry_set(es, sync);
|
||||
@ -218,32 +225,10 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
|
||||
num_clusters += num_to_be_allocated;
|
||||
*clu = new_clu.dir;
|
||||
|
||||
if (ei->dir.dir != DIR_DELETED && modified) {
|
||||
struct exfat_dentry *ep;
|
||||
struct exfat_entry_set_cache *es;
|
||||
int err;
|
||||
|
||||
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
|
||||
ES_ALL_ENTRIES);
|
||||
if (!es)
|
||||
if (modified) {
|
||||
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
|
||||
return -EIO;
|
||||
/* get stream entry */
|
||||
ep = exfat_get_dentry_cached(es, 1);
|
||||
|
||||
/* update directory entry */
|
||||
ep->dentry.stream.flags = ei->flags;
|
||||
ep->dentry.stream.start_clu =
|
||||
cpu_to_le32(ei->start_clu);
|
||||
ep->dentry.stream.valid_size =
|
||||
cpu_to_le64(i_size_read(inode));
|
||||
ep->dentry.stream.size =
|
||||
ep->dentry.stream.valid_size;
|
||||
|
||||
exfat_update_dir_chksum_with_entry_set(es);
|
||||
err = exfat_free_dentry_set(es, inode_needs_sync(inode));
|
||||
if (err)
|
||||
return err;
|
||||
} /* end of if != DIR_DELETED */
|
||||
}
|
||||
|
||||
inode->i_blocks +=
|
||||
num_to_be_allocated << sbi->sect_per_clus_bits;
|
||||
|
24
namei.c
24
namei.c
@ -345,7 +345,6 @@ static int exfat_find_empty_entry(struct inode *inode,
|
||||
unsigned int ret, last_clu;
|
||||
loff_t size = 0;
|
||||
struct exfat_chain clu;
|
||||
struct exfat_dentry *ep = NULL;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||
struct exfat_inode_info *ei = EXFAT_I(inode);
|
||||
@ -410,31 +409,16 @@ static int exfat_find_empty_entry(struct inode *inode,
|
||||
p_dir->size++;
|
||||
size = EXFAT_CLU_TO_B(p_dir->size, sbi);
|
||||
|
||||
/* update the directory entry */
|
||||
if (p_dir->dir != sbi->root_dir) {
|
||||
struct buffer_head *bh;
|
||||
|
||||
ep = exfat_get_dentry(sb,
|
||||
&(ei->dir), ei->entry + 1, &bh);
|
||||
if (!ep)
|
||||
return -EIO;
|
||||
|
||||
ep->dentry.stream.valid_size = cpu_to_le64(size);
|
||||
ep->dentry.stream.size = ep->dentry.stream.valid_size;
|
||||
ep->dentry.stream.flags = p_dir->flags;
|
||||
exfat_update_bh(bh, IS_DIRSYNC(inode));
|
||||
brelse(bh);
|
||||
if (exfat_update_dir_chksum(inode, &(ei->dir),
|
||||
ei->entry))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* directory inode should be updated in here */
|
||||
i_size_write(inode, size);
|
||||
ei->i_size_ondisk += sbi->cluster_size;
|
||||
ei->i_size_aligned += sbi->cluster_size;
|
||||
ei->flags = p_dir->flags;
|
||||
inode->i_blocks += 1 << sbi->sect_per_clus_bits;
|
||||
|
||||
/* update the directory entry */
|
||||
if (__exfat_write_inode(inode, IS_DIRSYNC(inode)))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return dentry;
|
||||
|
Loading…
Reference in New Issue
Block a user