fsck is broken on mips32 platform
Hi !
I'm using f2fs on router Dlink dir-825 with openwrt/LEDE firmware. Its mips32 rel 2 big endian cpu.
mkfs.f2fs - works
mount - works
fsck.f2fs - corrupts filesystem
# i'm trying to fsck valid empty mountable f2fs partition i have just mkfs'ed
fsck.f2fs /dev/sda2
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 6508544 (3178 MB)
Info: MKFS version
"Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"
Info: FSCK version
from "Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"
to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 6508544 (3178 MB)
Info: CKPT version = 1
Info: checkpoint state = 5 : compacted_summary unmount [ASSERT] (sanity_check_nid: 356) --> nid is not valid. [0x3]
NID[0x3] is unreachable
[FSCK] Unreachable nat entries [Fail] [0x1] [FSCK] SIT valid block bitmap checking [Fail] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Fail] [0x0] [FSCK] valid_node_count matcing with CP (de lookup) [Fail] [0x0] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Fail] [0x0] [FSCK] free segment_count matched with CP [Fail] [0x621] [FSCK] next block offset is free [Ok..]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs [Fail]
[FIX] (nullify_nat_entry:1688) --> Remove nid [0x3] in nat journal
After failed mount attempt :
dmesg
F2FS-fs (sda2): Failed to read root inode
On x86 and ARM everything is ok
f2fs-tools 1.7.0
kernel 4.4.30
------------------------------------------------------------------------------
Hi,
Quoted 19 lines · On 11/25/2016 6:30 AM, [email protected] wrote:
Hi !
I'm using f2fs on router Dlink dir-825 with openwrt/LEDE firmware. Its mips32 rel 2 big endian cpu.
mkfs.f2fs - works
mount - works
fsck.f2fs - corrupts filesystem# i'm trying to fsck valid empty mountable f2fs partition i have just mkfs'ed
fsck.f2fs/dev/sda2
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 6508544 (3178 MB)
Info: MKFS version
"Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"
Info: FSCK version
from "Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"
Quoted 7 lines
to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 6508544 (3178 MB)
Info: CKPT version = 1
Info: checkpoint state = 5 :compacted_summaryunmount [ASSERT] (sanity_check_nid: 356) --> nid is not valid. [0x3]
It seems that sanity_check_nid does not switch little endian value to big endian. I'm not sure if it is caused by this and if there are any other places have this endian switch issue, could you please test this.
thanks,
Sheng
======
fsck/f2fs.h +2 -2
@@ -370,7 +370,7 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)static inline bool IS_VALID_NID (struct f2fs_sb_info *sbi,u32 nid) {return (nid <= (NAT_ENTRY_PER_BLOCK * -F2FS_RAW_SUPER (sbi)->segment_count_nat +le32_to_cpu (F2FS_RAW_SUPER (sbi)->segment_count_nat) << (sbi->log_blocks_per_seg -1 ))); }
@@ -378,7 +378,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) {int i; -if (addr >=F2FS_RAW_SUPER (sbi)->block_count || +if (addr >=le64_to_cpu (F2FS_RAW_SUPER (sbi)->block_count) || addr <SM_I (sbi)->main_blkaddr) {DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ;
Quoted 26 lines
NID[0x3] is unreachable
[FSCK] Unreachable nat entries [Fail] [0x1] [FSCK] SIT valid block bitmap checking [Fail] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Fail] [0x0] [FSCK] valid_node_count matcing with CP (de lookup) [Fail] [0x0] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Fail] [0x0] [FSCK] free segment_count matched with CP [Fail] [0x621] [FSCK] next block offset is free [Ok..][FSCK] fixing SIT types
[FSCK] other corrupted bugs [Fail]
[FIX] (nullify_nat_entry:1688) --> Remove nid [0x3] in nat journalAfter failed mount attempt :
dmesg
F2FS-fs (sda2): Failed to read root inodeOn x86 and ARM everything is ok
f2fs-tools 1.7.0
kernel 4.4.30
Quoted 8 lines
------------------------------------------------------------------------------
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel.
------------------------------------------------------------------------------
Hi, Sheng.
A bit better but still fail. At least it does not corrupt fs and it mounts.
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 204800 (100 MB)
Info: MKFS version
"Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: FSCK version
from "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 204800 (100 MB)
Info: CKPT version = 3
Info: checkpoint state = 5 : compacted_summary unmount
[FSCK] Unreachable nat entries [Ok..] [0x0] [FSCK] SIT valid block bitmap checking [Ok..] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Ok..] [0x2] [FSCK] valid_node_count matcing with CP (de lookup) [Ok..] [0x1] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Ok..] [0x1] [FSCK] free segment_count matched with CP [Fail] [0x27] [FSCK] next block offset is free [Ok..]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs [Fail]
....... at this point according to strace fsck does readv from descriptor 0 (stdin). Must interrupt it with ctrl+c
Quoted 54 lines
Hi,
Quoted 19 lines · On 11/25/2016 6:30 AM, [email protected] wrote:
Hi !
I'm using f2fs on router Dlink dir-825 with openwrt/LEDE firmware. Its mips32 rel 2 big endian cpu.
mkfs.f2fs - works
mount - works
fsck.f2fs - corrupts filesystem# i'm trying to fsck valid empty mountable f2fs partition i have just mkfs'ed
fsck.f2fs/dev/sda2
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 6508544 (3178 MB)
Info: MKFS version
"Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"
Info: FSCK version
from "Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016"Quoted 7 lines
to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 6508544 (3178 MB)
Info: CKPT version = 1
Info: checkpoint state = 5 :compacted_summaryunmount [ASSERT] (sanity_check_nid: 356) --> nid is not valid. [0x3]It seems that
sanity_check_niddoes not switch little endian value to big endian. I'm not sure if it is caused by this and if there are any other places have this endian switch issue, could you please test this.thanks,
Sheng======
fsck/f2fs.h +1
-1@@ -370,7 +370,7 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type) static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid) { return (nid <= (NAT_ENTRY_PER_BLOCK * - F2FS_RAW_SUPER(sbi)->segment_count_nat + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat) << (sbi->log_blocks_per_seg - 1)));}
fsck/f2fs.h static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) · line 379
Quoted 2 lines
fsck/f2fs.h +0
-0@@ -378,7 +378,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) {int i;
- if (addr >>= F2FS_RAW_SUPER(sbi)->block_count ||
+ if (addr >>= le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count) ||
Quoted 29 lines
fsck/f2fs.h +0
-0addr < SM_I(sbi)->main_blkaddr) {DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ;Quoted 26 lines
NID[0x3] is unreachable
[FSCK] Unreachable nat entries [Fail] [0x1] [FSCK] SIT valid block bitmap checking [Fail] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Fail] [0x0] [FSCK] valid_node_count matcing with CP (de lookup) [Fail] [0x0] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Fail] [0x0] [FSCK] free segment_count matched with CP [Fail] [0x621] [FSCK] next block offset is free [Ok..][FSCK] fixing SIT types
[FSCK] other corrupted bugs [Fail]
[FIX] (nullify_nat_entry:1688) --> Remove nid [0x3] in nat journalAfter failed mount attempt :
dmesg
F2FS-fs (sda2): Failed to read root inodeOn x86 and ARM everything is ok
f2fs-tools 1.7.0
kernel 4.4.30
Quoted 8 lines
Quoted 8 lines
------------------------------------------------------------------------------
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel.
------------------------------------------------------------------------------
PATCH 1/2 fsck.f2fs: remove duplicated header files
--- fsck/f2fs.h | 2 -- fsck/xattr.h | 1 - 2 files changed, 3 deletions(-)
fsck/f2fs.h +0 -2
@@ -19,8 +19,6 @@#include <string.h> #include <errno.h> #include <mntent.h> -#include <linux/types.h> -#include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mount.h>
fsck/xattr.h +0 -1
@@ -16,7 +16,6 @@#ifndef _XATTR_H_#define _XATTR_H_ -#include <f2fs_fs.h> #include "f2fs.h" struct f2fs_xattr_header {
Signature · 4 lines
2.10.2 ------------------------------------------------------------------------------
PATCH 2/2 fsck.f2fs: correct endianness
---
Hi, k
Could you please try this? I think I've correct all endianness issue. And can I have your reported-by and test-by?
thanks,
Sheng
--- fsck/dir.c | 6 +++--- fsck/dump.c | 10 +++++----- fsck/f2fs.h | 4 ++-- fsck/mount.c | 12 ++++++------ fsck/node.c | 2 +- fsck/segment.c | 3 ++- include/f2fs_fs.h | 8 +++++--- 7 files changed, 24 insertions(+), 21 deletions(-)
fsck/dir.c +3 -3
@@ -134,7 +134,7 @@ static int find_in_level(struct f2fs_sb_info *sbi,struct f2fs_node *dir,struct dnode_of_data dn = {0 };void *dentry_blk;int max_slots =214 ; -nid_t ino = dir->footer.ino; +nid_t ino =le32_to_cpu (dir->footer.ino);f2fs_hash_t namehash;int ret =0 ;
@@ -191,7 +191,7 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,return 0 ; } - max_depth = dir->i.i_current_depth; + max_depth =le32_to_cpu (dir->i.i_current_depth);for (level =0 ; level < max_depth; level ++) {if (find_in_level (sbi, dir, level, de))return 1 ;
@@ -209,7 +209,7 @@ static void f2fs_update_dentry(nid_t ino, umode_t mode,int i; de = &d->dentry[bit_pos]; - de->name_len = len; + de->name_len =cpu_to_le16 (len); de->hash_code = name_hash;memcpy (d->filename[bit_pos], name, len); d->filename[bit_pos][len] =0 ;
fsck/dump.c +5 -5
@@ -81,7 +81,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +le32_to_cpu (node_block->footer.flag) >>OFFSET_BIT_SHIFT , ni.blk_addr, pack); ret =write (fd, buf,strlen (buf));
@@ -100,7 +100,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +le32_to_cpu (node_block->footer.flag) >>OFFSET_BIT_SHIFT , ni.blk_addr, pack); ret =write (fd, buf,strlen (buf));
@@ -335,13 +335,13 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,for (i =0 ; i <5 ; i++) {if (i ==0 || i ==1 )dump_node_blk (sbi,TYPE_DIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==2 || i ==3 )dump_node_blk (sbi,TYPE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==4 )dump_node_blk (sbi,TYPE_DOUBLE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else ASSERT (0 ); }
fsck/f2fs.h +2 -2
@@ -359,7 +359,7 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)static inline bool IS_VALID_NID (struct f2fs_sb_info *sbi,u32 nid) {return (nid <= (NAT_ENTRY_PER_BLOCK * -F2FS_RAW_SUPER (sbi)->segment_count_nat +le32_to_cpu (F2FS_RAW_SUPER (sbi)->segment_count_nat) << (sbi->log_blocks_per_seg -1 ))); }
@@ -367,7 +367,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) {int i; -if (addr >=F2FS_RAW_SUPER (sbi)->block_count || +if (le64_to_cpu (addr >=F2FS_RAW_SUPER (sbi)->block_count) || addr <SM_I (sbi)->main_blkaddr) {DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ;
fsck/mount.c +6 -6
@@ -1375,12 +1375,12 @@ void build_sit_area_bitmap(struct f2fs_sb_info *sbi) ptr +=SIT_VBLOCK_MAP_SIZE ;if (se->valid_blocks ==0x0 ) { -if (sbi->ckpt->cur_node_segno[0 ] == segno || - sbi->ckpt->cur_data_segno[0 ] == segno || - sbi->ckpt->cur_node_segno[1 ] == segno || - sbi->ckpt->cur_data_segno[1 ] == segno || - sbi->ckpt->cur_node_segno[2 ] == segno || - sbi->ckpt->cur_data_segno[2 ] == segno) { +if (le32_to_cpu (sbi->ckpt->cur_node_segno[0 ]) == segno || +le32_to_cpu (sbi->ckpt->cur_data_segno[0 ]) == segno || +le32_to_cpu (sbi->ckpt->cur_node_segno[1 ]) == segno || +le32_to_cpu (sbi->ckpt->cur_data_segno[1 ]) == segno || +le32_to_cpu (sbi->ckpt->cur_node_segno[2 ]) == segno || +le32_to_cpu (sbi->ckpt->cur_data_segno[2 ]) == segno) {continue ; }else { free_segs++;
fsck/node.c +1 -1
@@ -78,7 +78,7 @@ block_t new_node_block(struct f2fs_sb_info *sbi, type =CURSEG_COLD_NODE ;if (IS_DNODE (node_blk)) { -if (S_ISDIR (f2fs_inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (f2fs_inode->i.i_mode))) type =CURSEG_HOT_NODE ;else type =CURSEG_WARM_NODE ;
fsck/segment.c +2 -1
@@ -80,7 +80,8 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer, ret =dev_read_block (inode, ni.blk_addr);ASSERT (ret >=0 ); -if (S_ISDIR (inode->i.i_mode) ||S_ISLNK (inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (inode->i.i_mode)) || +S_ISLNK (le16_to_cpu (inode->i.i_mode)))ASSERT (0 ); off_in_block = offset & ((1 <<F2FS_BLKSIZE_BITS ) -1 );
include/f2fs_fs.h +5 -3
@@ -170,15 +170,17 @@ static inline uint64_t bswap_64(uint64_t val)#define DISP_u32 (ptr, member) \ do { \ assert(sizeof((ptr)->member) <= 4); \ - printf("%-30s" "\t\t[0x%8x : %u]\n", \ - #member, ((ptr)->member), ((ptr)->member)); \ + printf("%-30s" "\t\t[0x%8x : %u]\n", \ + #member, le32_to_cpu(((ptr)->member)), \ + le32_to_cpu(((ptr)->member))); \ } while (0)#define DISP_u64 (ptr, member) \ do { \ assert(sizeof((ptr)->member) == 8); \ printf("%-30s" "\t\t[0x%8llx : %llu]\n", \ - #member, ((ptr)->member), ((ptr)->member)); \ + #member, le64_to_cpu(((ptr)->member)), \ + le64_to_cpu(((ptr)->member))); \ } while (0)#define DISP_utf (ptr, member) \
Signature · 4 lines
2.10.2 ------------------------------------------------------------------------------
Re: [RFT PATCH 2/2] fsck.f2fs: correct endianness
The only thing I changed in your patch is :
- if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
+ if (le64_to_cpu(addr >= F2FS_RAW_SUPER(sbi)->block_count) ||
addr < SM_I(sbi)->main_blkaddr) {You're passing boolean to le64_to_cpu which is obviously error. I changed that to :
if (addr >= le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count) ||
And it worked without errors first on empty fs in a file, second on real sda partition with files.
I havent tested what happens if filesystem is damaged.
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 204800 (100 MB)
Info: MKFS version
"Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: FSCK version
from "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 204800 (100 MB)
Info: CKPT version = 1
Info: checkpoint state = 5 : compacted_summary unmount
[FSCK] Unreachable nat entries [Ok..] [0x0] [FSCK] SIT valid block bitmap checking [Ok..] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Ok..] [0x2] [FSCK] valid_node_count matcing with CP (de lookup) [Ok..] [0x1] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Ok..] [0x1] [FSCK] free segment_count matched with CP [Ok..] [0x24] [FSCK] next block offset is free [Ok..]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs [Ok..]
Done.
Quoted 43 lines
Reported-by <[email protected]>Signed-off-by Sheng Yong <[email protected]>---
Hi, kCould you please try this? I think I've correct all endianness issue. And can I have your reported-by and test-by?
thanks,
Sheng--- fsck/dir.c | 6 +++--- fsck/dump.c | 10 +++++----- fsck/f2fs.h | 4 ++-- fsck/mount.c | 12 ++++++------ fsck/node.c | 2 +- fsck/segment.c | 3 ++- include/f2fs_fs.h | 8 +++++--- 7 files changed, 24 insertions(+), 21 deletions(-)fsck/dir.c +2
-2@@ -134,7 +134,7 @@ static int find_in_level(struct f2fs_sb_info *sbi,struct f2fs_node *dir,struct dnode_of_data dn = {0 };void *dentry_blk;int max_slots =214 ; -nid_t ino = dir->footer.ino; +nid_t ino =le32_to_cpu (dir->footer.ino);f2fs_hash_t namehash;int ret =0 ;@@ -191,7 +191,7 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,return 0 ; } - max_depth = dir->i.i_current_depth; + max_depth =le32_to_cpu (dir->i.i_current_depth);for (level =0 ; level < max_depth; level ++) {if (find_in_level (sbi, dir, level, de))return 1 ;
fsck/dir.c static void f2fs_update_dentry(nid_t ino, umode_t mode, · line 211
Quoted 3 lines
fsck/dir.c +0
-0@@ -209,7 +209,7 @@ static void f2fs_update_dentry(nid_t ino, umode_t mode,int i; de = &d->dentry[bit_pos];
- de->>name_len = len;
+ de->>name_len = cpu_to_le16(len);
Quoted 63 lines
fsck/dir.c +0
-0de->hash_code = name_hash;memcpy (d->filename[bit_pos], name, len); d->filename[bit_pos][len] =0 ;fsck/dump.c +1
-1@@ -81,7 +81,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +
le32_to_cpu(node_block->footer.flag)>>OFFSET_BIT_SHIFT, ni.blk_addr, pack); ret = write(fd, buf, strlen(buf));fsck/dump.c +1
-1@@ -100,7 +100,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +
le32_to_cpu(node_block->footer.flag)>>OFFSET_BIT_SHIFT, ni.blk_addr, pack); ret = write(fd, buf, strlen(buf));fsck/dump.c +3
-3@@ -335,13 +335,13 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,for (i =0 ; i <5 ; i++) {if (i ==0 || i ==1 )dump_node_blk (sbi,TYPE_DIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==2 || i ==3 )dump_node_blk (sbi,TYPE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==4 )dump_node_blk (sbi,TYPE_DOUBLE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else ASSERT(0); }fsck/f2fs.h +1
-1@@ -359,7 +359,7 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type) static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid) { return (nid <= (NAT_ENTRY_PER_BLOCK * - F2FS_RAW_SUPER(sbi)->segment_count_nat + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat) << (sbi->log_blocks_per_seg - 1)));}
fsck/f2fs.h static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) · line 368
Quoted 2 lines
fsck/f2fs.h +0
-0@@ -367,7 +367,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) {int i;
- if (addr >>= F2FS_RAW_SUPER(sbi)->block_count ||
Quoted 90 lines
fsck/f2fs.h +1
-0+if (le64_to_cpu (addr >=F2FS_RAW_SUPER (sbi)->block_count) || addr <SM_I (sbi)->main_blkaddr) {DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ;fsck/mount.c +0
-2@@ -1375,12 +1375,12 @@ void build_sit_area_bitmap(struct f2fs_sb_info *sbi) ptr +=SIT_VBLOCK_MAP_SIZE ;if (se->valid_blocks ==0x0 ) { - if (sbi->ckpt->cur_node_segno[0] == segno || -sbi->ckpt->cur_data_segno[0] == segno ||
-
sbi->ckpt->cur_node_segno[1] == segno ||
-
sbi->ckpt->cur_data_segno[1] == segno ||
-
sbi->ckpt->cur_node_segno[2] == segno ||
-
sbi->ckpt->cur_data_segno[2] == segno) {
+ if
(le32_to_cpu(sbi->ckpt->cur_node_segno[0])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[0])== segno || +le32_to_cpu(sbi->ckpt->cur_node_segno[1])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[1])== segno || +le32_to_cpu(sbi->ckpt->cur_node_segno[2])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[2]) == segno) { continue; } else { free_segs++;fsck/node.c +1
-1@@ -78,7 +78,7 @@ block_t new_node_block(struct f2fs_sb_info *sbi, type =CURSEG_COLD_NODE ;if (IS_DNODE (node_blk)) { -if (S_ISDIR (f2fs_inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (f2fs_inode->i.i_mode))) type =CURSEG_HOT_NODE ;else type =CURSEG_WARM_NODE ;fsck/segment.c +2
-1@@ -80,7 +80,8 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer, ret =dev_read_block (inode, ni.blk_addr);ASSERT (ret >=0 ); -if (S_ISDIR (inode->i.i_mode) ||S_ISLNK (inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (inode->i.i_mode)) || +S_ISLNK (le16_to_cpu (inode->i.i_mode)))ASSERT (0 ); off_in_block = offset & ((1 <<F2FS_BLKSIZE_BITS ) -1 );include/f2fs_fs.h +5
-3@@ -170,15 +170,17 @@ static inline uint64_t bswap_64(uint64_t val)#define DISP_u32 (ptr, member) do {assert (sizeof ((ptr)->member) <=4 ); - printf("%-30s" "\t\t[0x%8x : %u]\n", \ - #member, ((ptr)->member), ((ptr)->member)); + printf("%-30s" "\t\t[0x%8x : %u]\n", + #member, le32_to_cpu(((ptr)->member)), +le32_to_cpu (((ptr)->member))); } while (0)#define DISP_u64 (ptr, member) do {assert (sizeof ((ptr)->member) ==8 ); printf("%-30s" "\t\t[0x%8llx : %llu]\n", - #member, ((ptr)->member), ((ptr)->member)); + #member, le64_to_cpu(((ptr)->member)), +le64_to_cpu (((ptr)->member))); } while (0)#define DISP_utf (ptr, member)
Signature · 9 lines
С уважением, K mailto:[email protected] ------------------------------------------------------------------------------ _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [RFT PATCH 2/2] fsck.f2fs: correct endianness
Quoted 11 lines · On 11/25/2016 11:55 PM, [email protected] wrote:
The only thing I changed in your patch is :
fsck/f2fs.h +1
-1-if (addr >=F2FS_RAW_SUPER (sbi)->block_count || +if (le64_to_cpu (addr >=F2FS_RAW_SUPER (sbi)->block_count) || addr <SM_I (sbi)->main_blkaddr) {You're passing boolean to
le64_to_cpuwhich is obviously error. I changed that to :if (addr >= le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count) ||
Right. My bad. I'll fix this and send a version 2 :)
thanks,
Sheng
Quoted 144 lines
And it worked without errors first on empty fs in a file, second on real sda partition with files.
I havent tested what happens if filesystem is damaged.Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 204800 (100 MB)
Info: MKFS version
"Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"
Info: FSCK version
from "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"to "Linux version 4.4.30 (vasya@nowhere) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2084) ) #0 PREEMPT Thu Nov 3 07:34:38 2016"Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 204800 (100 MB)
Info: CKPT version = 1
Info: checkpoint state = 5 :compacted_summaryunmount[FSCK] Unreachable nat entries [Ok..] [0x0] [FSCK] SIT valid block bitmap checking [Ok..] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Ok..] [0x2] [FSCK] valid_node_count matcing with CP (de lookup) [Ok..] [0x1] [FSCK] valid_node_count matcing with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Ok..] [0x1] [FSCK] free segment_count matched with CP [Ok..] [0x24] [FSCK] next block offset is free [Ok..][FSCK] fixing SIT types
[FSCK] other corrupted bugs [Ok..]Done.
Quoted 46 lines
Reported-by <[email protected]>Signed-off-by Sheng Yong <[email protected]>---
Hi, kCould you please try this? I think I've correct all endianness issue. And can I have your reported-by and test-by?
thanks,
Sheng--- fsck/dir.c | 6 +++--- fsck/dump.c | 10 +++++----- fsck/f2fs.h | 4 ++-- fsck/mount.c | 12 ++++++------ fsck/node.c | 2 +- fsck/segment.c | 3 ++- include/f2fs_fs.h | 8 +++++--- 7 files changed, 24 insertions(+), 21 deletions(-)fsck/dir.c +2
-2@@ -134,7 +134,7 @@ static int find_in_level(struct f2fs_sb_info *sbi,struct f2fs_node *dir,struct dnode_of_data dn = {0 };void *dentry_blk;int max_slots =214 ; -nid_t ino = dir->footer.ino; +nid_t ino =le32_to_cpu (dir->footer.ino);f2fs_hash_t namehash;int ret =0 ;@@ -191,7 +191,7 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,return 0 ; } - max_depth = dir->i.i_current_depth; + max_depth =le32_to_cpu (dir->i.i_current_depth);for (level =0 ; level < max_depth; level ++) {if (find_in_level (sbi, dir, level, de))return 1 ;@@ -209,7 +209,7 @@ static void f2fs_update_dentry(nid_t ino, umode_t mode,int i; de = &d->dentry[bit_pos];(quoted diff) +1
-1- de->>name_len = len; + de->>name_len = cpu_to_le16(len);Quoted 61 lines
fsck/dir.c +0
-0de->hash_code = name_hash;memcpy (d->filename[bit_pos], name, len); d->filename[bit_pos][len] =0 ;fsck/dump.c +1
-1@@ -81,7 +81,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +
le32_to_cpu(node_block->footer.flag)>>OFFSET_BIT_SHIFT, ni.blk_addr, pack); ret = write(fd, buf, strlen(buf));fsck/dump.c +1
-1@@ -100,7 +100,7 @@ void nat_dump(struct f2fs_sb_info *sbi)"nid:%5u\tino:%5u\toffset:%5u" "\tblkaddr:%10u\tpack:%d\n" , ni.nid, ni.ino, - node_block->footer.flag >> +
le32_to_cpu(node_block->footer.flag)>>OFFSET_BIT_SHIFT, ni.blk_addr, pack); ret = write(fd, buf, strlen(buf));fsck/dump.c +3
-3@@ -335,13 +335,13 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,for (i =0 ; i <5 ; i++) {if (i ==0 || i ==1 )dump_node_blk (sbi,TYPE_DIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==2 || i ==3 )dump_node_blk (sbi,TYPE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else if (i ==4 )dump_node_blk (sbi,TYPE_DOUBLE_INDIRECT_NODE , - node_blk->i.i_nid[i], &ofs); +le32_to_cpu (node_blk->i.i_nid[i]), &ofs);else ASSERT(0); }fsck/f2fs.h +1
-1@@ -359,7 +359,7 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type) static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid) { return (nid <= (NAT_ENTRY_PER_BLOCK * - F2FS_RAW_SUPER(sbi)->segment_count_nat + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat) << (sbi->log_blocks_per_seg - 1)));}
Quoted 98 lines
fsck/f2fs.h static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) · line 368
Quoted 3 lines
fsck/f2fs.h +0
-0@@ -367,7 +367,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) {int i;- if (addr >>= F2FS_RAW_SUPER(sbi)->block_count ||
Quoted 90 lines
fsck/f2fs.h +1
-0+if (le64_to_cpu (addr >=F2FS_RAW_SUPER (sbi)->block_count) || addr <SM_I (sbi)->main_blkaddr) {DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ;fsck/mount.c +0
-2@@ -1375,12 +1375,12 @@ void build_sit_area_bitmap(struct f2fs_sb_info *sbi) ptr +=SIT_VBLOCK_MAP_SIZE ;if (se->valid_blocks ==0x0 ) { - if (sbi->ckpt->cur_node_segno[0] == segno || -sbi->ckpt->cur_data_segno[0] == segno ||
-
sbi->ckpt->cur_node_segno[1] == segno ||
-
sbi->ckpt->cur_data_segno[1] == segno ||
-
sbi->ckpt->cur_node_segno[2] == segno ||
-
sbi->ckpt->cur_data_segno[2] == segno) {
+ if
(le32_to_cpu(sbi->ckpt->cur_node_segno[0])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[0])== segno || +le32_to_cpu(sbi->ckpt->cur_node_segno[1])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[1])== segno || +le32_to_cpu(sbi->ckpt->cur_node_segno[2])== segno || +le32_to_cpu(sbi->ckpt->cur_data_segno[2]) == segno) { continue; } else { free_segs++;fsck/node.c +1
-1@@ -78,7 +78,7 @@ block_t new_node_block(struct f2fs_sb_info *sbi, type =CURSEG_COLD_NODE ;if (IS_DNODE (node_blk)) { -if (S_ISDIR (f2fs_inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (f2fs_inode->i.i_mode))) type =CURSEG_HOT_NODE ;else type =CURSEG_WARM_NODE ;fsck/segment.c +2
-1@@ -80,7 +80,8 @@ static void f2fs_write_block(struct f2fs_sb_info *sbi, nid_t ino, void *buffer, ret =dev_read_block (inode, ni.blk_addr);ASSERT (ret >=0 ); -if (S_ISDIR (inode->i.i_mode) ||S_ISLNK (inode->i.i_mode)) +if (S_ISDIR (le16_to_cpu (inode->i.i_mode)) || +S_ISLNK (le16_to_cpu (inode->i.i_mode)))ASSERT (0 ); off_in_block = offset & ((1 <<F2FS_BLKSIZE_BITS ) -1 );include/f2fs_fs.h +5
-3@@ -170,15 +170,17 @@ static inline uint64_t bswap_64(uint64_t val)#define DISP_u32 (ptr, member) do {assert (sizeof ((ptr)->member) <=4 ); - printf("%-30s" "\t\t[0x%8x : %u]\n", \ - #member, ((ptr)->member), ((ptr)->member)); + printf("%-30s" "\t\t[0x%8x : %u]\n", + #member, le32_to_cpu(((ptr)->member)), +le32_to_cpu (((ptr)->member))); } while (0)#define DISP_u64 (ptr, member) do {assert (sizeof ((ptr)->member) ==8 ); printf("%-30s" "\t\t[0x%8llx : %llu]\n", - #member, ((ptr)->member), ((ptr)->member)); + #member, le64_to_cpu(((ptr)->member)), +le64_to_cpu (((ptr)->member))); } while (0)#define DISP_utf (ptr, member)
------------------------------------------------------------------------------