forked from Minki/linux
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> Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
3d7cb6b04c
commit
23e6e1c9b3
@ -483,6 +483,7 @@ struct inode *exfat_build_inode(struct super_block *sb,
|
|||||||
void exfat_hash_inode(struct inode *inode, loff_t i_pos);
|
void exfat_hash_inode(struct inode *inode, loff_t i_pos);
|
||||||
void exfat_unhash_inode(struct inode *inode);
|
void exfat_unhash_inode(struct inode *inode);
|
||||||
struct inode *exfat_iget(struct super_block *sb, loff_t i_pos);
|
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);
|
int exfat_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||||
void exfat_evict_inode(struct inode *inode);
|
void exfat_evict_inode(struct inode *inode);
|
||||||
int exfat_block_truncate_page(struct inode *inode, loff_t from);
|
int exfat_block_truncate_page(struct inode *inode, loff_t from);
|
||||||
|
@ -101,7 +101,6 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
|||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||||
struct exfat_inode_info *ei = EXFAT_I(inode);
|
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 */
|
/* check if the given file ID is opened */
|
||||||
if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
|
if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
|
||||||
@ -150,49 +149,9 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
|||||||
ei->attr |= ATTR_ARCHIVE;
|
ei->attr |= ATTR_ARCHIVE;
|
||||||
|
|
||||||
/* update the directory entry */
|
/* update the directory entry */
|
||||||
if (!evict) {
|
inode->i_mtime = current_time(inode);
|
||||||
struct timespec64 ts;
|
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
|
||||||
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;
|
return -EIO;
|
||||||
ep = exfat_get_dentry_cached(es, 0);
|
|
||||||
ep2 = exfat_get_dentry_cached(es, 1);
|
|
||||||
|
|
||||||
ts = current_time(inode);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cut off from the FAT chain */
|
/* cut off from the FAT chain */
|
||||||
if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
|
if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "exfat_raw.h"
|
#include "exfat_raw.h"
|
||||||
#include "exfat_fs.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;
|
unsigned long long on_disk_size;
|
||||||
struct exfat_dentry *ep, *ep2;
|
struct exfat_dentry *ep, *ep2;
|
||||||
@ -75,6 +75,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.valid_size = cpu_to_le64(on_disk_size);
|
||||||
ep2->dentry.stream.size = ep2->dentry.stream.valid_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);
|
exfat_update_dir_chksum_with_entry_set(es);
|
||||||
return exfat_free_dentry_set(es, sync);
|
return exfat_free_dentry_set(es, sync);
|
||||||
@ -216,32 +223,10 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
|
|||||||
num_clusters += num_to_be_allocated;
|
num_clusters += num_to_be_allocated;
|
||||||
*clu = new_clu.dir;
|
*clu = new_clu.dir;
|
||||||
|
|
||||||
if (ei->dir.dir != DIR_DELETED && modified) {
|
if (modified) {
|
||||||
struct exfat_dentry *ep;
|
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
|
||||||
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;
|
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 +=
|
inode->i_blocks +=
|
||||||
num_to_be_allocated << sbi->sect_per_clus_bits;
|
num_to_be_allocated << sbi->sect_per_clus_bits;
|
||||||
|
@ -318,7 +318,6 @@ static int exfat_find_empty_entry(struct inode *inode,
|
|||||||
unsigned int ret, last_clu;
|
unsigned int ret, last_clu;
|
||||||
loff_t size = 0;
|
loff_t size = 0;
|
||||||
struct exfat_chain clu;
|
struct exfat_chain clu;
|
||||||
struct exfat_dentry *ep = NULL;
|
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||||
struct exfat_inode_info *ei = EXFAT_I(inode);
|
struct exfat_inode_info *ei = EXFAT_I(inode);
|
||||||
@ -383,31 +382,16 @@ static int exfat_find_empty_entry(struct inode *inode,
|
|||||||
p_dir->size++;
|
p_dir->size++;
|
||||||
size = EXFAT_CLU_TO_B(p_dir->size, sbi);
|
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 */
|
/* directory inode should be updated in here */
|
||||||
i_size_write(inode, size);
|
i_size_write(inode, size);
|
||||||
ei->i_size_ondisk += sbi->cluster_size;
|
ei->i_size_ondisk += sbi->cluster_size;
|
||||||
ei->i_size_aligned += sbi->cluster_size;
|
ei->i_size_aligned += sbi->cluster_size;
|
||||||
ei->flags = p_dir->flags;
|
ei->flags = p_dir->flags;
|
||||||
inode->i_blocks += 1 << sbi->sect_per_clus_bits;
|
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;
|
return dentry;
|
||||||
|
Loading…
Reference in New Issue
Block a user