Commit 23e6e1c9 authored by Yuezhang Mo's avatar Yuezhang Mo Committed by Namjae Jeon
Browse files

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: default avatarYuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: default avatarAndy Wu <Andy.Wu@sony.com>
Reviewed-by: default avatarAoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: default avatarDaniel Palmer <daniel.palmer@sony.com>
Reviewed-by: default avatarSungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
parent 3d7cb6b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+3 −44
Original line number Diff line number Diff line
@@ -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)
	inode->i_mtime = current_time(inode);
	if (__exfat_write_inode(inode, inode_needs_sync(inode)))
		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 */
	if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
+11 −26
Original line number Diff line number Diff line
@@ -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;
+4 −20
Original line number Diff line number Diff line
@@ -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;