mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-06 05:13:18 +00:00
exfat: remove duplicate write inode for truncating file
This commit moves updating file attributes and timestamps before calling __exfat_write_inode(), so that all updates of the inode had been written by __exfat_write_inode(), mark_inode_dirty() is unneeded. 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
23e6e1c9b3
commit
4493895b2b
@ -148,8 +148,17 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
||||
if (ei->type == TYPE_FILE)
|
||||
ei->attr |= ATTR_ARCHIVE;
|
||||
|
||||
/* update the directory entry */
|
||||
inode->i_mtime = current_time(inode);
|
||||
/*
|
||||
* update the directory entry
|
||||
*
|
||||
* If the directory entry is updated by mark_inode_dirty(), the
|
||||
* directory entry will be written after a writeback cycle of
|
||||
* updating the bitmap/FAT, which may result in clusters being
|
||||
* freed but referenced by the directory entry in the event of a
|
||||
* sudden power failure.
|
||||
* __exfat_write_inode() is called for directory entry, bitmap
|
||||
* and FAT to be written in a same writeback.
|
||||
*/
|
||||
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
|
||||
return -EIO;
|
||||
|
||||
@ -202,12 +211,6 @@ void exfat_truncate(struct inode *inode, loff_t size)
|
||||
if (err)
|
||||
goto write_size;
|
||||
|
||||
inode->i_ctime = inode->i_mtime = current_time(inode);
|
||||
if (IS_DIRSYNC(inode))
|
||||
exfat_sync_inode(inode);
|
||||
else
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
|
||||
inode->i_blkbits;
|
||||
write_size:
|
||||
@ -289,6 +292,12 @@ int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
|
||||
attr->ia_valid &= ~ATTR_MODE;
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_SIZE)
|
||||
inode->i_mtime = inode->i_ctime = current_time(inode);
|
||||
|
||||
setattr_copy(&init_user_ns, inode, attr);
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
|
||||
if (attr->ia_valid & ATTR_SIZE) {
|
||||
error = exfat_block_truncate_page(inode, attr->ia_size);
|
||||
if (error)
|
||||
@ -296,13 +305,15 @@ int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
|
||||
|
||||
down_write(&EXFAT_I(inode)->truncate_lock);
|
||||
truncate_setsize(inode, attr->ia_size);
|
||||
|
||||
/*
|
||||
* __exfat_write_inode() is called from exfat_truncate(), inode
|
||||
* is already written by it, so mark_inode_dirty() is unneeded.
|
||||
*/
|
||||
exfat_truncate(inode, attr->ia_size);
|
||||
up_write(&EXFAT_I(inode)->truncate_lock);
|
||||
}
|
||||
|
||||
setattr_copy(&init_user_ns, inode, attr);
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
mark_inode_dirty(inode);
|
||||
} else
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
out:
|
||||
return error;
|
||||
|
@ -369,6 +369,7 @@ static void exfat_write_failed(struct address_space *mapping, loff_t to)
|
||||
|
||||
if (to > i_size_read(inode)) {
|
||||
truncate_pagecache(inode, i_size_read(inode));
|
||||
inode->i_mtime = inode->i_ctime = current_time(inode);
|
||||
exfat_truncate(inode, EXFAT_I(inode)->i_size_aligned);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user