[f2fs-dev] [PATCH 1/2] lib, mkfs: fix endian conversion for crc calculation

2013-06-19 Thread Jaegeuk Kim
From 860da681961e6891d625abffa02d6df7dea4f5b2 Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim jaegeuk@samsung.com
Date: Wed, 19 Jun 2013 20:49:47 +0900
Subject: [PATCH 1/2] lib, mkfs: fix endian conversion for crc calculation
Cc: linux-fsde...@vger.kernel.org, linux-ker...@vger.kernel.org, 
linux-f2fs-devel@lists.sourceforge.net

Let's store the crc value for the checkpoint blocks with __le32.

Signed-off-by: Jaegeuk Kim jaegeuk@samsung.com
---
 include/f2fs_fs.h  |  1 +
 mkfs/f2fs_format.c | 19 ---
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index b4ac876..ad10815 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -124,6 +124,7 @@
 #define PAGE_CACHE_SIZE4096
 #define BITS_PER_BYTE  8
 #define F2FS_SUPER_MAGIC   0xF2F52010  /* F2FS Magic Number */
+#define CHECKSUM_OFFSET4092
 
 /* for mkfs */
 #define F2FS_MIN_VOLUME_SIZE   104857600
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 8e49ed4..9115520 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -525,7 +525,7 @@ static int f2fs_write_check_point_pack(void)
}
 
/* 1. cp page 1 of checkpoint pack 1 */
-   ckp-checkpoint_ver = 1;
+   ckp-checkpoint_ver = cpu_to_le64(1);
ckp-cur_node_segno[0] =
cpu_to_le32(config.cur_seg[CURSEG_HOT_NODE]);
ckp-cur_node_segno[1] =
@@ -578,12 +578,11 @@ static int f2fs_write_check_point_pack(void)
((le32_to_cpu(super_block.segment_count_nat) / 2) 
 le32_to_cpu(super_block.log_blocks_per_seg)) / 8);
 
-   ckp-checksum_offset = cpu_to_le32(4092);
+   ckp-checksum_offset = cpu_to_le32(CHECKSUM_OFFSET);
 
-   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp,
-   le32_to_cpu(ckp-checksum_offset));
-   *((u_int32_t *)((unsigned char *)ckp +
-   le32_to_cpu(ckp-checksum_offset))) = crc;
+   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET);
+   *((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) =
+   cpu_to_le32(crc);
 
blk_size_bytes = 1  le32_to_cpu(super_block.log_blocksize);
cp_seg_blk_offset = le32_to_cpu(super_block.segment0_blkaddr);
@@ -690,11 +689,9 @@ static int f2fs_write_check_point_pack(void)
 */
ckp-checkpoint_ver = 0;
 
-   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp,
-   le32_to_cpu(ckp-checksum_offset));
-   *((u_int32_t *)((unsigned char *)ckp +
-   le32_to_cpu(ckp-checksum_offset))) = crc;
-
+   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET);
+   *((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) =
+   cpu_to_le32(crc);
cp_seg_blk_offset = (le32_to_cpu(super_block.segment0_blkaddr) +
config.blks_per_seg) *
blk_size_bytes;
-- 
1.8.3.1.437.g0dbd812



-- 
Jaegeuk Kim
Samsung


--
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: fix crc endian conversion

2013-06-19 Thread Jaegeuk Kim
From ed1e92d596f5356ff2f8f8af2818d36ca31f5cf1 Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim jaegeuk@samsung.com
Date: Wed, 19 Jun 2013 20:47:19 +0900
Subject: [PATCH] f2fs: fix crc endian conversion
Cc: linux-fsde...@vger.kernel.org, linux-ker...@vger.kernel.org, 
linux-f2fs-devel@lists.sourceforge.net

While calculating CRC for the checkpoint block, we use __u32, but when storing
the crc value to the disk, we use __le32.

Let's fix the inconsistency.

Signed-off-by: Jaegeuk Kim jaegeuk@samsung.com
---
 fs/f2fs/checkpoint.c | 12 ++--
 fs/f2fs/f2fs.h   | 19 +++
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 9a77509..66a6b85 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
unsigned long blk_size = sbi-blocksize;
struct f2fs_checkpoint *cp_block;
unsigned long long cur_version = 0, pre_version = 0;
-   unsigned int crc = 0;
size_t crc_offset;
+   __u32 crc = 0;
 
/* Read the 1st cp block in this CP pack */
cp_page_1 = get_meta_page(sbi, cp_addr);
@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
if (crc_offset = blk_size)
goto invalid_cp1;
 
-   crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
+   crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
goto invalid_cp1;
 
@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
if (crc_offset = blk_size)
goto invalid_cp2;
 
-   crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
+   crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
goto invalid_cp2;
 
@@ -648,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool 
is_umount)
block_t start_blk;
struct page *cp_page;
unsigned int data_sum_blocks, orphan_blocks;
-   unsigned int crc32 = 0;
+   __u32 crc32 = 0;
void *kaddr;
int i;
 
@@ -717,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool 
is_umount)
get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
 
crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt-checksum_offset));
-   *(__le32 *)((unsigned char *)ckpt +
-   le32_to_cpu(ckpt-checksum_offset))
+   *((__le32 *)((unsigned char *)ckpt +
+   le32_to_cpu(ckpt-checksum_offset)))
= cpu_to_le32(crc32);
 
start_blk = __start_cp_addr(sbi);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 863a5e91..467d42d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -47,14 +47,25 @@ struct f2fs_mount_info {
unsigned intopt;
 };
 
-static inline __u32 f2fs_crc32(void *buff, size_t len)
+#define CRCPOLY_LE 0xedb88320
+
+static inline __u32 f2fs_crc32(void *buf, size_t len)
 {
-   return crc32_le(F2FS_SUPER_MAGIC, buff, len);
+   unsigned char *p = (unsigned char *)buf;
+   __u32 crc = F2FS_SUPER_MAGIC;
+   int i;
+
+   while (len--) {
+   crc ^= *p++;
+   for (i = 0; i  8; i++)
+   crc = (crc  1) ^ ((crc  1) ? CRCPOLY_LE : 0);
+   }
+   return crc;
 }
 
-static inline bool f2fs_crc_valid(__u32 blk_crc, void *buff, size_t buff_size)
+static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size)
 {
-   return f2fs_crc32(buff, buff_size) == blk_crc;
+   return f2fs_crc32(buf, buf_size) == blk_crc;
 }
 
 /*
-- 
1.8.3.1.437.g0dbd812



-- 
Jaegeuk Kim
Samsung


--
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] Kernel BUG when writing to f2fs drive, PowerPC, SD card, USB3

2013-06-19 Thread Oded Gabbay
Hi,

I tried your patches and they seem to work :)
I fixed umount flag yesterday but the CRC was the keypoint. Thanks.
I will now stress-test the SD card on my board and let you know the results.

Best regards,
Oded

On 06/19/2013 03:43 PM, Jaegeuk Kim wrote:
 Hi,
 Could you test the following three patches sent right after this email?

 For f2fs-tools:
   1. store crc as __le32
   2. store checkpoint flags as __le32

 For f2fs:
   1. handle crc as __le32

 I suspect that:
 1. mount failure is able to be occurred due to the crc endian error.
 2. update_sit_entry bug_on is caused by the endian problem on the
 checkpoint flags.

 If wrong checkpoint flag is got at mount time, we cannot build the
 latest sit entries correctly.

 Thanks,

 2013-06-18 (화), 15:10 +0300, Oded Gabbay:
 Hi,

 I printed also the segment no. and it appears that every time that
 segment 187 is written to, which is assigned to the HOT data, the
 system crashes.
 BTW, even if I just do echo oded  /mnt/file and then just wait for
 about 30-45 seconds, the crash occurs

 I got the following prints when I did the echo thing:

 REMOVE_ME update_sit_entry(202):
 offset = 0, segoff = 3584, blkaddr = 4096, segno = 0
 REMOVE_ME update_sit_entry(202):
 offset = 1, segoff = 99329, blkaddr = 99841, segno = 187
 REMOVE_ME update_sit_entry(202):
 offset = 0, segoff = 99328, blkaddr = 99840, segno = 187
 [ cut here ]
 kernel BUG
 at 
 /home/ogabbay/views/r5.xcj/software/os-software/powerpc/usr/src/linux-3.9.6-adva/fs/f2fs/segment.c:217!

 Here is the print from the debugfs. You can see segment 187 is
 allocated to HOT data:

 [cj:~] # cat /sys/kernel/debug/f2fs/status

 =[ partition info(loop0). #0 ]=
 [SB: 1] [CP: 2] [SIT: 2] [NAT: 2] [SSA: 1] [MAIN: 192(OverProv:55
 Resv:48)]

 Utilization: 0% (4 valid blocks)
- Node: 2 (Inode: 2, Other: 0)
- Data: 2

 Main area: 192 segs, 192 secs 192 zones
- COLD  data: 0, 0, 0
- WARM  data: 1, 1, 1
- HOT   data: 187, 187, 187
- Dir   dnode: 190, 190, 190
- File   dnode: 189, 189, 189
- Indir nodes: 188, 188, 188

- Valid: 6
- Dirty: 0
- Prefree: 0
- Free: 186 (186)

 GC calls: 0 (BG: 0)
- data segments : 0
- node segments : 0
 Try to move 0 blocks
- data blocks : 0
- node blocks : 0

 Extent Hit Ratio: 0 / 0

 Balancing F2FS Async:
- nodes1 in2
- dents1 in dirs:   1
- meta0 in   21
- NATs 2  29120
- SITs: 0
- free_nids:  2270

 Distribution of User Blocks: [ valid | invalid | free ]
[|---|---]

 SSR: 0 blocks in 0 segments
 LFS: 0 blocks in 0 segments

 BDF: 100, avg. vblocks: 0

 Memory: 154 KB = static: 60 + cached: 94


 On 06/18/2013 12:44 PM, Oded Gabbay wrote:

 Hi,

 I would like to share additional information I have from pr_err I
 put into the update_sit_entry function.

 The following is the printout from the terminal. This is only the
 end of the printout. The start was with segoff = 3584 and it went
 sequentially up until 9215, where then it jumped to 99329 and after
 that 99328 - which is the entry that caused the crash.
 Each time I repeated the experiment I got exactly the same results.

 I put the pr_err after the line: offset = GET_SEGOFF_FROM_SEG0(sbi,
 blkaddr)  (sbi-blocks_per_seg - 1);
 where segoff = GET_SEGOFF_FROM_SEG0(sbi, blkaddr)

 Hope this helps.

 REMOVE_ME update_sit_entry(202): offset = 0, segoff = 3584,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 1, segoff = 3585,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 2, segoff = 3586,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 3, segoff = 3587,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 4, segoff = 3588,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 5, segoff = 3589,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 6, segoff = 3590,
 sbi-blocks_per_seg = 512
 :::
 REMOVE_ME update_sit_entry(202): offset = 502, segoff = 9206,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 503, segoff = 9207,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 504, segoff = 9208,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 505, segoff = 9209,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 506, segoff = 9210,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 507, segoff = 9211,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 508, segoff = 9212,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 509, segoff = 9213,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 510, segoff = 9214,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 511, segoff = 9215,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 1, segoff = 99329,
 

Re: [f2fs-dev] Kernel BUG when writing to f2fs drive, PowerPC, SD card, USB3

2013-06-19 Thread Oded Gabbay
Hi,

After stress-testing the F2FS on SD card and iNAND, and doing multiple 
mounts/umounts, I believe I can say the fix is working for the powerpc.

Thanks for all the help

Oded.
On 06/19/2013 03:43 PM, Jaegeuk Kim wrote:
 Hi,
 Could you test the following three patches sent right after this email?

 For f2fs-tools:
   1. store crc as __le32
   2. store checkpoint flags as __le32

 For f2fs:
   1. handle crc as __le32

 I suspect that:
 1. mount failure is able to be occurred due to the crc endian error.
 2. update_sit_entry bug_on is caused by the endian problem on the
 checkpoint flags.

 If wrong checkpoint flag is got at mount time, we cannot build the
 latest sit entries correctly.

 Thanks,

 2013-06-18 (화), 15:10 +0300, Oded Gabbay:
 Hi,

 I printed also the segment no. and it appears that every time that
 segment 187 is written to, which is assigned to the HOT data, the
 system crashes.
 BTW, even if I just do echo oded  /mnt/file and then just wait for
 about 30-45 seconds, the crash occurs

 I got the following prints when I did the echo thing:

 REMOVE_ME update_sit_entry(202):
 offset = 0, segoff = 3584, blkaddr = 4096, segno = 0
 REMOVE_ME update_sit_entry(202):
 offset = 1, segoff = 99329, blkaddr = 99841, segno = 187
 REMOVE_ME update_sit_entry(202):
 offset = 0, segoff = 99328, blkaddr = 99840, segno = 187
 [ cut here ]
 kernel BUG
 at 
 /home/ogabbay/views/r5.xcj/software/os-software/powerpc/usr/src/linux-3.9.6-adva/fs/f2fs/segment.c:217!

 Here is the print from the debugfs. You can see segment 187 is
 allocated to HOT data:

 [cj:~] # cat /sys/kernel/debug/f2fs/status

 =[ partition info(loop0). #0 ]=
 [SB: 1] [CP: 2] [SIT: 2] [NAT: 2] [SSA: 1] [MAIN: 192(OverProv:55
 Resv:48)]

 Utilization: 0% (4 valid blocks)
- Node: 2 (Inode: 2, Other: 0)
- Data: 2

 Main area: 192 segs, 192 secs 192 zones
- COLD  data: 0, 0, 0
- WARM  data: 1, 1, 1
- HOT   data: 187, 187, 187
- Dir   dnode: 190, 190, 190
- File   dnode: 189, 189, 189
- Indir nodes: 188, 188, 188

- Valid: 6
- Dirty: 0
- Prefree: 0
- Free: 186 (186)

 GC calls: 0 (BG: 0)
- data segments : 0
- node segments : 0
 Try to move 0 blocks
- data blocks : 0
- node blocks : 0

 Extent Hit Ratio: 0 / 0

 Balancing F2FS Async:
- nodes1 in2
- dents1 in dirs:   1
- meta0 in   21
- NATs 2  29120
- SITs: 0
- free_nids:  2270

 Distribution of User Blocks: [ valid | invalid | free ]
[|---|---]

 SSR: 0 blocks in 0 segments
 LFS: 0 blocks in 0 segments

 BDF: 100, avg. vblocks: 0

 Memory: 154 KB = static: 60 + cached: 94


 On 06/18/2013 12:44 PM, Oded Gabbay wrote:

 Hi,

 I would like to share additional information I have from pr_err I
 put into the update_sit_entry function.

 The following is the printout from the terminal. This is only the
 end of the printout. The start was with segoff = 3584 and it went
 sequentially up until 9215, where then it jumped to 99329 and after
 that 99328 - which is the entry that caused the crash.
 Each time I repeated the experiment I got exactly the same results.

 I put the pr_err after the line: offset = GET_SEGOFF_FROM_SEG0(sbi,
 blkaddr)  (sbi-blocks_per_seg - 1);
 where segoff = GET_SEGOFF_FROM_SEG0(sbi, blkaddr)

 Hope this helps.

 REMOVE_ME update_sit_entry(202): offset = 0, segoff = 3584,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 1, segoff = 3585,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 2, segoff = 3586,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 3, segoff = 3587,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 4, segoff = 3588,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 5, segoff = 3589,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 6, segoff = 3590,
 sbi-blocks_per_seg = 512
 :::
 REMOVE_ME update_sit_entry(202): offset = 502, segoff = 9206,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 503, segoff = 9207,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 504, segoff = 9208,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 505, segoff = 9209,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 506, segoff = 9210,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 507, segoff = 9211,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 508, segoff = 9212,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 509, segoff = 9213,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 510, segoff = 9214,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 511, segoff = 9215,
 sbi-blocks_per_seg = 512
 REMOVE_ME update_sit_entry(202): offset = 1, segoff = 99329,
 sbi-blocks_per_seg = 512
 REMOVE_ME