mirror of
https://gitee.com/openharmony/kernel_linux
synced 2025-02-19 02:33:01 +00:00
[PATCH] fat: Fix truncate() write ordering
The truncate() should write the file size before writing the new EOF entry. This patch fixes it. This bug was pointed out by Machida Hiroyuki. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
e60e5c50aa
commit
3b641407a1
@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip)
|
|||||||
if (MSDOS_I(inode)->i_start == 0)
|
if (MSDOS_I(inode)->i_start == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
fat_cache_inval_inode(inode);
|
||||||
* Write a new EOF, and get the remaining cluster chain for freeing.
|
|
||||||
*/
|
|
||||||
wait = IS_DIRSYNC(inode);
|
wait = IS_DIRSYNC(inode);
|
||||||
|
i_start = free_start = MSDOS_I(inode)->i_start;
|
||||||
|
i_logstart = MSDOS_I(inode)->i_logstart;
|
||||||
|
|
||||||
|
/* First, we write the new file size. */
|
||||||
|
if (!skip) {
|
||||||
|
MSDOS_I(inode)->i_start = 0;
|
||||||
|
MSDOS_I(inode)->i_logstart = 0;
|
||||||
|
}
|
||||||
|
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
|
||||||
|
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
if (wait) {
|
||||||
|
err = fat_sync_inode(inode);
|
||||||
|
if (err) {
|
||||||
|
MSDOS_I(inode)->i_start = i_start;
|
||||||
|
MSDOS_I(inode)->i_logstart = i_logstart;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
mark_inode_dirty(inode);
|
||||||
|
|
||||||
|
/* Write a new EOF, and get the remaining cluster chain for freeing. */
|
||||||
if (skip) {
|
if (skip) {
|
||||||
struct fat_entry fatent;
|
struct fat_entry fatent;
|
||||||
int ret, fclus, dclus;
|
int ret, fclus, dclus;
|
||||||
@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
free_start = ret;
|
free_start = ret;
|
||||||
i_start = i_logstart = 0;
|
|
||||||
fat_cache_inval_inode(inode);
|
|
||||||
} else {
|
|
||||||
fat_cache_inval_inode(inode);
|
|
||||||
|
|
||||||
i_start = free_start = MSDOS_I(inode)->i_start;
|
|
||||||
i_logstart = MSDOS_I(inode)->i_logstart;
|
|
||||||
MSDOS_I(inode)->i_start = 0;
|
|
||||||
MSDOS_I(inode)->i_logstart = 0;
|
|
||||||
}
|
}
|
||||||
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
|
|
||||||
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
|
|
||||||
if (wait) {
|
|
||||||
err = fat_sync_inode(inode);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
} else
|
|
||||||
mark_inode_dirty(inode);
|
|
||||||
inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
|
inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
|
||||||
|
|
||||||
/* Freeing the remained cluster chain */
|
/* Freeing the remained cluster chain */
|
||||||
return fat_free_clusters(inode, free_start);
|
return fat_free_clusters(inode, free_start);
|
||||||
|
|
||||||
error:
|
|
||||||
if (i_start) {
|
|
||||||
MSDOS_I(inode)->i_start = i_start;
|
|
||||||
MSDOS_I(inode)->i_logstart = i_logstart;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fat_truncate(struct inode *inode)
|
void fat_truncate(struct inode *inode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user