Re: [f2fs-dev] [PATCH 5/5] fsck.f2fs: try to recover cp_payload from valid cp pack

2018-09-19 Thread Junling Zheng
On 2018/9/20 7:38, Jaegeuk Kim wrote:
> On 09/19, Junling Zheng wrote:
>> From: Chao Yu 
>>
>> If sb checksum is not enabled, and cp pack is valid due to no
>> crc inconsistence, let's try to recover cp_payload based on
>> cp_pack_start_sum in cp pack.
>>
>> Signed-off-by: Chao Yu 
>> ---
>>  fsck/f2fs.h  |  5 +
>>  fsck/mount.c | 10 +++---
>>  2 files changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/fsck/f2fs.h b/fsck/f2fs.h
>> index d216444..0d0d5e2 100644
>> --- a/fsck/f2fs.h
>> +++ b/fsck/f2fs.h
>> @@ -259,6 +259,11 @@ static inline unsigned long __bitmap_size(struct 
>> f2fs_sb_info *sbi, int flag)
>>  return 0;
>>  }
>>  
>> +static inline block_t __cp_payload(struct f2fs_sb_info *sbi)
>> +{
>> +return le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
>> +}
>> +
>>  static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
>>  {
>>  struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
>> diff --git a/fsck/mount.c b/fsck/mount.c
>> index 9019921..0e8fa41 100644
>> --- a/fsck/mount.c
>> +++ b/fsck/mount.c
>> @@ -975,12 +975,16 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
>>  }
>>  
>>  cp_pack_start_sum = __start_sum_addr(sbi);
>> -cp_payload = get_sb(cp_payload);
>> +cp_payload = __cp_payload(sbi);
>>  if (cp_pack_start_sum < cp_payload + 1 ||
>>  cp_pack_start_sum > blocks_per_seg - 1 -
>>  NR_CURSEG_TYPE) {
>> -MSG(0, "\tWrong cp_pack_start_sum(%u)\n", cp_pack_start_sum);
>> -return 1;
>> +MSG(0, "\tWrong cp_pack_start_sum(%u) or cp_payload(%u)\n",
>> +cp_pack_start_sum, cp_payload);
>> +if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM))
>> +return 1;
> 
> Is this trying to fix superblock? Why is it related to SB_CHKSUM?
> 

If sb_checksum is enabled, we should not try to fix superblock.
In this situation, both sb and cp are verified with crc, so we
don't know which one, cp_payload or cp_pack_start_sum, is the
exact one.

By contraries, if sb_checksum is disabled, we could try to fix
superblock as below :)

>> +set_sb(cp_payload, cp_pack_start_sum - 1);
>> +update_superblock(sb, SB_ALL);
>>  }
>>  >>  return 0;
>> -- 
>> 2.19.0
> 
> .
> 




___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 4/5] f2fs-tools: introduce sb checksum

2018-09-19 Thread Junling Zheng
Hi, Jaegeuk

On 2018/9/20 7:35, Jaegeuk Kim wrote:
> On 09/19, Junling Zheng wrote:
>> This patch introduced crc for superblock.
>>
>> Signed-off-by: Junling Zheng 
>> ---
>>  fsck/mount.c   | 33 +
>>  fsck/resize.c  | 12 ++--
>>  include/f2fs_fs.h  |  6 +-
>>  mkfs/f2fs_format.c |  8 
>>  4 files changed, 52 insertions(+), 7 deletions(-)
>>
>> diff --git a/fsck/mount.c b/fsck/mount.c
>> index 74ff7c6..9019921 100644
>> --- a/fsck/mount.c
>> +++ b/fsck/mount.c
>> @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb)
>>  DISP_u32(sb, node_ino);
>>  DISP_u32(sb, meta_ino);
>>  DISP_u32(sb, cp_payload);
>> +DISP_u32(sb, crc);
>>  DISP("%-.256s", sb, version);
>>  printf("\n");
>>  }
>> @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb)
>>  if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
>>  MSG(0, "%s", " lost_found");
>>  }
>> +if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) {
>> +MSG(0, "%s", " sb_checksum");
>> +}
>>  MSG(0, "\n");
>>  MSG(0, "Info: superblock encrypt level = %d, salt = ",
>>  sb->encryption_level);
>> @@ -479,10 +483,20 @@ void update_superblock(struct f2fs_super_block *sb, 
>> int sb_mask)
>>  {
>>  int index, ret;
>>  u_int8_t *buf;
>> +u32 old_crc, new_crc;
>>  
>>  buf = calloc(BLOCK_SZ, 1);
>>  ASSERT(buf);
>>  
>> +if (get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) {
>> +old_crc = get_sb(crc);
>> +new_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, sb,
>> +SB_CHKSUM_OFFSET);
>> +set_sb(crc, new_crc);
>> +MSG(1, "Info: SB CRC is updated (0x%x -> 0x%x)\n",
>> +old_crc, new_crc);
>> +}
>> +
>>  memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb));
>>  for (index = 0; index < SB_ADDR_MAX; index++) {
>>  if ((1 << index) & sb_mask) {
>> @@ -575,10 +589,29 @@ static inline int sanity_check_area_boundary(struct 
>> f2fs_super_block *sb,
>>  return 0;
>>  }
>>  
>> +static int verify_sb_chksum(struct f2fs_super_block *sb)
>> +{
>> +if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) {
>> +MSG(0, "\tInvalid SB CRC offset: %u\n",
>> +get_sb(checksum_offset));
>> +return -1;
>> +}
>> +if (f2fs_crc_valid(get_sb(crc), sb,
>> +get_sb(checksum_offset))) {
>> +MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc));
>> +return -1;
>> +}
>> +return 0;
>> +}
>> +
>>  int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR 
>> sb_addr)
>>  {
>>  unsigned int blocksize;
>>  
>> +if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) &&
>> +verify_sb_chksum(sb))
>> +return -1;
>> +
>>  if (F2FS_SUPER_MAGIC != get_sb(magic))
>>  return -1;
>>  
>> diff --git a/fsck/resize.c b/fsck/resize.c
>> index 5161a1f..3462165 100644
>> --- a/fsck/resize.c
>> +++ b/fsck/resize.c
>> @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
>>  }
>>  }
>>  
>> -print_raw_sb_info(sb);
>> -print_raw_sb_info(new_sb);
> 
> It'd be worth to keep this to show the previous states.
> 

Here, I just want to move the printing of sb and new_sb to the place
behind update_superblock(), where the crc in sb will be updated.

>> -
>>  old_main_blkaddr = get_sb(main_blkaddr);
>>  new_main_blkaddr = get_newsb(main_blkaddr);
>>  offset = new_main_blkaddr - old_main_blkaddr;
>> @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
>>  migrate_sit(sbi, new_sb, offset_seg);
>>  rebuild_checkpoint(sbi, new_sb, offset_seg);
>>  update_superblock(new_sb, SB_ALL);
>> +print_raw_sb_info(sb);
>> +print_raw_sb_info(new_sb);
>> +
>>  return 0;
>>  }
>>  
>> @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
>>  }
>>  }
>>  
>> -print_raw_sb_info(sb);
>> -print_raw_sb_info(new_sb);
> 
> Ditto.
> 
>> -
>>  old_main_blkaddr = get_sb(main_blkaddr);
>>  new_main_blkaddr = get_newsb(main_blkaddr);
>>  offset = old_main_blkaddr - new_main_blkaddr;
>> @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
>>  /* move whole data region */
>>  //if (err)
>>  //  migrate_main(sbi, offset);
>> +print_raw_sb_info(sb);
>> +print_raw_sb_info(new_sb);
>> +
>>  return 0;
>>  }
>>  
>> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
>> index 38a0da4..f80632a 100644
>> --- a/include/f2fs_fs.h
>> +++ b/include/f2fs_fs.h
>> @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val)
>>  #define BITS_PER_BYTE   8
>>  #define F2FS_SUPER_MAGIC0xF2F52010  /* F2FS Magic Number */
>>  

Re: [f2fs-dev] [PATCH] f2fs: remove default option setting in remount

2018-09-19 Thread cgxu519

On 9/19/18 10:02 PM, Chao Yu wrote:

On 2018/9/18 21:47, cgxu519 wrote:

On 09/18/2018 09:20 PM, Chao Yu wrote:

On 2018/9/18 14:23, Chengguang Xu wrote:

Currently we set default value to options before parsing remount options,
it will cause unexpected change of options which were specified in first
mount.

Can you check below commit? It looks w/o it we may lose default option after
remount.

498c5e9fcd10 ("f2fs: add default mount options to remount")

Hi Chao,

Hi Chengguang,


It looks like there was a bug in remount at that time, but I think the fix above
is not correct.

from the patch '498c5e9fcd10', I think it was caused by clearing
sbi->mount_opt.opt before

parsing. I think remount should not change the options which were specified by
user in

previous mount unless user specifies in remount.

Can you check description in manual of mount.

IIRC, old mount option will be record into /etc/mtab or /proc/mounts (for
adapting namespace feature), with command of "mount -o remount,rw  /dir", old
mount options can be loaded from above config file, and merge them with new
specified options.

Even we kill old mount options by call default_options() in ->remount, user's
old mount option can still be set through parameters.


Please let me show you different behaviors before/after this patch.


[root@x201 cgxu]# uname -a
Linux x201 4.19.0-rc2+ #51 SMP Wed Sep 19 22:41:20 CST 2018 x86_64 
x86_64 x86_64 GNU/Linux



Before:

[root@x201 cgxu]# mount -o fsync_mode=strict /dev/mapper/test-test1 
/mnt/test/test1

[root@x201 cgxu]# mount | grep test1
/dev/mapper/test-test1 on /mnt/test/test1 type f2fs 
(rw,relatime,lazytime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=strict)


[root@x201 cgxu]# mount -o remount,background_gc=sync 
/dev/mapper/test-test1 /mnt/test/test1

[root@x201 cgxu]# mount | grep test1
/dev/mapper/test-test1 on /mnt/test/test1 type f2fs 
(rw,relatime,background_gc=sync,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=default,fsync_mode=posix)



I only changed background_gc in ->remount, but fsync_mode is implicitly 
set to default value 'posix'.


After:

[root@x201 linus]# mount -o fsync_mode=strict /dev/mapper/test-test1 
/mnt/test/test1

[root@x201 linus]# mount | grep test1
/dev/mapper/test-test1 on /mnt/test/test1 type f2fs 
(rw,relatime,lazytime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=strict)


[root@x201 linus]# mount -o remount,background_gc=sync 
/dev/mapper/test-test1 /mnt/test/test1

[root@x201 linus]# mount | grep test1
/dev/mapper/test-test1 on /mnt/test/test1 type f2fs 
(rw,relatime,background_gc=sync,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=strict)


This time fysnc_mode looks fine.



But the problem here is, some old parameter can be configured via sysfs, if we
reset them in default_options(), we will lose them forever after remount.

If you have no other opinion about this, could you adapt your commit log?




___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 5/5] fsck.f2fs: try to recover cp_payload from valid cp pack

2018-09-19 Thread Jaegeuk Kim
On 09/19, Junling Zheng wrote:
> From: Chao Yu 
> 
> If sb checksum is not enabled, and cp pack is valid due to no
> crc inconsistence, let's try to recover cp_payload based on
> cp_pack_start_sum in cp pack.
> 
> Signed-off-by: Chao Yu 
> ---
>  fsck/f2fs.h  |  5 +
>  fsck/mount.c | 10 +++---
>  2 files changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/fsck/f2fs.h b/fsck/f2fs.h
> index d216444..0d0d5e2 100644
> --- a/fsck/f2fs.h
> +++ b/fsck/f2fs.h
> @@ -259,6 +259,11 @@ static inline unsigned long __bitmap_size(struct 
> f2fs_sb_info *sbi, int flag)
>   return 0;
>  }
>  
> +static inline block_t __cp_payload(struct f2fs_sb_info *sbi)
> +{
> + return le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
> +}
> +
>  static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
>  {
>   struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 9019921..0e8fa41 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -975,12 +975,16 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
>   }
>  
>   cp_pack_start_sum = __start_sum_addr(sbi);
> - cp_payload = get_sb(cp_payload);
> + cp_payload = __cp_payload(sbi);
>   if (cp_pack_start_sum < cp_payload + 1 ||
>   cp_pack_start_sum > blocks_per_seg - 1 -
>   NR_CURSEG_TYPE) {
> - MSG(0, "\tWrong cp_pack_start_sum(%u)\n", cp_pack_start_sum);
> - return 1;
> + MSG(0, "\tWrong cp_pack_start_sum(%u) or cp_payload(%u)\n",
> + cp_pack_start_sum, cp_payload);
> + if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM))
> + return 1;

Is this trying to fix superblock? Why is it related to SB_CHKSUM?

> + set_sb(cp_payload, cp_pack_start_sum - 1);
> + update_superblock(sb, SB_ALL);
>   }
>  
>   return 0;
> -- 
> 2.19.0


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 4/5] f2fs-tools: introduce sb checksum

2018-09-19 Thread Jaegeuk Kim
On 09/19, Junling Zheng wrote:
> This patch introduced crc for superblock.
> 
> Signed-off-by: Junling Zheng 
> ---
>  fsck/mount.c   | 33 +
>  fsck/resize.c  | 12 ++--
>  include/f2fs_fs.h  |  6 +-
>  mkfs/f2fs_format.c |  8 
>  4 files changed, 52 insertions(+), 7 deletions(-)
> 
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 74ff7c6..9019921 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb)
>   DISP_u32(sb, node_ino);
>   DISP_u32(sb, meta_ino);
>   DISP_u32(sb, cp_payload);
> + DISP_u32(sb, crc);
>   DISP("%-.256s", sb, version);
>   printf("\n");
>  }
> @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb)
>   if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
>   MSG(0, "%s", " lost_found");
>   }
> + if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) {
> + MSG(0, "%s", " sb_checksum");
> + }
>   MSG(0, "\n");
>   MSG(0, "Info: superblock encrypt level = %d, salt = ",
>   sb->encryption_level);
> @@ -479,10 +483,20 @@ void update_superblock(struct f2fs_super_block *sb, int 
> sb_mask)
>  {
>   int index, ret;
>   u_int8_t *buf;
> + u32 old_crc, new_crc;
>  
>   buf = calloc(BLOCK_SZ, 1);
>   ASSERT(buf);
>  
> + if (get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) {
> + old_crc = get_sb(crc);
> + new_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, sb,
> + SB_CHKSUM_OFFSET);
> + set_sb(crc, new_crc);
> + MSG(1, "Info: SB CRC is updated (0x%x -> 0x%x)\n",
> + old_crc, new_crc);
> + }
> +
>   memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb));
>   for (index = 0; index < SB_ADDR_MAX; index++) {
>   if ((1 << index) & sb_mask) {
> @@ -575,10 +589,29 @@ static inline int sanity_check_area_boundary(struct 
> f2fs_super_block *sb,
>   return 0;
>  }
>  
> +static int verify_sb_chksum(struct f2fs_super_block *sb)
> +{
> + if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) {
> + MSG(0, "\tInvalid SB CRC offset: %u\n",
> + get_sb(checksum_offset));
> + return -1;
> + }
> + if (f2fs_crc_valid(get_sb(crc), sb,
> + get_sb(checksum_offset))) {
> + MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc));
> + return -1;
> + }
> + return 0;
> +}
> +
>  int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
>  {
>   unsigned int blocksize;
>  
> + if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) &&
> + verify_sb_chksum(sb))
> + return -1;
> +
>   if (F2FS_SUPER_MAGIC != get_sb(magic))
>   return -1;
>  
> diff --git a/fsck/resize.c b/fsck/resize.c
> index 5161a1f..3462165 100644
> --- a/fsck/resize.c
> +++ b/fsck/resize.c
> @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
>   }
>   }
>  
> - print_raw_sb_info(sb);
> - print_raw_sb_info(new_sb);

It'd be worth to keep this to show the previous states.

> -
>   old_main_blkaddr = get_sb(main_blkaddr);
>   new_main_blkaddr = get_newsb(main_blkaddr);
>   offset = new_main_blkaddr - old_main_blkaddr;
> @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
>   migrate_sit(sbi, new_sb, offset_seg);
>   rebuild_checkpoint(sbi, new_sb, offset_seg);
>   update_superblock(new_sb, SB_ALL);
> + print_raw_sb_info(sb);
> + print_raw_sb_info(new_sb);
> +
>   return 0;
>  }
>  
> @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
>   }
>   }
>  
> - print_raw_sb_info(sb);
> - print_raw_sb_info(new_sb);

Ditto.

> -
>   old_main_blkaddr = get_sb(main_blkaddr);
>   new_main_blkaddr = get_newsb(main_blkaddr);
>   offset = old_main_blkaddr - new_main_blkaddr;
> @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
>   /* move whole data region */
>   //if (err)
>   //  migrate_main(sbi, offset);
> + print_raw_sb_info(sb);
> + print_raw_sb_info(new_sb);
> +
>   return 0;
>  }
>  
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index 38a0da4..f80632a 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val)
>  #define BITS_PER_BYTE8
>  #define F2FS_SUPER_MAGIC 0xF2F52010  /* F2FS Magic Number */
>  #define CP_CHKSUM_OFFSET 4092
> +#define SB_CHKSUM_OFFSET 3068
>  #define MAX_PATH_LEN 64
>  #define MAX_DEVICES  8
>  
> @@ -579,6 +580,7 @@ enum {
>  #define F2FS_FEATURE_INODE_CRTIME0x0100
>  #define F2FS_FEATURE_LOST_FOUND 

Re: [f2fs-dev] [PATCH 3/5] fsck.f2fs: unify the updating of superblocks

2018-09-19 Thread Jaegeuk Kim
On 09/19, Junling Zheng wrote:
> Rename write_superblock() to update_superblock() and make it support updating
> specified one superblock or both two superblocks, then unify all places where
> sb needs to be updated.
> 
> Signed-off-by: Junling Zheng 
> ---
>  fsck/fsck.h   | 12 ++-
>  fsck/mount.c  | 94 +++
>  fsck/resize.c | 20 ++-
>  3 files changed, 47 insertions(+), 79 deletions(-)
> 
> diff --git a/fsck/fsck.h b/fsck/fsck.h
> index 6042e68..bdd7f8d 100644
> --- a/fsck/fsck.h
> +++ b/fsck/fsck.h
> @@ -32,6 +32,16 @@ enum {
>   EUNKNOWN_ARG,
>  };
>  
> +enum SB_ADDR {
> + SB_ADDR_0,
> + SB_ADDR_1,
> + SB_ADDR_MAX,

SB0_ADDR = 0,
SB1_ADDR,
SB_MAX_ADDR,

> +};
> +

#define SB_MASK(i)  (1 << i)
#define SB_MASK_ALL (SB_MASK(SB0_ADDR) | SB_MASK(SB1_ADDR))

> +#define SB_FIRST (1 << SB_ADDR_0)
> +#define SB_SECOND(1 << SB_ADDR_1)
> +#define SB_ALL   (SB_FIRST | SB_SECOND)
> +
>  /* fsck.c */
>  struct orphan_info {
>   u32 nr_inodes;
> @@ -178,7 +188,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, 
> int);
>  extern void write_curseg_info(struct f2fs_sb_info *);
>  extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int);
>  extern void write_checkpoint(struct f2fs_sb_info *);
> -extern void write_superblock(struct f2fs_super_block *);
> +extern void update_superblock(struct f2fs_super_block *, int);
>  extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t);
>  extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t);
>  
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 1daef75..74ff7c6 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -475,8 +475,28 @@ void print_sb_state(struct f2fs_super_block *sb)
>   MSG(0, "\n");
>  }
>  
> +void update_superblock(struct f2fs_super_block *sb, int sb_mask)
> +{
> + int index, ret;
> + u_int8_t *buf;
> +
> + buf = calloc(BLOCK_SZ, 1);
> + ASSERT(buf);
> +
> + memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb));
> + for (index = 0; index < SB_ADDR_MAX; index++) {

for (addr = SB0_ADDR; addr < SB_MAX_ADDR; addr++)

> + if ((1 << index) & sb_mask) {

if (SB_MASK(addr) & sb_mask) {

> + ret = dev_write_block(buf, index);
> + ASSERT(ret >= 0);
> + }
> + }
> +
> + free(buf);
> + DBG(0, "Info: Done to update superblock\n");
> +}
> +
>  static inline int sanity_check_area_boundary(struct f2fs_super_block *sb,
> - u64 offset)
> + enum SB_ADDR sb_addr)
>  {
>   u32 segment0_blkaddr = get_sb(segment0_blkaddr);
>   u32 cp_blkaddr = get_sb(cp_blkaddr);
> @@ -542,14 +562,11 @@ static inline int sanity_check_area_boundary(struct 
> f2fs_super_block *sb,
>   segment_count_main << log_blocks_per_seg);
>   return -1;
>   } else if (main_end_blkaddr < seg_end_blkaddr) {
> - int err;
> -
>   set_sb(segment_count, (main_end_blkaddr -
>   segment0_blkaddr) >> log_blocks_per_seg);
>  
> - err = dev_write(sb, offset, sizeof(struct f2fs_super_block));
> - MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n",
> - err ? "failed": "done",
> + update_superblock(sb, 1 << sb_addr);

update_superblock(sb, SB_MASK(sb_addr));

> + MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n",
>   main_blkaddr,
>   segment0_blkaddr +
>   (segment_count << log_blocks_per_seg),
> @@ -558,7 +575,7 @@ static inline int sanity_check_area_boundary(struct 
> f2fs_super_block *sb,
>   return 0;
>  }
>  
> -int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset)
> +int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
>  {
>   unsigned int blocksize;
>  
> @@ -600,30 +617,24 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, 
> u64 offset)
>   if (get_sb(segment_count) > F2FS_MAX_SEGMENT)
>   return -1;
>  
> - if (sanity_check_area_boundary(sb, offset))
> + if (sanity_check_area_boundary(sb, sb_addr))
>   return -1;
>   return 0;
>  }
>  
> -int validate_super_block(struct f2fs_sb_info *sbi, int block)
> +int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr)
>  {
> - u64 offset;
>   char buf[F2FS_BLKSIZE];
>  
>   sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
>  
> - if (block == 0)
> - offset = F2FS_SUPER_OFFSET;
> - else
> - offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET;
> -
> - if (dev_read_block(buf, block))
> + if (dev_read_block(buf, sb_addr))
>   return -1;
>  
>  

[f2fs-dev] [PATCH] f2fs: avoid infinite loop in f2fs_alloc_nid

2018-09-19 Thread Jaegeuk Kim
If we have an error in f2fs_build_free_nids, we're able to fall into a loop
to find free nids.

Suggested-by: Chao Yu 
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/node.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 79b6fee354f7..e24f8acbea82 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2356,8 +2356,9 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
spin_unlock(_i->nid_list_lock);
 
/* Let's scan nat pages and its caches to get free nids */
-   f2fs_build_free_nids(sbi, true, false);
-   goto retry;
+   if (!f2fs_build_free_nids(sbi, true, false))
+   goto retry;
+   return false;
 }
 
 /*
-- 
2.17.0.441.gb46fe60e1d-goog



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 2/2 v2] f2fs: avoid f2fs_bug_on if f2fs_get_meta_page_nofail got EIO

2018-09-19 Thread Jaegeuk Kim
On 09/19, Chao Yu wrote:
> On 2018/9/19 1:56, Jaegeuk Kim wrote:
> > This patch avoids BUG_ON when f2fs_get_meta_page_nofail got EIO during
> > xfstests/generic/475.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> > Change log from v1:
> >  - propagate errno
> >  - drop sum_pages
> > 
> >  fs/f2fs/checkpoint.c | 10 +-
> >  fs/f2fs/f2fs.h   |  2 +-
> >  fs/f2fs/gc.c |  9 +
> >  fs/f2fs/node.c   | 32 
> >  fs/f2fs/recovery.c   |  2 ++
> >  fs/f2fs/segment.c|  3 +++
> >  6 files changed, 44 insertions(+), 14 deletions(-)
> > 
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index 01e0d8f5bbbe..1ddf332ce4b2 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -119,11 +119,8 @@ struct page *f2fs_get_meta_page_nofail(struct 
> > f2fs_sb_info *sbi, pgoff_t index)
> > if (PTR_ERR(page) == -EIO &&
> > ++count <= DEFAULT_RETRY_IO_COUNT)
> > goto retry;
> > -
> > f2fs_stop_checkpoint(sbi, false);
> > -   f2fs_bug_on(sbi, 1);
> > }
> > -
> > return page;
> >  }
> >  
> > @@ -1512,7 +1509,10 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, 
> > struct cp_control *cpc)
> > ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver);
> >  
> > /* write cached NAT/SIT entries to NAT/SIT area */
> > -   f2fs_flush_nat_entries(sbi, cpc);
> > +   err = f2fs_flush_nat_entries(sbi, cpc);
> > +   if (err)
> > +   goto stop;
> > +
> > f2fs_flush_sit_entries(sbi, cpc);
> >  
> > /* unlock all the fs_lock[] in do_checkpoint() */
> > @@ -1521,7 +1521,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, 
> > struct cp_control *cpc)
> > f2fs_release_discard_addrs(sbi);
> > else
> > f2fs_clear_prefree_segments(sbi, cpc);
> > -
> > +stop:
> > unblock_operations(sbi);
> > stat_inc_cp_count(sbi->stat_info);
> >  
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index a0c868127a7c..29021dbc8f2a 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -2895,7 +2895,7 @@ int f2fs_recover_xattr_data(struct inode *inode, 
> > struct page *page);
> >  int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
> >  int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
> > unsigned int segno, struct f2fs_summary_block *sum);
> > -void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control 
> > *cpc);
> > +int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control 
> > *cpc);
> >  int f2fs_build_node_manager(struct f2fs_sb_info *sbi);
> >  void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi);
> >  int __init f2fs_create_node_manager_caches(void);
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index 4bcc8a59fdef..c7d14282dbf4 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -1070,6 +1070,15 @@ static int do_garbage_collect(struct f2fs_sb_info 
> > *sbi,
> > /* reference all summary page */
> > while (segno < end_segno) {
> > sum_page = f2fs_get_sum_page(sbi, segno++);
> > +   if (IS_ERR(sum_page)) {
> > +   end_segno = segno - 1;
> > +   for (segno = start_segno; segno < end_segno; segno++) {
> > +   sum_page = find_get_page(META_MAPPING(sbi),
> > +   GET_SUM_BLOCK(sbi, segno));
> > +   f2fs_put_page(sum_page, 0);
> > +   }
> > +   return PTR_ERR(sum_page);
> > +   }
> > unlock_page(sum_page);
> > }
> >  
> > diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> > index fa2381c0bc47..79b6fee354f7 100644
> > --- a/fs/f2fs/node.c
> > +++ b/fs/f2fs/node.c
> > @@ -126,6 +126,8 @@ static struct page *get_next_nat_page(struct 
> > f2fs_sb_info *sbi, nid_t nid)
> >  
> > /* get current nat block page with lock */
> > src_page = get_current_nat_page(sbi, nid);
> > +   if (IS_ERR(src_page))
> > +   return src_page;
> > dst_page = f2fs_grab_meta_page(sbi, dst_off);
> > f2fs_bug_on(sbi, PageDirty(src_page));
> >  
> > @@ -2265,15 +2267,19 @@ static int __f2fs_build_free_nids(struct 
> > f2fs_sb_info *sbi,
> > nm_i->nat_block_bitmap)) {
> > struct page *page = get_current_nat_page(sbi, nid);
> >  
> > -   ret = scan_nat_page(sbi, page, nid);
> > -   f2fs_put_page(page, 1);
> > +   if (IS_ERR(page)) {
> > +   ret = PTR_ERR(page);
> > +   } else {
> > +   ret = scan_nat_page(sbi, page, nid);
> > +   f2fs_put_page(page, 1);
> > +   }
> >  
> > if (ret) {
> > up_read(_i->nat_tree_lock);
> > f2fs_bug_on(sbi, !mount);
> >   

Re: [f2fs-dev] [PATCH] f2fs: fix quota info to adjust recovered data

2018-09-19 Thread Jaegeuk Kim
On 09/19, Chao Yu wrote:
> On 2018/9/19 0:45, Jaegeuk Kim wrote:
> > On 09/18, Chao Yu wrote:
> >> On 2018/9/18 10:05, Jaegeuk Kim wrote:
> >>> On 09/18, Chao Yu wrote:
>  On 2018/9/18 9:19, Jaegeuk Kim wrote:
> > On 09/13, Chao Yu wrote:
> >> On 2018/9/13 3:54, Jaegeuk Kim wrote:
> >>> On 09/12, Chao Yu wrote:
>  On 2018/9/12 9:40, Chao Yu wrote:
> > On 2018/9/12 9:25, Jaegeuk Kim wrote:
> >> On 09/12, Chao Yu wrote:
> >>> On 2018/9/12 8:27, Jaegeuk Kim wrote:
>  On 09/11, Jaegeuk Kim wrote:
> > On 09/12, Chao Yu wrote:
> >> On 2018/9/12 4:15, Jaegeuk Kim wrote:
> >>> fsck.f2fs is able to recover the quota structure, since 
> >>> roll-forward recovery
> >>> can recover it based on previous user information.
> >>
> >> I didn't get it, both fsck and kernel recover quota file based 
> >> all inodes'
> >> uid/gid/prjid, if {x}id didn't change, wouldn't those two 
> >> recovery result be the
> >> same?
> >
> > I thought that, but had to add this, since I was encountering 
> > quota errors right
> > after getting some files recovered. And, I thought it'd make it 
> > more safe to do
> > fsck after roll-forward recovery.
> >
> > Anyway, let me test again without this patch for a while.
> 
>  Hmm, I just got a fsck failure right after some files recovered.
> >>>
> >>> To make sure, do you test with "f2fs: guarantee journalled quota 
> >>> data by
> >>> checkpoint"? if not, I think there is no guarantee that f2fs can 
> >>> recover
> >>> quote info into correct quote file, because, in last checkpoint, 
> >>> quota file
> >>> may was corrupted/inconsistent. Right?
> >
> > Oh, I forget to mention that, I add a patch to fsck to let it 
> > noticing
> > CP_QUOTA_NEED_FSCK_FLAG flag, and by default, fsck will fix 
> > corrupted quote
> > file if the flag is set, but w/o this flag, quota file is still 
> > corrupted
> > detected by fsck, I guess there is bug in v8.
> 
>  In v8, there are two cases we didn't guarantee quota file's 
>  consistence:
>  1. flush time in block_operation exceed a threshold.
>  2. dquot subsystem error occurs.
> 
>  For above case, fsck should repair the quota file by default.
> >>>
> >>> Okay, I got another failure and it seems CP_QUOTA_NEED_FSCK_FLAG was 
> >>> not set
> >>> during the recovery. So, we have something missing in the recovery in 
> >>> terms
> >>> of quota updates.
> >>
> >> Yeah, I checked the code, just found one suspected place:
> >>
> >> find_fsync_dnodes()
> >>  - f2fs_recover_inode_page
> >>   - inc_valid_node_count
> >>- dquot_reserve_block  dquot info is not initialized now
> >>  - add_fsync_inode
> >>   - dquot_initialize
> >>
> >> I think we should reserve block for inode block after 
> >> dquot_initialize(), can
> >> you confirm this?
> >
> > Let me test this.
> >
> > >From b90260bc577fe87570b1ef7b134554a8295b1f6c Mon Sep 17 00:00:00 2001
> > From: Jaegeuk Kim 
> > Date: Mon, 17 Sep 2018 18:14:41 -0700
> > Subject: [PATCH] f2fs: count inode block for recovered files
> >
> > If a new file is recovered, we missed to reserve its inode block.
> 
>  I remember, in order to keep line with other filesystem, unlike on-disk, 
>  we
>  have to keep backward compatibilty, in memory we don't account block 
>  number
>  for f2fs' inode block, but only account inode number for it, so here like
>  we did in inc_valid_node_count(), we don't need to do this.
> >>>
> >>> Okay, I just hit the error again w/o your patch. Another one coming to my 
> >>> mind
> >>> is that caused by uid/gid change during recovery. Let me try out your 
> >>> patch.
> >>
> >> I guess we should update dquot and inode's uid/gid atomically under
> >> lock_op() in f2fs_setattr() to prevent corruption on sys quota file.
> >>
> >> v9 can pass all xfstest cases and por_fsstress case w/ sys quota file
> >> enabled, but w/ normal quota file, I got one regression reported by
> >> generic/232, I fixed in v10, will do some tests and release it later.
> >>
> >> Note that, my fsck can fix corrupted quota file automatically once
> >> CP_QUOTA_NEED_FSCK_FLAG is set.
> > 
> > I hit failures again with your v9 w/ sysfile quota and modified fsck to 
> > detect
> 
> That's strange, in my environment, before v9, I always encounter corrupted
> quota sysfile after step 9), after v9, I never hit failure again.
> 
> 1) enable fault injection
> 2) run fsstress
> 3) call shutdowon
> 4) kill fsstress
> 5) 

Re: [f2fs-dev] [PATCH] f2fs: allow out-place-update for direct IO in LFS mode

2018-09-19 Thread Jaegeuk Kim
On 09/19, Chao Yu wrote:
> On 2018/9/19 0:27, Jaegeuk Kim wrote:
> > On 09/18, Chao Yu wrote:
> >> On 2018/9/18 9:27, Jaegeuk Kim wrote:
> >>> On 09/16, Chao Yu wrote:
>  From: Chao Yu 
> 
>  Normally, DIO uses in-pllace-update, but in LFS mode, f2fs doesn't
>  allow triggering any in-place-update writes, so we fallback direct
>  write to buffered write, result in bad performance of large size
>  write.
> >>>
> >>> I remember this is to serialize all the IOs in one buffered IO path to 
> >>> keep
> >>> the IO sequence espeicially useful for SMR drivers. Could you confirm 
> >>> whether
> >>> there is any IO reordering problem?
> >>
> >> IMO, buffered IO will encounter reordering issue more easily, for example:
> >>
> >> User write 2mb data via DIO, but according to policy on LFS mode, it will
> >> fallback to buffered IO.
> >>
> >> Before dio triggers writeback, an async writeback from background is
> >> triggered, so all IO distribution can be:
> >>
> >>pageLBA range
> >> async IO:  0 - 255 x + 0, x + 255
> >> sync IO:   256 - 511   x + 256, x + 511
> >>
> >> Then block IO scheduler can issue sync IO before async IO, result IO
> >> reordering.
> >>
> >> Anyway, in DIO path we will suffer less IO reordering issue.
> > 
> > My concern was on mixed DIO and buffered IOs where we don't have a way to
> > serialize all the IOs.
> 
> As I explained above, even we always use buffered IO, there is no such
> guarantee for serializing all async/sync IO in block layer, am I missing
> something?
> 
> If you really don't want to change the logic for SMR, how about let me just
> leave that case?

Okay, that could be fine to me.
Thanks,

> 
> Thanks,
> 
> > 
> >>
> >> Thanks,
> >>
> >>>
> 
>  This patch adds to support triggering out-place-update for direct IO
>  to enhance its performance.
> 
>  Note that it needs to exclude direct read IO during direct write,
>  since new data writing to new block address will no be valid until
>  write finished.
> 
>  storage: zram
> 
>  time xfs_io -f -d /mnt/f2fs/file -c "pwrite 0 1073741824" -c "fsync"
> 
>  Before:
>  real 0m13.061s
>  user 0m0.327s
>  sys  0m12.486s
> 
>  After:
>  real 0m6.448s
>  user 0m0.228s
>  sys  0m6.212s
> 
>  Signed-off-by: Chao Yu 
>  ---
>   fs/f2fs/data.c | 41 +
>   fs/f2fs/f2fs.h | 39 +++
>   fs/f2fs/file.c |  3 ++-
>   3 files changed, 70 insertions(+), 13 deletions(-)
> 
>  diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>  index 048f9cf1d589..9937dc2f384a 100644
>  --- a/fs/f2fs/data.c
>  +++ b/fs/f2fs/data.c
>  @@ -894,7 +894,7 @@ static int __allocate_data_block(struct 
>  dnode_of_data *dn, int seg_type)
>   
>   dn->data_blkaddr = datablock_addr(dn->inode,
>   dn->node_page, dn->ofs_in_node);
>  -if (dn->data_blkaddr == NEW_ADDR)
>  +if (dn->data_blkaddr != NULL_ADDR)
>   goto alloc;
>   
>   if (unlikely((err = inc_valid_block_count(sbi, dn->inode, 
>  
>  @@ -950,7 +950,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, 
>  struct iov_iter *from)
>   
>   if (direct_io) {
>   map.m_seg_type = 
>  f2fs_rw_hint_to_seg_type(iocb->ki_hint);
>  -flag = f2fs_force_buffered_io(inode, WRITE) ?
>  +flag = f2fs_force_buffered_io(inode, iocb, from) ?
>   F2FS_GET_BLOCK_PRE_AIO :
>   F2FS_GET_BLOCK_PRE_DIO;
>   goto map_blocks;
>  @@ -1069,7 +1069,15 @@ int f2fs_map_blocks(struct inode *inode, struct 
>  f2fs_map_blocks *map,
>   goto sync_out;
>   }
>   
>  -if (!is_valid_data_blkaddr(sbi, blkaddr)) {
>  +if (is_valid_data_blkaddr(sbi, blkaddr)) {
>  +/* use out-place-update for driect IO under LFS mode */
>  +if (test_opt(sbi, LFS) && create &&
>  +flag == F2FS_GET_BLOCK_DEFAULT) {
>  +err = __allocate_data_block(, 
>  map->m_seg_type);
>  +if (!err)
>  +set_inode_flag(inode, FI_APPEND_WRITE);
>  +}
>  +} else {
>   if (create) {
>   if (unlikely(f2fs_cp_error(sbi))) {
>   err = -EIO;
>  @@ -2491,36 +2499,53 @@ static ssize_t f2fs_direct_IO(struct kiocb 
>  *iocb, struct iov_iter *iter)
>   struct address_space *mapping = iocb->ki_filp->f_mapping;
>   struct inode 

Re: [f2fs-dev] [PATCH] f2fs: remove default option setting in remount

2018-09-19 Thread Chao Yu
On 2018/9/18 21:47, cgxu519 wrote:
> On 09/18/2018 09:20 PM, Chao Yu wrote:
>> On 2018/9/18 14:23, Chengguang Xu wrote:
>>> Currently we set default value to options before parsing remount options,
>>> it will cause unexpected change of options which were specified in first
>>> mount.
>> Can you check below commit? It looks w/o it we may lose default option after
>> remount.
>>
>> 498c5e9fcd10 ("f2fs: add default mount options to remount")
> 
> Hi Chao,

Hi Chengguang,

> 
> It looks like there was a bug in remount at that time, but I think the fix 
> above
> is not correct.
> 
> from the patch '498c5e9fcd10', I think it was caused by clearing
> sbi->mount_opt.opt before
> 
> parsing. I think remount should not change the options which were specified by
> user in
> 
> previous mount unless user specifies in remount.

Can you check description in manual of mount.

IIRC, old mount option will be record into /etc/mtab or /proc/mounts (for
adapting namespace feature), with command of "mount -o remount,rw  /dir", old
mount options can be loaded from above config file, and merge them with new
specified options.

Even we kill old mount options by call default_options() in ->remount, user's
old mount option can still be set through parameters.

But the problem here is, some old parameter can be configured via sysfs, if we
reset them in default_options(), we will lose them forever after remount.

If you have no other opinion about this, could you adapt your commit log?

Thanks,

> 
> Thanks,
> Chengguang
> 
> 
> 
> 
> ___
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 5/5] fsck.f2fs: try to recover cp_payload from valid cp pack

2018-09-19 Thread Junling Zheng
From: Chao Yu 

If sb checksum is not enabled, and cp pack is valid due to no
crc inconsistence, let's try to recover cp_payload based on
cp_pack_start_sum in cp pack.

Signed-off-by: Chao Yu 
---
 fsck/f2fs.h  |  5 +
 fsck/mount.c | 10 +++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index d216444..0d0d5e2 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -259,6 +259,11 @@ static inline unsigned long __bitmap_size(struct 
f2fs_sb_info *sbi, int flag)
return 0;
 }
 
+static inline block_t __cp_payload(struct f2fs_sb_info *sbi)
+{
+   return le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
+}
+
 static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
 {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
diff --git a/fsck/mount.c b/fsck/mount.c
index 9019921..0e8fa41 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -975,12 +975,16 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
}
 
cp_pack_start_sum = __start_sum_addr(sbi);
-   cp_payload = get_sb(cp_payload);
+   cp_payload = __cp_payload(sbi);
if (cp_pack_start_sum < cp_payload + 1 ||
cp_pack_start_sum > blocks_per_seg - 1 -
NR_CURSEG_TYPE) {
-   MSG(0, "\tWrong cp_pack_start_sum(%u)\n", cp_pack_start_sum);
-   return 1;
+   MSG(0, "\tWrong cp_pack_start_sum(%u) or cp_payload(%u)\n",
+   cp_pack_start_sum, cp_payload);
+   if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM))
+   return 1;
+   set_sb(cp_payload, cp_pack_start_sum - 1);
+   update_superblock(sb, SB_ALL);
}
 
return 0;
-- 
2.19.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/5] f2fs-tools: rename CHECKSUM_OFFSET to CP_CHKSUM_OFFSET

2018-09-19 Thread Junling Zheng
This patch renamed CHECKSUM_OFFSET to CP_CHKSUM_OFFSET.

Reviewed-by: Chao Yu 
Signed-off-by: Junling Zheng 
---
 fsck/fsck.c|  4 ++--
 fsck/mount.c   |  4 ++--
 fsck/resize.c  |  8 
 include/f2fs_fs.h  |  6 +++---
 mkfs/f2fs_format.c | 14 +++---
 5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index d550403..f080d3c 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -2010,8 +2010,8 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
set_cp(valid_node_count, fsck->chk.valid_node_cnt);
set_cp(valid_inode_count, fsck->chk.valid_inode_cnt);
 
-   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CHECKSUM_OFFSET);
-   *((__le32 *)((unsigned char *)cp + CHECKSUM_OFFSET)) = cpu_to_le32(crc);
+   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CP_CHKSUM_OFFSET);
+   *((__le32 *)((unsigned char *)cp + CP_CHKSUM_OFFSET)) = 
cpu_to_le32(crc);
 
cp_blk_no = get_sb(cp_blkaddr);
if (sbi->cur_cp == 2)
diff --git a/fsck/mount.c b/fsck/mount.c
index 2c2473d..1daef75 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -2252,8 +2252,8 @@ void write_checkpoint(struct f2fs_sb_info *sbi)
flags = update_nat_bits_flags(sb, cp, flags);
set_cp(ckpt_flags, flags);
 
-   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CHECKSUM_OFFSET);
-   *((__le32 *)((unsigned char *)cp + CHECKSUM_OFFSET)) = cpu_to_le32(crc);
+   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CP_CHKSUM_OFFSET);
+   *((__le32 *)((unsigned char *)cp + CP_CHKSUM_OFFSET)) = 
cpu_to_le32(crc);
 
cp_blk_no = get_sb(cp_blkaddr);
if (sbi->cur_cp == 2)
diff --git a/fsck/resize.c b/fsck/resize.c
index fe8a61a..e9612b3 100644
--- a/fsck/resize.c
+++ b/fsck/resize.c
@@ -90,10 +90,10 @@ static int get_new_sb(struct f2fs_super_block *sb)
 * It requires more pages for cp.
 */
if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) {
-   max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct 
f2fs_checkpoint) + 1;
+   max_nat_bitmap_size = CP_CHKSUM_OFFSET - sizeof(struct 
f2fs_checkpoint) + 1;
set_sb(cp_payload, F2FS_BLK_ALIGN(max_sit_bitmap_size));
} else {
-   max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct 
f2fs_checkpoint) + 1
+   max_nat_bitmap_size = CP_CHKSUM_OFFSET - sizeof(struct 
f2fs_checkpoint) + 1
- max_sit_bitmap_size;
set_sb(cp_payload, 0);
}
@@ -520,8 +520,8 @@ static void rebuild_checkpoint(struct f2fs_sb_info *sbi,
(unsigned char *)cp);
new_cp->checkpoint_ver = cpu_to_le64(cp_ver + 1);
 
-   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, new_cp, CHECKSUM_OFFSET);
-   *((__le32 *)((unsigned char *)new_cp + CHECKSUM_OFFSET)) =
+   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, new_cp, CP_CHKSUM_OFFSET);
+   *((__le32 *)((unsigned char *)new_cp + CP_CHKSUM_OFFSET)) =
cpu_to_le32(crc);
 
/* Write a new checkpoint in the other set */
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 2c086a9..38a0da4 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -278,7 +278,7 @@ static inline uint64_t bswap_64(uint64_t val)
 #define PAGE_CACHE_SIZE4096
 #define BITS_PER_BYTE  8
 #define F2FS_SUPER_MAGIC   0xF2F52010  /* F2FS Magic Number */
-#define CHECKSUM_OFFSET4092
+#define CP_CHKSUM_OFFSET   4092
 #define MAX_PATH_LEN   64
 #define MAX_DEVICES8
 
@@ -682,9 +682,9 @@ struct f2fs_checkpoint {
 } __attribute__((packed));
 
 #define MAX_SIT_BITMAP_SIZE_IN_CKPT\
-   (CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 - 64)
+   (CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 - 64)
 #define MAX_BITMAP_SIZE_IN_CKPT\
-   (CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1)
+   (CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1)
 
 /*
  * For orphan inode management
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 4b88d93..621126c 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -342,12 +342,12 @@ static int f2fs_prepare_super_block(void)
 * It requires more pages for cp.
 */
if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) {
-   max_nat_bitmap_size = CHECKSUM_OFFSET -
+   max_nat_bitmap_size = CP_CHKSUM_OFFSET -
sizeof(struct f2fs_checkpoint) + 1;
set_sb(cp_payload, F2FS_BLK_ALIGN(max_sit_bitmap_size));
} else {
max_nat_bitmap_size =
-   CHECKSUM_OFFSET - sizeof(struct 
f2fs_checkpoint) + 1
+   

[f2fs-dev] [PATCH 1/5] f2fs: support superblock checksum

2018-09-19 Thread Junling Zheng
Now we support crc32 checksum for superblock.

Reviewed-by: Chao Yu 
Signed-off-by: Junling Zheng 
---
 fs/f2fs/f2fs.h  |  2 ++
 fs/f2fs/super.c | 29 +
 fs/f2fs/sysfs.c |  7 +++
 include/linux/f2fs_fs.h |  3 ++-
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4525f4f82af0..d50d6efda96b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -147,6 +147,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
 #define F2FS_FEATURE_LOST_FOUND0x0200
 #define F2FS_FEATURE_VERITY0x0400  /* reserved */
+#define F2FS_FEATURE_SB_CHKSUM 0x0800
 
 #define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -3376,6 +3377,7 @@ F2FS_FEATURE_FUNCS(flexible_inline_xattr, 
FLEXIBLE_INLINE_XATTR);
 F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
 F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
 F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
+F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
 
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline int get_blkz_type(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index bd57be470e23..3ffc336caea8 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2149,6 +2149,26 @@ static int sanity_check_raw_super(struct f2fs_sb_info 
*sbi,
(bh->b_data + F2FS_SUPER_OFFSET);
struct super_block *sb = sbi->sb;
unsigned int blocksize;
+   size_t crc_offset = 0;
+   __u32 crc = 0;
+
+   /* Check checksum_offset and crc in superblock */
+   if (le32_to_cpu(raw_super->feature) & F2FS_FEATURE_SB_CHKSUM) {
+   crc_offset = le32_to_cpu(raw_super->checksum_offset);
+   if (crc_offset !=
+   offsetof(struct f2fs_super_block, crc)) {
+   f2fs_msg(sb, KERN_INFO,
+   "Invalid SB checksum offset: %zu",
+   crc_offset);
+   return 1;
+   }
+   crc = le32_to_cpu(raw_super->crc);
+   if (!f2fs_crc_valid(sbi, crc, raw_super, crc_offset)) {
+   f2fs_msg(sb, KERN_INFO,
+   "Invalid SB checksum value: %u", crc);
+   return 1;
+   }
+   }
 
if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
f2fs_msg(sb, KERN_INFO,
@@ -2568,6 +2588,7 @@ static int read_raw_super_block(struct f2fs_sb_info *sbi,
 int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
 {
struct buffer_head *bh;
+   __u32 crc = 0;
int err;
 
if ((recover && f2fs_readonly(sbi->sb)) ||
@@ -2576,6 +2597,13 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
return -EROFS;
}
 
+   /* we should update superblock crc here */
+   if (!recover && f2fs_sb_has_sb_chksum(sbi->sb)) {
+   crc = f2fs_crc32(sbi, F2FS_RAW_SUPER(sbi),
+   offsetof(struct f2fs_super_block, crc));
+   F2FS_RAW_SUPER(sbi)->crc = cpu_to_le32(crc);
+   }
+
/* write back-up superblock first */
bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1);
if (!bh)
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index cd2e030e47b8..c86d91be6c48 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -120,6 +120,9 @@ static ssize_t features_show(struct f2fs_attr *a,
if (f2fs_sb_has_lost_found(sb))
len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
len ? ", " : "", "lost_found");
+   if (f2fs_sb_has_sb_chksum(sb))
+   len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
+   len ? ", " : "", "sb_checksum");
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
return len;
 }
@@ -337,6 +340,7 @@ enum feat_id {
FEAT_QUOTA_INO,
FEAT_INODE_CRTIME,
FEAT_LOST_FOUND,
+   FEAT_SB_CHECKSUM,
 };
 
 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
@@ -353,6 +357,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a,
case FEAT_QUOTA_INO:
case FEAT_INODE_CRTIME:
case FEAT_LOST_FOUND:
+   case FEAT_SB_CHECKSUM:
return snprintf(buf, PAGE_SIZE, "supported\n");
}
return 0;
@@ -433,6 +438,7 @@ F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, 
FEAT_FLEXIBLE_INLINE_XATTR);
 F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
 F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
 F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
+F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
 
 #define ATTR_LIST(name) (_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -489,6 +495,7 @@ static struct attribute *f2fs_feat_attrs[] = {
ATTR_LIST(quota_ino),

[f2fs-dev] [PATCH 3/5] fsck.f2fs: unify the updating of superblocks

2018-09-19 Thread Junling Zheng
Rename write_superblock() to update_superblock() and make it support updating
specified one superblock or both two superblocks, then unify all places where
sb needs to be updated.

Signed-off-by: Junling Zheng 
---
 fsck/fsck.h   | 12 ++-
 fsck/mount.c  | 94 +++
 fsck/resize.c | 20 ++-
 3 files changed, 47 insertions(+), 79 deletions(-)

diff --git a/fsck/fsck.h b/fsck/fsck.h
index 6042e68..bdd7f8d 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -32,6 +32,16 @@ enum {
EUNKNOWN_ARG,
 };
 
+enum SB_ADDR {
+   SB_ADDR_0,
+   SB_ADDR_1,
+   SB_ADDR_MAX,
+};
+
+#define SB_FIRST   (1 << SB_ADDR_0)
+#define SB_SECOND  (1 << SB_ADDR_1)
+#define SB_ALL (SB_FIRST | SB_SECOND)
+
 /* fsck.c */
 struct orphan_info {
u32 nr_inodes;
@@ -178,7 +188,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, 
int);
 extern void write_curseg_info(struct f2fs_sb_info *);
 extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int);
 extern void write_checkpoint(struct f2fs_sb_info *);
-extern void write_superblock(struct f2fs_super_block *);
+extern void update_superblock(struct f2fs_super_block *, int);
 extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t);
 extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t);
 
diff --git a/fsck/mount.c b/fsck/mount.c
index 1daef75..74ff7c6 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -475,8 +475,28 @@ void print_sb_state(struct f2fs_super_block *sb)
MSG(0, "\n");
 }
 
+void update_superblock(struct f2fs_super_block *sb, int sb_mask)
+{
+   int index, ret;
+   u_int8_t *buf;
+
+   buf = calloc(BLOCK_SZ, 1);
+   ASSERT(buf);
+
+   memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb));
+   for (index = 0; index < SB_ADDR_MAX; index++) {
+   if ((1 << index) & sb_mask) {
+   ret = dev_write_block(buf, index);
+   ASSERT(ret >= 0);
+   }
+   }
+
+   free(buf);
+   DBG(0, "Info: Done to update superblock\n");
+}
+
 static inline int sanity_check_area_boundary(struct f2fs_super_block *sb,
-   u64 offset)
+   enum SB_ADDR sb_addr)
 {
u32 segment0_blkaddr = get_sb(segment0_blkaddr);
u32 cp_blkaddr = get_sb(cp_blkaddr);
@@ -542,14 +562,11 @@ static inline int sanity_check_area_boundary(struct 
f2fs_super_block *sb,
segment_count_main << log_blocks_per_seg);
return -1;
} else if (main_end_blkaddr < seg_end_blkaddr) {
-   int err;
-
set_sb(segment_count, (main_end_blkaddr -
segment0_blkaddr) >> log_blocks_per_seg);
 
-   err = dev_write(sb, offset, sizeof(struct f2fs_super_block));
-   MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n",
-   err ? "failed": "done",
+   update_superblock(sb, 1 << sb_addr);
+   MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n",
main_blkaddr,
segment0_blkaddr +
(segment_count << log_blocks_per_seg),
@@ -558,7 +575,7 @@ static inline int sanity_check_area_boundary(struct 
f2fs_super_block *sb,
return 0;
 }
 
-int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset)
+int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
 {
unsigned int blocksize;
 
@@ -600,30 +617,24 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, 
u64 offset)
if (get_sb(segment_count) > F2FS_MAX_SEGMENT)
return -1;
 
-   if (sanity_check_area_boundary(sb, offset))
+   if (sanity_check_area_boundary(sb, sb_addr))
return -1;
return 0;
 }
 
-int validate_super_block(struct f2fs_sb_info *sbi, int block)
+int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr)
 {
-   u64 offset;
char buf[F2FS_BLKSIZE];
 
sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
 
-   if (block == 0)
-   offset = F2FS_SUPER_OFFSET;
-   else
-   offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET;
-
-   if (dev_read_block(buf, block))
+   if (dev_read_block(buf, sb_addr))
return -1;
 
memcpy(sbi->raw_super, buf + F2FS_SUPER_OFFSET,
sizeof(struct f2fs_super_block));
 
-   if (!sanity_check_raw_super(sbi->raw_super, offset)) {
+   if (!sanity_check_raw_super(sbi->raw_super, sb_addr)) {
/* get kernel version */
if (c.kd >= 0) {
dev_read_version(c.version, 0, VERSION_LEN);
@@ -642,13 +653,9 @@ int validate_super_block(struct f2fs_sb_info *sbi, int 
block)
  

[f2fs-dev] [PATCH 4/5] f2fs-tools: introduce sb checksum

2018-09-19 Thread Junling Zheng
This patch introduced crc for superblock.

Signed-off-by: Junling Zheng 
---
 fsck/mount.c   | 33 +
 fsck/resize.c  | 12 ++--
 include/f2fs_fs.h  |  6 +-
 mkfs/f2fs_format.c |  8 
 4 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 74ff7c6..9019921 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb)
DISP_u32(sb, node_ino);
DISP_u32(sb, meta_ino);
DISP_u32(sb, cp_payload);
+   DISP_u32(sb, crc);
DISP("%-.256s", sb, version);
printf("\n");
 }
@@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb)
if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
MSG(0, "%s", " lost_found");
}
+   if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) {
+   MSG(0, "%s", " sb_checksum");
+   }
MSG(0, "\n");
MSG(0, "Info: superblock encrypt level = %d, salt = ",
sb->encryption_level);
@@ -479,10 +483,20 @@ void update_superblock(struct f2fs_super_block *sb, int 
sb_mask)
 {
int index, ret;
u_int8_t *buf;
+   u32 old_crc, new_crc;
 
buf = calloc(BLOCK_SZ, 1);
ASSERT(buf);
 
+   if (get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) {
+   old_crc = get_sb(crc);
+   new_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, sb,
+   SB_CHKSUM_OFFSET);
+   set_sb(crc, new_crc);
+   MSG(1, "Info: SB CRC is updated (0x%x -> 0x%x)\n",
+   old_crc, new_crc);
+   }
+
memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb));
for (index = 0; index < SB_ADDR_MAX; index++) {
if ((1 << index) & sb_mask) {
@@ -575,10 +589,29 @@ static inline int sanity_check_area_boundary(struct 
f2fs_super_block *sb,
return 0;
 }
 
+static int verify_sb_chksum(struct f2fs_super_block *sb)
+{
+   if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) {
+   MSG(0, "\tInvalid SB CRC offset: %u\n",
+   get_sb(checksum_offset));
+   return -1;
+   }
+   if (f2fs_crc_valid(get_sb(crc), sb,
+   get_sb(checksum_offset))) {
+   MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc));
+   return -1;
+   }
+   return 0;
+}
+
 int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
 {
unsigned int blocksize;
 
+   if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) &&
+   verify_sb_chksum(sb))
+   return -1;
+
if (F2FS_SUPER_MAGIC != get_sb(magic))
return -1;
 
diff --git a/fsck/resize.c b/fsck/resize.c
index 5161a1f..3462165 100644
--- a/fsck/resize.c
+++ b/fsck/resize.c
@@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
}
}
 
-   print_raw_sb_info(sb);
-   print_raw_sb_info(new_sb);
-
old_main_blkaddr = get_sb(main_blkaddr);
new_main_blkaddr = get_newsb(main_blkaddr);
offset = new_main_blkaddr - old_main_blkaddr;
@@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
migrate_sit(sbi, new_sb, offset_seg);
rebuild_checkpoint(sbi, new_sb, offset_seg);
update_superblock(new_sb, SB_ALL);
+   print_raw_sb_info(sb);
+   print_raw_sb_info(new_sb);
+
return 0;
 }
 
@@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
}
}
 
-   print_raw_sb_info(sb);
-   print_raw_sb_info(new_sb);
-
old_main_blkaddr = get_sb(main_blkaddr);
new_main_blkaddr = get_newsb(main_blkaddr);
offset = old_main_blkaddr - new_main_blkaddr;
@@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
/* move whole data region */
//if (err)
//  migrate_main(sbi, offset);
+   print_raw_sb_info(sb);
+   print_raw_sb_info(new_sb);
+
return 0;
 }
 
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 38a0da4..f80632a 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val)
 #define BITS_PER_BYTE  8
 #define F2FS_SUPER_MAGIC   0xF2F52010  /* F2FS Magic Number */
 #define CP_CHKSUM_OFFSET   4092
+#define SB_CHKSUM_OFFSET   3068
 #define MAX_PATH_LEN   64
 #define MAX_DEVICES8
 
@@ -579,6 +580,7 @@ enum {
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
 #define F2FS_FEATURE_LOST_FOUND0x0200
 #define F2FS_FEATURE_VERITY0x0400  /* reserved */
+#define F2FS_FEATURE_SB_CHKSUM 0x0800
 
 #define MAX_VOLUME_NAME512
 
@@ -632,7 +634,8 @@ struct f2fs_super_block {

Re: [f2fs-dev] [PATCH v4] f2fs: add new idle interval timing for discard and gc paths

2018-09-19 Thread Chao Yu
On 2018/9/19 16:48, Sahitya Tummala wrote:
> This helps to control the frequency of submission of discard and
> GC requests independently, based on the need.
> 
> Suggested-by: Chao Yu 
> Signed-off-by: Sahitya Tummala 

Reviewed-by: Chao Yu 

Thanks,


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] fsck.f2fs: detect and recover corrupted quota file

2018-09-19 Thread Chao Yu
Hi Sheng,

On 2018/9/19 9:48, Sheng Yong wrote:
> Hi, Chao
> 
> On 2018/9/19 9:28, Chao Yu wrote:
>> Once quota file is corrupted, kernel will set CP_QUOTA_NEED_FSCK_FLAG
>> into checkpoint pack, this patch makes fsck supporting to detect the flag
>> and try to rebuild corrupted quota file.
>>
>> Signed-off-by: Chao Yu 
>> ---
>>   fsck/fsck.c   |  3 ++-
>>   fsck/main.c   |  1 +
>>   fsck/mount.c  | 11 +--
>>   include/f2fs_fs.h |  2 ++
>>   4 files changed, 14 insertions(+), 3 deletions(-)
>>
>> diff --git a/fsck/fsck.c b/fsck/fsck.c
>> index 40b95f7054a2..28c913b83355 100644
>> --- a/fsck/fsck.c
>> +++ b/fsck/fsck.c
>> @@ -2670,7 +2670,8 @@ int fsck_verify(struct f2fs_sb_info *sbi)
>>  flush_curseg_sit_entries(sbi);
>>  }
>>  fix_checkpoint(sbi);
>> -} else if (is_set_ckpt_flags(cp, CP_FSCK_FLAG)) {
>> +} else if (is_set_ckpt_flags(cp, CP_FSCK_FLAG) ||
>> +is_set_ckpt_flags(cp, CP_QUOTA_NEED_FSCK_FLAG)) {
>>  write_checkpoint(sbi);
>>  }
>>  }
>> diff --git a/fsck/main.c b/fsck/main.c
>> index 714e28a509b9..e20f31ca09e4 100644
>> --- a/fsck/main.c
>> +++ b/fsck/main.c
>> @@ -162,6 +162,7 @@ static void add_default_options(void)
>>  case CONF_ANDROID:
>>  __add_fsck_options();
>>  }
>> +c.quota_fix = 1;
>>   }
>>   
>>   void f2fs_parse_options(int argc, char *argv[])
>> diff --git a/fsck/mount.c b/fsck/mount.c
>> index 6a3382dbd449..21a39a7222c6 100644
>> --- a/fsck/mount.c
>> +++ b/fsck/mount.c
>> @@ -405,6 +405,8 @@ void print_ckpt_info(struct f2fs_sb_info *sbi)
>>   void print_cp_state(u32 flag)
>>   {
>>  MSG(0, "Info: checkpoint state = %x : ", flag);
>> +if (flag & CP_QUOTA_NEED_FSCK_FLAG)
>> +MSG(0, "%s", " quota_need_fsck");
>>  if (flag & CP_LARGE_NAT_BITMAP_FLAG)
>>  MSG(0, "%s", " large_nat_bitmap");
>>  if (flag & CP_NOCRC_RECOVERY_FLAG)
>> @@ -2541,12 +2543,17 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
>>   
>>  print_ckpt_info(sbi);
>>   
>> +if (c.quota_fix) {
>> +if (get_cp(ckpt_flags) & CP_QUOTA_NEED_FSCK_FLAG)
>> +c.fix_on = 1;
>> +}
>> +
> 
> I think we don't need the quota_fix, if -f is set, fsck will always check
> quota files. If anything wrong, fix_on will be set.

Yeah, since kernel will be aware of quota file corruption under journalled
mode, so I prefer to let fsck to check the CP_QUOTA_NEED_FSCK_FLAG by
default and once that flag is set, then do repairing automatically, like we
did for CP_FSCK_FLAG. By this way we can avoid traversing all data to check
quota info.

So how about just turning o c.fix_on under -a or -p 0 mode? Since in
android environment, auto_fix is enabled by default, we can expect above
design can work.

Thanks,

> 
> thanks,
> 
>>  if (c.auto_fix || c.preen_mode) {
>>  u32 flag = get_cp(ckpt_flags);
>>   
>>  if (flag & CP_FSCK_FLAG ||
>> -(exist_qf_ino(sb) && (!(flag & CP_UMOUNT_FLAG) ||
>> -flag & CP_ERROR_FLAG))) {
>> +flag & CP_QUOTA_NEED_FSCK_FLAG ||
>> +(exist_qf_ino(sb) && (flag & CP_ERROR_FLAG))) {
>>  c.fix_on = 1;
>>  } else if (!c.preen_mode) {
>>  print_cp_state(flag);
>> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
>> index 9396c785a254..160eaf72f0b6 100644
>> --- a/include/f2fs_fs.h
>> +++ b/include/f2fs_fs.h
>> @@ -372,6 +372,7 @@ struct f2fs_configuration {
>>  int defset;
>>  int bug_on;
>>  int auto_fix;
>> +int quota_fix;
>>  int preen_mode;
>>  int ro;
>>  int preserve_limits;/* preserve quota limits */
>> @@ -641,6 +642,7 @@ struct f2fs_super_block {
>>   /*
>>* For checkpoint
>>*/
>> +#define CP_QUOTA_NEED_FSCK_FLAG 0x0800
>>   #define CP_LARGE_NAT_BITMAP_FLAG   0x0400
>>   #define CP_NOCRC_RECOVERY_FLAG 0x0200
>>   #define CP_TRIMMED_FLAG0x0100
>>
> 
> 
> 
> ___
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
> 
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v4] f2fs: add new idle interval timing for discard and gc paths

2018-09-19 Thread Sahitya Tummala
This helps to control the frequency of submission of discard and
GC requests independently, based on the need.

Suggested-by: Chao Yu 
Signed-off-by: Sahitya Tummala 
---
v4:
- initialize and use sbi->last_time[discard_time], sbi->last_time[gc_time]

 Documentation/ABI/testing/sysfs-fs-f2fs | 17 -
 fs/f2fs/f2fs.h  | 30 +++---
 fs/f2fs/gc.c|  2 +-
 fs/f2fs/segment.c   | 14 +-
 fs/f2fs/super.c |  2 ++
 fs/f2fs/sysfs.c |  5 +
 6 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 94a24ae..3ac4177 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -121,7 +121,22 @@ What:  /sys/fs/f2fs//idle_interval
 Date:  January 2016
 Contact:   "Jaegeuk Kim" 
 Description:
-Controls the idle timing.
+Controls the idle timing for all paths other than
+discard and gc path.
+
+What:  /sys/fs/f2fs//discard_idle_interval
+Date:  September 2018
+Contact:   "Chao Yu" 
+Contact:   "Sahitya Tummala" 
+Description:
+Controls the idle timing for discard path.
+
+What:  /sys/fs/f2fs//gc_idle_interval
+Date:  September 2018
+Contact:   "Chao Yu" 
+Contact:   "Sahitya Tummala" 
+Description:
+Controls the idle timing for gc path.
 
 What:  /sys/fs/f2fs//iostat_enable
 Date:  August 2017
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 88b8d50..c47b7d2 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1095,6 +1095,8 @@ enum {
 enum {
CP_TIME,
REQ_TIME,
+   DISCARD_TIME,
+   GC_TIME,
MAX_TIME,
 };
 
@@ -1346,7 +1348,15 @@ static inline bool time_to_inject(struct f2fs_sb_info 
*sbi, int type)
 
 static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
 {
-   sbi->last_time[type] = jiffies;
+   unsigned long now = jiffies;
+
+   sbi->last_time[type] = now;
+
+   /* DISCARD_TIME and GC_TIME are based on REQ_TIME */
+   if (type == REQ_TIME) {
+   sbi->last_time[DISCARD_TIME] = now;
+   sbi->last_time[GC_TIME] = now;
+   }
 }
 
 static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
@@ -1356,7 +1366,21 @@ static inline bool f2fs_time_over(struct f2fs_sb_info 
*sbi, int type)
return time_after(jiffies, sbi->last_time[type] + interval);
 }
 
-static inline bool is_idle(struct f2fs_sb_info *sbi)
+static inline unsigned int f2fs_time_to_wait(struct f2fs_sb_info *sbi,
+   int type)
+{
+   unsigned long interval = sbi->interval_time[type] * HZ;
+   unsigned int wait_ms = 0;
+   long delta;
+
+   delta = (sbi->last_time[type] + interval) - jiffies;
+   if (delta > 0)
+   wait_ms = jiffies_to_msecs(delta);
+
+   return wait_ms;
+}
+
+static inline bool is_idle(struct f2fs_sb_info *sbi, int type)
 {
struct block_device *bdev = sbi->sb->s_bdev;
struct request_queue *q = bdev_get_queue(bdev);
@@ -1365,7 +1389,7 @@ static inline bool is_idle(struct f2fs_sb_info *sbi)
if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
return false;
 
-   return f2fs_time_over(sbi, REQ_TIME);
+   return f2fs_time_over(sbi, type);
 }
 
 /*
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 5c8d004..49e2328 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -83,7 +83,7 @@ static int gc_thread_func(void *data)
if (!mutex_trylock(>gc_mutex))
goto next;
 
-   if (!is_idle(sbi)) {
+   if (!is_idle(sbi, GC_TIME)) {
increase_sleep_time(gc_th, _ms);
mutex_unlock(>gc_mutex);
goto next;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 187c848..67cf7e4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -511,7 +511,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
else
f2fs_build_free_nids(sbi, false, false);
 
-   if (!is_idle(sbi) &&
+   if (!is_idle(sbi, REQ_TIME) &&
(!excess_dirty_nats(sbi) && !excess_dirty_nodes(sbi)))
return;
 
@@ -1311,7 +1311,7 @@ static unsigned int __issue_discard_cmd_orderly(struct 
f2fs_sb_info *sbi,
if (dc->state != D_PREP)
goto next;
 
-   if (dpolicy->io_aware && !is_idle(sbi)) {
+   if (dpolicy->io_aware && !is_idle(sbi, DISCARD_TIME)) {
io_interrupted = true;
break;
}
@@ -1371,7 +1371,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,