exfat: reuse __exfat_write_inode() to update directory entry
authorYuezhang Mo <Yuezhang.Mo@sony.com>
Wed, 29 Jun 2022 01:51:40 +0000 (09:51 +0800)
committerNamjae Jeon <linkinjeon@kernel.org>
Mon, 1 Aug 2022 01:14:05 +0000 (10:14 +0900)
__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>
fs/exfat/exfat_fs.h
fs/exfat/file.c
fs/exfat/inode.c
fs/exfat/namei.c

index 4a7a2308eb72d4bc335ea959196f651c3d3e373c..708d972700c0863915624abef8bed924eb57ad39 100644 (file)
@@ -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_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);
index 20d4e47f57ab2e27310f5da64df61eae95d3c8b3..08e5ffd78b1049a173701b86a7d8db0d6a704f18 100644 (file)
@@ -101,7 +101,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)
@@ -150,49 +149,9 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
                ei->attr |= ATTR_ARCHIVE;
 
        /* update the directory entry */
-       if (!evict) {
-               struct timespec64 ts;
-               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);
-
-               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;
-       }
+       inode->i_mtime = current_time(inode);
+       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 &&
index 0133d385d8e8904133a7b25491fadf9bcd4d876f..ebc64fa5c2de4a8c102016b1269da1bcedcdbaa3 100644 (file)
@@ -17,7 +17,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;
@@ -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.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);
@@ -216,32 +223,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;
index c6eaf7e9ea743a1cabd032bed93fd8dd465ade28..d640f9de16a907f3f3da19c7537dcd65e4d1254e 100644 (file)
@@ -318,7 +318,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);
@@ -383,31 +382,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;