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:
Hyojun Kim 2017-10-30 12:12:39 -07:00 committed by Jaegeuk Kim
parent 8d46072f07
commit 5b2dc59ece

View File

@ -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) {