From: Hyojun Kim <hyo...@google.com> 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 <hyo...@google.com> Signed-off-by: Jaegeuk Kim <jaeg...@google.com> --- fsck/segment.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/fsck/segment.c b/fsck/segment.c index d568d61..2ea5bf1 100644 --- a/fsck/segment.c +++ b/fsck/segment.c @@ -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) { -- 2.14.0.rc1.383.gd1ce394fe2-goog ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel