mirror of
https://gitee.com/openharmony/third_party_f2fs-tools
synced 2024-11-23 10:10:00 +00:00
sload.f2fs: fix bugs in f2fs_write_block()
Found and fixed following three bugs in f2fs_write_block() function. - Write (4096 - offset) bytes for the first block even for small count. - For overwriting, found blkaddr is not used for writing. - dn.idirty status can be lost by set_new_dnode(). - missing inode_checksum Signed-off-by: Hyojun Kim <hyojun@google.com> Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
This commit is contained in:
parent
8d46072f07
commit
5b2dc59ece
@ -16,6 +16,14 @@
|
||||
#include "fsck.h"
|
||||
#include "node.h"
|
||||
|
||||
static void write_inode(u64 blkaddr, struct f2fs_node *inode)
|
||||
{
|
||||
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
|
||||
inode->i.i_inode_checksum =
|
||||
cpu_to_le32(f2fs_inode_chksum(inode));
|
||||
ASSERT(dev_write_block(inode, blkaddr) >= 0);
|
||||
}
|
||||
|
||||
void reserve_new_block(struct f2fs_sb_info *sbi, block_t *to,
|
||||
struct f2fs_summary *sum, int type)
|
||||
{
|
||||
@ -71,6 +79,7 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer,
|
||||
void *data_blk;
|
||||
struct node_info ni;
|
||||
struct f2fs_node *inode;
|
||||
int idirty = 0;
|
||||
int ret = -1;
|
||||
|
||||
get_node_info(sbi, ino, &ni);
|
||||
@ -86,6 +95,8 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer,
|
||||
|
||||
off_in_block = offset & ((1 << F2FS_BLKSIZE_BITS) - 1);
|
||||
len_in_block = (1 << F2FS_BLKSIZE_BITS) - off_in_block;
|
||||
if (len_in_block > count)
|
||||
len_in_block = count;
|
||||
len_already = 0;
|
||||
|
||||
/*
|
||||
@ -115,17 +126,20 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer,
|
||||
blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node);
|
||||
|
||||
/* A new page from WARM_DATA */
|
||||
if (blkaddr == NULL_ADDR)
|
||||
if (blkaddr == NULL_ADDR) {
|
||||
new_data_block(sbi, data_blk, &dn,
|
||||
CURSEG_WARM_DATA);
|
||||
blkaddr = dn.data_blkaddr;
|
||||
idirty |= dn.idirty;
|
||||
}
|
||||
|
||||
/* Copy data from buffer to file */
|
||||
ret = dev_read_block(data_blk, dn.data_blkaddr);
|
||||
ret = dev_read_block(data_blk, blkaddr);
|
||||
ASSERT(ret >= 0);
|
||||
|
||||
memcpy(data_blk + off_in_block, buffer, len_in_block);
|
||||
|
||||
ret = dev_write_block(data_blk, dn.data_blkaddr);
|
||||
ret = dev_write_block(data_blk, blkaddr);
|
||||
ASSERT(ret >= 0);
|
||||
|
||||
off_in_block = 0;
|
||||
@ -148,13 +162,12 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer,
|
||||
/* Update the inode info */
|
||||
if (le64_to_cpu(inode->i.i_size) < offset + count) {
|
||||
inode->i.i_size = cpu_to_le64(offset + count);
|
||||
dn.idirty = 1;
|
||||
idirty = 1;
|
||||
}
|
||||
|
||||
if (dn.idirty) {
|
||||
if (idirty) {
|
||||
ASSERT(inode == dn.inode_blk);
|
||||
ret = dev_write_block(inode, ni.blk_addr);
|
||||
ASSERT(ret >= 0);
|
||||
write_inode(ni.blk_addr, inode);
|
||||
}
|
||||
|
||||
if (dn.node_blk && dn.node_blk != dn.inode_blk)
|
||||
@ -203,15 +216,8 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
|
||||
n = read(fd, buffer, BLOCK_SZ);
|
||||
ASSERT(n == de->size);
|
||||
memcpy(inline_data_addr(node_blk), buffer, de->size);
|
||||
|
||||
node_blk->i.i_size = cpu_to_le64(de->size);
|
||||
|
||||
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
|
||||
node_blk->i.i_inode_checksum =
|
||||
cpu_to_le32(f2fs_inode_chksum(node_blk));
|
||||
|
||||
ret = dev_write_block(node_blk, ni.blk_addr);
|
||||
ASSERT(ret >= 0);
|
||||
write_inode(ni.blk_addr, node_blk);
|
||||
free(node_blk);
|
||||
} else {
|
||||
while ((n = read(fd, buffer, BLOCK_SZ)) > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user