Re: [PATCH v3 2/2] exfat: aggregate dir-entry updates into __exfat_write_inode().

2020-10-18 Thread Tetsuhiro Kohada

@@ -184,6 +185,11 @@ static int exfat_map_cluster(struct inode *inode, unsigned 
int clu_offset,
return -EIO;
}

+   exfat_warn(sb, "alloc[%lu]@map: %lld (%d - %08x)",
+  inode->i_ino, i_size_read(inode),
+  (clu_offset << sbi->sect_per_clus_bits) * 512,
+  last_clu);

Is this leftover print from debugging?


Oops!
Yes, just as you said.
I will post V4 soon.
Is there any other problem?


BR
---
Tetsuhiro Kohada 


RE: [PATCH v3 2/2] exfat: aggregate dir-entry updates into __exfat_write_inode().

2020-10-16 Thread Namjae Jeon
> *inode)  static int exfat_map_cluster(struct inode *inode, unsigned int 
> clu_offset,
>   unsigned int *clu, int create)
>  {
> - int ret, modified = false;
> + int ret;
>   unsigned int last_clu;
>   struct exfat_chain new_clu;
>   struct super_block *sb = inode->i_sb;
> @@ -184,6 +185,11 @@ static int exfat_map_cluster(struct inode *inode, 
> unsigned int clu_offset,
>   return -EIO;
>   }
> 
> + exfat_warn(sb, "alloc[%lu]@map: %lld (%d - %08x)",
> +inode->i_ino, i_size_read(inode),
> +(clu_offset << sbi->sect_per_clus_bits) * 512,
> +last_clu);
Is this leftover print from debugging?



[PATCH v3 2/2] exfat: aggregate dir-entry updates into __exfat_write_inode().

2020-10-02 Thread Tetsuhiro Kohada
The following function writes the updated inode information as dir-entry
by themselves.
 - __exfat_truncate()
 - exfat_map_cluster()
 - exfat_find_empty_entry()
Aggregate these writes into __exfat_write_inode().

In exfat_map_cluster(), the value obtained from i_size_read() is set to
stream.valid_size and stream.size.
However, in the context of get_block(), inode->i_size has not been set yet,
so the same value as current will be set, which is a meaningless update.
Furthermore, if it is called with previous size=0, the newly allocated
cluster number will be set to stream.start_clu, and stream.valid_size/size
will be 0, which is illegal.
Update stream.valid_size/size and stream.start_clu when __exfat_write_inode
is called after i_size is set, to prevent meaningless/illegal updates.

Others:
 - Remove double inode-update in __exfat_truncate() and exfat_truncate().
 - In __exfat_write_inode(), rename 'on_disk_size' to 'filesize' and
   add adjustment when filesize is 0.

Signed-off-by: Tetsuhiro Kohada 
---
Changes in v3
 - Remove update_inode() in exfat_map_cluster()/exfat_truncate()
 - Update commit-message
Changes in v2
 - Fix endian issue

 fs/exfat/file.c  | 52 +---
 fs/exfat/inode.c | 47 +++
 fs/exfat/namei.c | 26 +---
 3 files changed, 22 insertions(+), 103 deletions(-)

diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index e510b95dbf77..211fb947747a 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -100,7 +100,7 @@ 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;
+   int ret;
 
/* check if the given file ID is opened */
if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
@@ -150,49 +150,10 @@ 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, ,
-   >dentry.file.modify_tz,
-   >dentry.file.modify_time,
-   >dentry.file.modify_date,
-   >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_ctime = inode->i_mtime = current_time(inode);
+   ret = exfat_update_inode(inode);
+   if (ret)
+   return ret;
 
/* cut off from the FAT chain */
if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
@@ -244,9 +205,6 @@ void exfat_truncate(struct inode *inode, loff_t size)
if (err)
goto write_size;
 
-   inode->i_ctime = inode->i_mtime = current_time(inode);
-   exfat_update_inode(inode);
-
inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) &
~(sbi->cluster_size - 1)) >> inode->i_blkbits;
 write_size:
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
index 5a55303e1f65..cf29b14ce7f9 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -19,7 +19,7 @@
 
 static int __exfat_write_inode(struct inode *inode, int sync)
 {
-   unsigned long long on_disk_size;
+   unsigned long long filesize;
struct exfat_dentry *ep, *ep2;
struct exfat_entry_set_cache *es =