[f2fs-dev] [PATCH] fsck.f2fs: do not check segment type of empty curseg

2018-10-08 Thread Sheng Yong
If a curseg is not used, its SIT entry may have an inconsistent type.
This will be fixed during recover.

Fixes: df8065e52928be ("fsck.f2fs: introduce fsck_chk_curseg_info")
Signed-off-by: Sheng Yong 
---
 fsck/fsck.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 85d9823..dd7f6ae 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -2485,7 +2485,7 @@ int fsck_chk_curseg_info(struct f2fs_sb_info *sbi)
se = get_seg_entry(sbi, curseg->segno);
sum_blk = curseg->sum_blk;
 
-   if (se->type != i) {
+   if (se->valid_blocks && se->type != i) {
ASSERT_MSG("Incorrect curseg [%d]: segno [0x%x] "
   "type(SIT) [%d]", i, curseg->segno,
   se->type);
-- 
2.17.1



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


[f2fs-dev] [PATCH] f2fs: cleanup dirty pages if recover failed

2018-09-27 Thread Sheng Yong
During recover, we will try to create new dentries for inodes with
dentry_mark. But if the parent is missing (e.g. killed by fsck),
recover will break. But those recovered dirty pages are not cleanup.
This will hit f2fs_bug_on:

[   53.519566] F2FS-fs (loop0): Found nat_bits in checkpoint
[   53.539354] F2FS-fs (loop0): recover_inode: ino = 5, name = file, inline = 3
[   53.539402] F2FS-fs (loop0): recover_dentry: ino = 5, name = file, dir = 0, 
err = -2
[   53.545760] F2FS-fs (loop0): Cannot recover all fsync data errno=-2
[   53.546105] F2FS-fs (loop0): access invalid blkaddr:4294967295
[   53.546171] WARNING: CPU: 1 PID: 1798 at fs/f2fs/checkpoint.c:163 
f2fs_is_valid_blkaddr+0x26c/0x320
[   53.546174] Modules linked in:
[   53.546183] CPU: 1 PID: 1798 Comm: mount Not tainted 4.19.0-rc2+ #1
[   53.546186] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS 
VirtualBox 12/01/2006
[   53.546191] RIP: 0010:f2fs_is_valid_blkaddr+0x26c/0x320
[   53.546195] Code: 85 bb 00 00 00 48 89 df 88 44 24 07 e8 ad a8 db ff 48 8b 
3b 44 89 e1 48 c7 c2 40 03 72 a9 48 c7 c6 e0 01 72 a9 e8 84 3c ff ff <0f> 0b 0f 
b6 44 24 07 e9 8a 00 00 00 48 8d bf 38 01 00 00 e8 7c a8
[   53.546201] RSP: 0018:88006c067768 EFLAGS: 00010282
[   53.546208] RAX:  RBX: 880068844200 RCX: a83e1a33
[   53.546211] RDX:  RSI: 0008 RDI: 88006d51e590
[   53.546215] RBP: 0005 R08: ed000daa3cb3 R09: ed000daa3cb3
[   53.546218] R10: 0001 R11: ed000daa3cb2 R12: 
[   53.546221] R13: 88006a1f8000 R14: 0200 R15: 0009
[   53.546226] FS:  7fb2f3646840() GS:88006d50() 
knlGS:
[   53.546229] CS:  0010 DS:  ES:  CR0: 80050033
[   53.546234] CR2: 7f0fd77f0008 CR3: 687e6002 CR4: 000206e0
[   53.546237] DR0:  DR1:  DR2: 
[   53.546240] DR3:  DR6: fffe0ff0 DR7: 0400
[   53.546242] Call Trace:
[   53.546248]  f2fs_submit_page_bio+0x95/0x740
[   53.546253]  read_node_page+0x161/0x1e0
[   53.546271]  ? truncate_node+0x650/0x650
[   53.546283]  ? add_to_page_cache_lru+0x12c/0x170
[   53.546288]  ? pagecache_get_page+0x262/0x2d0
[   53.546292]  __get_node_page+0x200/0x660
[   53.546302]  f2fs_update_inode_page+0x4a/0x160
[   53.546306]  f2fs_write_inode+0x86/0xb0
[   53.546317]  __writeback_single_inode+0x49c/0x620
[   53.546322]  writeback_single_inode+0xe4/0x1e0
[   53.546326]  sync_inode_metadata+0x93/0xd0
[   53.546330]  ? sync_inode+0x10/0x10
[   53.546342]  ? do_raw_spin_unlock+0xed/0x100
[   53.546347]  f2fs_sync_inode_meta+0xe0/0x130
[   53.546351]  f2fs_fill_super+0x287d/0x2d10
[   53.546367]  ? vsnprintf+0x742/0x7a0
[   53.546372]  ? f2fs_commit_super+0x180/0x180
[   53.546379]  ? up_write+0x20/0x40
[   53.546385]  ? set_blocksize+0x5f/0x140
[   53.546391]  ? f2fs_commit_super+0x180/0x180
[   53.546402]  mount_bdev+0x181/0x200
[   53.546406]  mount_fs+0x94/0x180
[   53.546411]  vfs_kern_mount+0x6c/0x1e0
[   53.546415]  do_mount+0xe5e/0x1510
[   53.546420]  ? fs_reclaim_release+0x9/0x30
[   53.546424]  ? copy_mount_string+0x20/0x20
[   53.546428]  ? fs_reclaim_acquire+0xd/0x30
[   53.546435]  ? __might_sleep+0x2c/0xc0
[   53.546440]  ? ___might_sleep+0x53/0x170
[   53.546453]  ? __might_fault+0x4c/0x60
[   53.546468]  ? _copy_from_user+0x95/0xa0
[   53.546474]  ? memdup_user+0x39/0x60
[   53.546478]  ksys_mount+0x88/0xb0
[   53.546482]  __x64_sys_mount+0x5d/0x70
[   53.546495]  do_syscall_64+0x65/0x130
[   53.546503]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   53.547639] ---[ end trace b804d1ea2fec893e ]---

So if recover fails, we need to drop all recovered data.

Signed-off-by: Sheng Yong 
---
 fs/f2fs/recovery.c | 19 ---
 fs/f2fs/super.c| 15 ++-
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index fb24a6d734e9..064b91544a84 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -96,8 +96,12 @@ static struct fsync_inode_entry *add_fsync_inode(struct 
f2fs_sb_info *sbi,
return ERR_PTR(err);
 }
 
-static void del_fsync_inode(struct fsync_inode_entry *entry)
+static void del_fsync_inode(struct fsync_inode_entry *entry, int drop)
 {
+   if (drop) {
+   make_bad_inode(entry->inode);
+   f2fs_inode_synced(entry->inode);
+   }
iput(entry->inode);
list_del(>list);
kmem_cache_free(fsync_entry_slab, entry);
@@ -337,12 +341,12 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, 
struct list_head *head,
return err;
 }
 
-static void destroy_fsync_dnodes(struct list_head *head)
+static void destroy_fsync_dnodes(struct list_head *head, int drop)
 {
struct fsync_inode_entry *entry, *tmp;
 
list_for_each_entry_safe(entry, tmp, head, list)
-   del

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

2018-09-18 Thread Sheng Yong

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.

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_FLAG0x0800
  #define CP_LARGE_NAT_BITMAP_FLAG  0x0400
  #define CP_NOCRC_RECOVERY_FLAG0x0200
  #define CP_TRIMMED_FLAG   0x0100





___
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-08-29 Thread Sheng Yong

Hi, Chao

On 2018/8/29 20:09, 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.


Do we need to drop recovery data? Recovery data is never checked by fsck,
if fsck tries to rebuild quota, it needs to allocate blocks from cursegs,
this may overwrite data blocks which may be recovered latter.

thanks

Signed-off-by: Chao Yu 
---
  fsck/fsck.c   | 3 ++-
  fsck/mount.c  | 6 --
  include/f2fs_fs.h | 2 ++
  lib/libf2fs.c | 2 ++
  4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index f080d3c8741c..10b69ef403ef 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -2668,7 +2668,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/mount.c b/fsck/mount.c
index a2448e370c0b..168cf387991f 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)
@@ -2532,8 +2534,8 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
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_FLAG0x0800
  #define CP_LARGE_NAT_BITMAP_FLAG  0x0400
  #define CP_NOCRC_RECOVERY_FLAG0x0200
  #define CP_TRIMMED_FLAG   0x0100
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index a1f8beb1f78d..192b8125de36 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -619,6 +619,8 @@ void f2fs_init_configuration(void)
/* default root owner */
c.root_uid = getuid();
c.root_gid = getgid();
+
+   c.quota_fix = 1;
  }
  
  #ifdef HAVE_SETMNTENT





--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: wake up gc thread immediately when gc_urgent is set

2018-08-04 Thread Sheng Yong
Fixes: 5b0e95398e2b ("f2fs: introduce sbi->gc_mode to determine the policy")
Signed-off-by: Sheng Yong 
---
 fs/f2fs/sysfs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index f22782a0defe..cd2e030e47b8 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -253,6 +253,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
if (t >= 1) {
sbi->gc_mode = GC_URGENT;
if (sbi->gc_thread) {
+   sbi->gc_thread->gc_wake = 1;
wake_up_interruptible_all(
>gc_thread->gc_wait_queue_head);
wake_up_discard_thread(sbi, true);
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] f2fs: check total CP pack block count correctly

2018-08-01 Thread Sheng Yong




On 2018/8/1 18:26, Chao Yu wrote:

On 2018/8/1 15:36, Sheng Yong wrote:



On 2018/8/1 14:56, Chao Yu wrote:

Hi Sheng,

On 2018/8/1 11:46, Sheng Yong wrote:

Fixes: 652d19558a347 ('f2fs: fix to do sanity check with block address in main 
area')
Reported-by: Zhang Xiaobo 
Signed-off-by: Sheng Yong 


That's my bad, and thanks for the fix.

Do you mind merge this into buggy patch, since the patch has not been upstreamed
yet.


No, of course not :)

Thanks,



Thanks,


---
   fs/f2fs/checkpoint.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 3587aa53dc90..c32ee10a1384 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -809,7 +809,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
goto invalid_cp1;
   
   	if (le32_to_cpu(cp_block->cp_pack_total_block_count) >

-   sbi->log_blocks_per_seg) {
+   sbi->blocks_per_seg - 1) {


actually, cp_pack_total_block_count can be sbi->blocks_per_seg?


Oh, right, it can be sbi->blocks_per_seg :)

Thanks

Thanks,


f2fs_msg(sbi->sb, KERN_WARNING,
"invalid cp_pack_total_block_count:%u",
le32_to_cpu(cp_block->cp_pack_total_block_count));




.




.




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] f2fs: check total CP pack block count correctly

2018-08-01 Thread Sheng Yong




On 2018/8/1 14:56, Chao Yu wrote:

Hi Sheng,

On 2018/8/1 11:46, Sheng Yong wrote:

Fixes: 652d19558a347 ('f2fs: fix to do sanity check with block address in main 
area')
Reported-by: Zhang Xiaobo 
Signed-off-by: Sheng Yong 


That's my bad, and thanks for the fix.

Do you mind merge this into buggy patch, since the patch has not been upstreamed
yet.


No, of course not :)

Thanks,



Thanks,


---
  fs/f2fs/checkpoint.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 3587aa53dc90..c32ee10a1384 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -809,7 +809,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
goto invalid_cp1;
  
  	if (le32_to_cpu(cp_block->cp_pack_total_block_count) >

-   sbi->log_blocks_per_seg) {
+   sbi->blocks_per_seg - 1) {
f2fs_msg(sbi->sb, KERN_WARNING,
"invalid cp_pack_total_block_count:%u",
le32_to_cpu(cp_block->cp_pack_total_block_count));




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: check total CP pack block count correctly

2018-07-31 Thread Sheng Yong
Fixes: 652d19558a347 ('f2fs: fix to do sanity check with block address in main 
area')
Reported-by: Zhang Xiaobo 
Signed-off-by: Sheng Yong 
---
 fs/f2fs/checkpoint.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 3587aa53dc90..c32ee10a1384 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -809,7 +809,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
goto invalid_cp1;
 
if (le32_to_cpu(cp_block->cp_pack_total_block_count) >
-   sbi->log_blocks_per_seg) {
+   sbi->blocks_per_seg - 1) {
f2fs_msg(sbi->sb, KERN_WARNING,
"invalid cp_pack_total_block_count:%u",
le32_to_cpu(cp_block->cp_pack_total_block_count));
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] fsck.f2fs: rebuild qf_ino if quota node is corrupted

2018-07-27 Thread Sheng Yong




On 2018/7/27 17:23, Jaegeuk Kim wrote:

On 07/24, Sheng Yong wrote:

Hi, Jaegeuk

On 2018/7/23 20:49, Jaegeuk Kim wrote:

On 07/23, Sheng Yong wrote:

If a quota node is corrupted, it may be removed. But its qf_ino in
super blocks is not cleared. To keep quota feature available, let's
try to rebuild a new quota node.


Hi Sheng,

IIRC, we need to rebuild whole quota structures, no?


I'm afraid not. Fsck records all dquot entries to a dict during checking all 
files.
If a quota file is removed or quota content is corrupted, quota_write_inode (in
fsck_chk_quota_files) will rebuild quota structures for us according to data 
recorded
in the dict. We only have to make sure the inode of a quota file is correct.

In the scenario where a quota file is removed, I think, rebuilding the inode of 
the
unreachable quota file is enough. Am I missing something?


Ahha, got the point. Can we consider trying this iff there is no error found in
other areas? I'm not slightly sure whether we can get a valid node block to 
store
the new node. If it's wrong, we're going to corrupt the partition more.


Right, we must be careful when allocating blocks in fsck. I think 
reserve_new_block(),
called by fsck, should have more check to ensure blkaddr is really free. I'll 
try to
fix that.

thanks



Thanks,



thanks,
Sheng


Thanks,



Signed-off-by: Sheng Yong 
---
   fsck/fsck.c  | 82 +---
   fsck/fsck.h  |  1 +
   fsck/mount.c |  7 +++--
   3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index e95dedf..dd10182 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
*/
   #include "fsck.h"
   #include "quotaio.h"
+#include "quotaio_v2.h"
   #include 
   char *tree_mark;
@@ -1697,13 +1698,80 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
}
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_REG_FILE, TYPE_INODE, _cnt, NULL);
-   if (ret)
-   ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
-   qtype, ino);
+   if (ret) {
+   /* sanity_check_nid failed, node should be removed */
+   ASSERT_MSG("[0x%x] wrong quota inode", ino);
+   if (c.fix_on)
+   F2FS_FSCK(sbi)->corrupt_quotas = 1 << qtype;
+   }
}
return ret;
   }
+static nid_t prepare_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)
+{
+   struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+   struct f2fs_summary sum;
+   struct f2fs_node *qf_node;
+   nid_t nid = QUOTA_INO(F2FS_RAW_SUPER(sbi), qtype);
+   block_t node_blkaddr;
+   int ret;
+
+   DBG(1, "Rebuild Quota file (qtype [%3d] ino [0x%x])\n", qtype, nid);
+
+   qf_node = calloc(F2FS_BLKSIZE, 1);
+   if (!qf_node) {
+   MSG(0, "\tError: calloc failed for qf_inode!!!\n");
+   return 0;
+   }
+
+   /* prepare qf_node */
+   qf_node->footer.nid = cpu_to_le32(nid);
+   qf_node->footer.ino = cpu_to_le32(nid);
+   qf_node->footer.cp_ver = cpu_to_le64(get_cp(checkpoint_ver));
+
+   qf_node->i.i_mode = cpu_to_le16(0x8180);
+   qf_node->i.i_links = cpu_to_le32(1);
+   qf_node->i.i_uid = cpu_to_le32(getuid());
+   qf_node->i.i_gid = cpu_to_le32(getgid());
+   qf_node->i.i_size = 0;
+   qf_node->i.i_blocks = 1;
+   qf_node->i.i_atime = cpu_to_le32(time(NULL));
+   qf_node->i.i_atime_nsec = 0;
+   qf_node->i.i_ctime = cpu_to_le32(time(NULL));
+   qf_node->i.i_ctime_nsec = 0;
+   qf_node->i.i_mtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_mtime_nsec = 0;
+   qf_node->i.i_generation = 0;
+   qf_node->i.i_xattr_nid = 0;
+   qf_node->i.i_flags = FS_IMMUTABLE_FL;
+   qf_node->i.i_current_depth = cpu_to_le32(1);
+   qf_node->i.i_dir_level = DEF_DIR_LEVEL;
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   qf_node->i.i_inline = F2FS_EXTRA_ATTR;
+   qf_node->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   }
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
+   qf_node->i.i_crtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_crtime_nsec = 0;
+   }
+
+   /* write back qf inode */
+   node_blkaddr = 0;
+   set_summary(, nid, 0, 0);
+   reserve_new_block(sbi, _blkaddr, , CURSEG_HOT_NODE);
+   update_nat_blkaddr(sbi, nid, nid, node_blkaddr);
+   DBG(1, "Write new qf_node to blk %#x\n", node_blkaddr);
+
+   ret = dev_write_block(qf_node, node_blkaddr);


Ah.. It should be writ

[f2fs-dev] [RFC PATCH v2] fsck.f2fs: rebuild qf_ino if quota node is unreachable

2018-07-26 Thread Sheng Yong
If a quota node is corrupted, it may be unreachable. But its qf_ino in
super blocks is not cleared. To keep quota feature available, let's try
to rebuild a new quota node.

Disk quota entries are written back according to data recorded in
the dict. quota_write_inode() will help to rebuild all quota structures
later.

Signed-off-by: Sheng Yong 
---
v2->v1: calculate inode checksum when write quota inode, update commit msg
---
 fsck/fsck.c  | 82 +---
 fsck/fsck.h  |  1 +
 fsck/mount.c |  7 +++--
 3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index e95dedf..5e68c1e 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
  */
 #include "fsck.h"
 #include "quotaio.h"
+#include "quotaio_v2.h"
 #include 
 
 char *tree_mark;
@@ -1697,13 +1698,80 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
}
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_REG_FILE, TYPE_INODE, _cnt, NULL);
-   if (ret)
-   ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
-   qtype, ino);
+   if (ret) {
+   /* sanity_check_nid failed, node should be removed */
+   ASSERT_MSG("[0x%x] wrong quota inode", ino);
+   if (c.fix_on)
+   F2FS_FSCK(sbi)->corrupt_quotas = 1 << qtype;
+   }
}
return ret;
 }
 
+static nid_t prepare_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)
+{
+   struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+   struct f2fs_summary sum;
+   struct f2fs_node *qf_node;
+   nid_t nid = QUOTA_INO(F2FS_RAW_SUPER(sbi), qtype);
+   block_t node_blkaddr;
+
+   DBG(1, "Rebuild Quota file (qtype [%3d] ino [0x%x])\n", qtype, nid);
+
+   qf_node = calloc(F2FS_BLKSIZE, 1);
+   if (!qf_node) {
+   MSG(0, "\tError: calloc failed for qf_inode!!!\n");
+   return 0;
+   }
+
+   /* prepare qf_node */
+   qf_node->footer.nid = cpu_to_le32(nid);
+   qf_node->footer.ino = cpu_to_le32(nid);
+   qf_node->footer.cp_ver = cpu_to_le64(get_cp(checkpoint_ver));
+
+   qf_node->i.i_mode = cpu_to_le16(0x8180);
+   qf_node->i.i_links = cpu_to_le32(1);
+   qf_node->i.i_uid = cpu_to_le32(getuid());
+   qf_node->i.i_gid = cpu_to_le32(getgid());
+   qf_node->i.i_size = 0;
+   qf_node->i.i_blocks = 1;
+   qf_node->i.i_atime = cpu_to_le32(time(NULL));
+   qf_node->i.i_atime_nsec = 0;
+   qf_node->i.i_ctime = cpu_to_le32(time(NULL));
+   qf_node->i.i_ctime_nsec = 0;
+   qf_node->i.i_mtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_mtime_nsec = 0;
+   qf_node->i.i_generation = 0;
+   qf_node->i.i_xattr_nid = 0;
+   qf_node->i.i_flags = FS_IMMUTABLE_FL;
+   qf_node->i.i_current_depth = cpu_to_le32(1);
+   qf_node->i.i_dir_level = DEF_DIR_LEVEL;
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   qf_node->i.i_inline = F2FS_EXTRA_ATTR;
+   qf_node->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   }
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
+   qf_node->i.i_crtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_crtime_nsec = 0;
+   }
+
+   /* write back qf inode */
+   node_blkaddr = 0;
+   set_summary(, nid, 0, 0);
+   reserve_new_block(sbi, _blkaddr, , CURSEG_HOT_NODE);
+   update_nat_blkaddr(sbi, nid, nid, node_blkaddr);
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+   qf_node->i.i_inode_checksum =
+   cpu_to_le32(f2fs_inode_chksum(qf_node));
+   ASSERT(dev_write_block(qf_node, node_blkaddr) >= 0);
+   DBG(1, "Write new qf_node to blk %#x\n", node_blkaddr);
+   f2fs_clear_bit(nid, F2FS_FSCK(sbi)->nat_area_bitmap);
+
+   free(qf_node);
+   return nid;
+}
+
 int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -1722,6 +1790,12 @@ int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
if (!ino)
continue;
 
+   if (fsck->corrupt_quotas & (1 << qtype) && c.fix_on) {
+   ino = prepare_rebuild_qf_inode(sbi, qtype);
+   if (!ino)
+   continue;
+   }
+
DBG(1, "Checking Quota file ([%3d] ino [0x%x])\n", qtype, ino);
needs_writeout = 0;
ret = quota_compare_and_update(sbi, qtype, _wr

Re: [f2fs-dev] [PATCH] f2fs: quota: remove journalled project quota

2018-07-26 Thread Sheng Yong

Hi, Chao

On 2018/7/26 19:38, Chao Yu wrote:

On 2018/7/26 19:25, Sheng Yong wrote:

Quota sysfiles are already using journalled method to save quota value.
And non-journalled project quota is not supported by userspace tools. So
there is no need to implement journalled project quota.


Well, when quota_ino is not supported yet, I wrote patch for quota-tools to
enable project quota file support for test, but have not upstreamed them yet, so
I'd like to keep those codes, how do you think?


OK. I agree to keep them if there will be user visible project quota file in
the feature :)

thanks


Thanks,



Signed-off-by: Sheng Yong 
---
  Documentation/filesystems/f2fs.txt |  2 --
  fs/f2fs/super.c| 20 
  2 files changed, 22 deletions(-)

diff --git a/Documentation/filesystems/f2fs.txt 
b/Documentation/filesystems/f2fs.txt
index 69f8de995739..acfb95d0d655 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -167,11 +167,9 @@ grpquota   Enable plain group disk quota 
accounting.
  prjquota   Enable plain project quota accounting.
  usrjquota=   Appoint specified file and type during mount, so that 
quota
  grpjquota=   information can be properly updated during recovery 
flow,
-prjjquota=   : must be in root directory;
  jqfmt= : [vfsold,vfsv0,vfsv1].
  offusrjquota   Turn off user journelled quota.
  offgrpjquota   Turn off group journelled quota.
-offprjjquota   Turn off project journelled quota.
  quota  Enable plain user disk quota accounting.
  noquotaDisable all plain disk quota option.
  whint_mode=%s  Control which write hints are passed down to block
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 6ad0414ba303..c683952fe6e6 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -121,10 +121,8 @@ enum {
Opt_prjquota,
Opt_usrjquota,
Opt_grpjquota,
-   Opt_prjjquota,
Opt_offusrjquota,
Opt_offgrpjquota,
-   Opt_offprjjquota,
Opt_jqfmt_vfsold,
Opt_jqfmt_vfsv0,
Opt_jqfmt_vfsv1,
@@ -178,10 +176,8 @@ static match_table_t f2fs_tokens = {
{Opt_prjquota, "prjquota"},
{Opt_usrjquota, "usrjquota=%s"},
{Opt_grpjquota, "grpjquota=%s"},
-   {Opt_prjjquota, "prjjquota=%s"},
{Opt_offusrjquota, "usrjquota="},
{Opt_offgrpjquota, "grpjquota="},
-   {Opt_offprjjquota, "prjjquota="},
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
@@ -639,11 +635,6 @@ static int parse_options(struct super_block *sb, char 
*options)
if (ret)
return ret;
break;
-   case Opt_prjjquota:
-   ret = f2fs_set_qf_name(sb, PRJQUOTA, [0]);
-   if (ret)
-   return ret;
-   break;
case Opt_offusrjquota:
ret = f2fs_clear_qf_name(sb, USRQUOTA);
if (ret)
@@ -654,11 +645,6 @@ static int parse_options(struct super_block *sb, char 
*options)
if (ret)
return ret;
break;
-   case Opt_offprjjquota:
-   ret = f2fs_clear_qf_name(sb, PRJQUOTA);
-   if (ret)
-   return ret;
-   break;
case Opt_jqfmt_vfsold:
F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_OLD;
break;
@@ -681,10 +667,8 @@ static int parse_options(struct super_block *sb, char 
*options)
case Opt_prjquota:
case Opt_usrjquota:
case Opt_grpjquota:
-   case Opt_prjjquota:
case Opt_offusrjquota:
case Opt_offgrpjquota:
-   case Opt_offprjjquota:
case Opt_jqfmt_vfsold:
case Opt_jqfmt_vfsv0:
case Opt_jqfmt_vfsv1:
@@ -1224,10 +1208,6 @@ static inline void f2fs_show_quota_options(struct 
seq_file *seq,
if (F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
seq_show_option(seq, "grpjquota",
F2FS_OPTION(sbi).s_qf_names[GRPQUOTA]);
-
-   if (F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
-   seq_show_option(seq, "prjjquota",
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]);
  #endif
  }
  




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_

[f2fs-dev] [PATCH] f2fs: quota: remove journalled project quota

2018-07-26 Thread Sheng Yong
Quota sysfiles are already using journalled method to save quota value.
And non-journalled project quota is not supported by userspace tools. So
there is no need to implement journalled project quota.

Signed-off-by: Sheng Yong 
---
 Documentation/filesystems/f2fs.txt |  2 --
 fs/f2fs/super.c| 20 
 2 files changed, 22 deletions(-)

diff --git a/Documentation/filesystems/f2fs.txt 
b/Documentation/filesystems/f2fs.txt
index 69f8de995739..acfb95d0d655 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -167,11 +167,9 @@ grpquota   Enable plain group disk quota 
accounting.
 prjquota   Enable plain project quota accounting.
 usrjquota=   Appoint specified file and type during mount, so that 
quota
 grpjquota=   information can be properly updated during recovery 
flow,
-prjjquota=   : must be in root directory;
 jqfmt= : [vfsold,vfsv0,vfsv1].
 offusrjquota   Turn off user journelled quota.
 offgrpjquota   Turn off group journelled quota.
-offprjjquota   Turn off project journelled quota.
 quota  Enable plain user disk quota accounting.
 noquotaDisable all plain disk quota option.
 whint_mode=%s  Control which write hints are passed down to block
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 6ad0414ba303..c683952fe6e6 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -121,10 +121,8 @@ enum {
Opt_prjquota,
Opt_usrjquota,
Opt_grpjquota,
-   Opt_prjjquota,
Opt_offusrjquota,
Opt_offgrpjquota,
-   Opt_offprjjquota,
Opt_jqfmt_vfsold,
Opt_jqfmt_vfsv0,
Opt_jqfmt_vfsv1,
@@ -178,10 +176,8 @@ static match_table_t f2fs_tokens = {
{Opt_prjquota, "prjquota"},
{Opt_usrjquota, "usrjquota=%s"},
{Opt_grpjquota, "grpjquota=%s"},
-   {Opt_prjjquota, "prjjquota=%s"},
{Opt_offusrjquota, "usrjquota="},
{Opt_offgrpjquota, "grpjquota="},
-   {Opt_offprjjquota, "prjjquota="},
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
@@ -639,11 +635,6 @@ static int parse_options(struct super_block *sb, char 
*options)
if (ret)
return ret;
break;
-   case Opt_prjjquota:
-   ret = f2fs_set_qf_name(sb, PRJQUOTA, [0]);
-   if (ret)
-   return ret;
-   break;
case Opt_offusrjquota:
ret = f2fs_clear_qf_name(sb, USRQUOTA);
if (ret)
@@ -654,11 +645,6 @@ static int parse_options(struct super_block *sb, char 
*options)
if (ret)
return ret;
break;
-   case Opt_offprjjquota:
-   ret = f2fs_clear_qf_name(sb, PRJQUOTA);
-   if (ret)
-   return ret;
-   break;
case Opt_jqfmt_vfsold:
F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_OLD;
break;
@@ -681,10 +667,8 @@ static int parse_options(struct super_block *sb, char 
*options)
case Opt_prjquota:
case Opt_usrjquota:
case Opt_grpjquota:
-   case Opt_prjjquota:
case Opt_offusrjquota:
case Opt_offgrpjquota:
-   case Opt_offprjjquota:
case Opt_jqfmt_vfsold:
case Opt_jqfmt_vfsv0:
case Opt_jqfmt_vfsv1:
@@ -1224,10 +1208,6 @@ static inline void f2fs_show_quota_options(struct 
seq_file *seq,
if (F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
seq_show_option(seq, "grpjquota",
F2FS_OPTION(sbi).s_qf_names[GRPQUOTA]);
-
-   if (F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
-   seq_show_option(seq, "prjjquota",
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]);
 #endif
 }
 
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v2] f2fs: quota: fix incorrect comments

2018-07-26 Thread Sheng Yong
Signed-off-by: Sheng Yong 
---
 fs/f2fs/checkpoint.c | 5 -
 fs/f2fs/super.c  | 5 +
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 04841f32d4d9..581710760ba6 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -661,7 +661,10 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
/* Needed for iput() to work correctly and not trash data */
sbi->sb->s_flags |= SB_ACTIVE;
 
-   /* Turn on quotas so that they are updated correctly */
+   /*
+* Turn on quotas which were not enabled for read-only mounts if
+* filesystem has quota feature, so that they are updated correctly.
+*/
quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
 #endif
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 7187885da251..6ad0414ba303 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2968,10 +2968,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
goto free_root_inode;
 
 #ifdef CONFIG_QUOTA
-   /*
-* Turn on quotas which were not enabled for read-only mounts if
-* filesystem has quota feature, so that they are updated correctly.
-*/
+   /* Enable quota usage during mount */
if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb)) {
err = f2fs_enable_quotas(sb);
if (err) {
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 3/3] f2fs: quota: fix incorrect error message and comments

2018-07-25 Thread Sheng Yong




On 2018/7/25 23:44, Chao Yu wrote:

On 2018/7/24 20:17, Sheng Yong wrote:

Signed-off-by: Sheng Yong 
---
  fs/f2fs/checkpoint.c | 5 -
  fs/f2fs/recovery.c   | 2 +-
  fs/f2fs/super.c  | 5 +
  3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 9c29526a7633..9a0222d9e28c 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -645,7 +645,10 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
/* Needed for iput() to work correctly and not trash data */
sbi->sb->s_flags |= SB_ACTIVE;
  
-	/* Turn on quotas so that they are updated correctly */

+   /*
+* Turn on quotas which were not enabled for read-only mounts if
+* filesystem has quota feature, so that they are updated correctly.
+*/
quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
  #endif
  
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c

index 0d927ae26c48..e93162a2e6d8 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -628,7 +628,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool 
check_only)
  #endif
  
  	if (s_flags & SB_RDONLY) {

-   f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs");
+   f2fs_msg(sbi->sb, KERN_INFO, "fsync data recover on readonly 
fs");


I remember Yunlei has fix this print info in another patch.



Hi, Chao,

I checked the list just now, yes, Yunlei has already submitted a patch to fix
the error message. Please ignore this :)

thanks


Thanks,


sbi->sb->s_flags &= ~SB_RDONLY;
}
  
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c

index 4ed91ceab3ee..3e24dde60f54 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2970,10 +2970,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
goto free_root_inode;
  
  #ifdef CONFIG_QUOTA

-   /*
-* Turn on quotas which were not enabled for read-only mounts if
-* filesystem has quota feature, so that they are updated correctly.
-*/
+   /* Enable quota usage during mount */
if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb)) {
err = f2fs_enable_quotas(sb);
if (err) {



.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH RESEND] f2fs: fix to restrict mount condition when without CONFIG_QUOTA

2018-07-25 Thread Sheng Yong

Hi, Chao

On 2018/7/26 7:19, Chao Yu wrote:

From: Chao Yu 

Like quota_ino feature, we need to reject mounting RDWR with image
which enables project_quota feature when there is no CONFIG_QUOTA
be set in kernel.

Signed-off-by: Chao Yu 
---
  fs/f2fs/super.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index dbc1cb53581f..bc7c14a055bb 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -775,6 +775,12 @@ static int parse_options(struct super_block *sb, char 
*options)
 "without CONFIG_QUOTA");
return -EINVAL;
}


I think the following should be checked within !CONFIG_QUOTA, like patch "f2fs: 
quota: do
not mount as RDWR without QUOTA if quota feature enabled" :)

thanks


+   if (f2fs_sb_has_project_quota(sbi->sb) && !f2fs_readonly(sbi->sb)) {
+   f2fs_msg(sb, KERN_ERR,
+   "Filesystem with project quota feature cannot be "
+   "mounted RDWR without CONFIG_QUOTA");
+   return -EINVAL;
+   }
  #endif
  
  	if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) {





--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/3] f2fs: quota: decrease the lock granularity of statfs_project

2018-07-24 Thread Sheng Yong
According to fs/quota/dquot.c, `dq_data_lock' protects mem_dqinfo
structures and modifications of dquot pointers in the inode, and
`dquot->dq_dqb_lock' protects data from dq_dqb.

We should use dquot->dq_dqb_lock in statfs_project instead of
dq_dat_lock.

Signed-off-by: Sheng Yong 
---
 fs/f2fs/super.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 796a2d756572..4ed91ceab3ee 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1118,7 +1118,7 @@ static int f2fs_statfs_project(struct super_block *sb,
dquot = dqget(sb, qid);
if (IS_ERR(dquot))
return PTR_ERR(dquot);
-   spin_lock(_data_lock);
+   spin_lock(>dq_dqb_lock);
 
limit = (dquot->dq_dqb.dqb_bsoftlimit ?
 dquot->dq_dqb.dqb_bsoftlimit :
@@ -1141,7 +1141,7 @@ static int f2fs_statfs_project(struct super_block *sb,
 (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
}
 
-   spin_unlock(_data_lock);
+   spin_unlock(>dq_dqb_lock);
dqput(dquot);
return 0;
 }
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 1/3] f2fs: quota: do not mount as RDWR without QUOTA if quota feature enabled

2018-07-24 Thread Sheng Yong
If quota feature is enabled, quota is on by default. However, if
CONFIG_QUOTA is not built in kernel, dquot entries will not get updated,
which leads to quota inconsistency.

Signed-off-by: Sheng Yong 
---
 fs/f2fs/super.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 0a8e12662174..796a2d756572 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -346,12 +346,6 @@ static int f2fs_check_quota_options(struct f2fs_sb_info 
*sbi)
"QUOTA feature is enabled, so ignore jquota_fmt");
F2FS_OPTION(sbi).s_jquota_fmt = 0;
}
-   if (f2fs_sb_has_quota_ino(sbi->sb) && f2fs_readonly(sbi->sb)) {
-   f2fs_msg(sbi->sb, KERN_INFO,
-"Filesystem with quota feature cannot be mounted RDWR "
-"without CONFIG_QUOTA");
-   return -1;
-   }
return 0;
 }
 #endif
@@ -774,6 +768,13 @@ static int parse_options(struct super_block *sb, char 
*options)
 #ifdef CONFIG_QUOTA
if (f2fs_check_quota_options(sbi))
return -EINVAL;
+#else
+   if (f2fs_sb_has_quota_ino(sbi->sb) && !f2fs_readonly(sbi->sb)) {
+   f2fs_msg(sbi->sb, KERN_INFO,
+"Filesystem with quota feature cannot be mounted RDWR "
+"without CONFIG_QUOTA");
+   return -EINVAL;
+   }
 #endif
 
if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) {
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/3] f2fs: quota: fix incorrect error message and comments

2018-07-24 Thread Sheng Yong
Signed-off-by: Sheng Yong 
---
 fs/f2fs/checkpoint.c | 5 -
 fs/f2fs/recovery.c   | 2 +-
 fs/f2fs/super.c  | 5 +
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 9c29526a7633..9a0222d9e28c 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -645,7 +645,10 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
/* Needed for iput() to work correctly and not trash data */
sbi->sb->s_flags |= SB_ACTIVE;
 
-   /* Turn on quotas so that they are updated correctly */
+   /*
+* Turn on quotas which were not enabled for read-only mounts if
+* filesystem has quota feature, so that they are updated correctly.
+*/
quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
 #endif
 
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 0d927ae26c48..e93162a2e6d8 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -628,7 +628,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool 
check_only)
 #endif
 
if (s_flags & SB_RDONLY) {
-   f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs");
+   f2fs_msg(sbi->sb, KERN_INFO, "fsync data recover on readonly 
fs");
sbi->sb->s_flags &= ~SB_RDONLY;
}
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4ed91ceab3ee..3e24dde60f54 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2970,10 +2970,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
goto free_root_inode;
 
 #ifdef CONFIG_QUOTA
-   /*
-* Turn on quotas which were not enabled for read-only mounts if
-* filesystem has quota feature, so that they are updated correctly.
-*/
+   /* Enable quota usage during mount */
if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb)) {
err = f2fs_enable_quotas(sb);
if (err) {
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] fsck.f2fs: rebuild qf_ino if quota node is corrupted

2018-07-23 Thread Sheng Yong

Hi, Jaegeuk

On 2018/7/23 20:49, Jaegeuk Kim wrote:

On 07/23, Sheng Yong wrote:

If a quota node is corrupted, it may be removed. But its qf_ino in
super blocks is not cleared. To keep quota feature available, let's
try to rebuild a new quota node.


Hi Sheng,

IIRC, we need to rebuild whole quota structures, no?


I'm afraid not. Fsck records all dquot entries to a dict during checking all 
files.
If a quota file is removed or quota content is corrupted, quota_write_inode (in
fsck_chk_quota_files) will rebuild quota structures for us according to data 
recorded
in the dict. We only have to make sure the inode of a quota file is correct.

In the scenario where a quota file is removed, I think, rebuilding the inode of 
the
unreachable quota file is enough. Am I missing something?

thanks,
Sheng


Thanks,



Signed-off-by: Sheng Yong 
---
  fsck/fsck.c  | 82 +---
  fsck/fsck.h  |  1 +
  fsck/mount.c |  7 +++--
  3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index e95dedf..dd10182 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
   */
  #include "fsck.h"
  #include "quotaio.h"
+#include "quotaio_v2.h"
  #include 
  
  char *tree_mark;

@@ -1697,13 +1698,80 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
}
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_REG_FILE, TYPE_INODE, _cnt, NULL);
-   if (ret)
-   ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
-   qtype, ino);
+   if (ret) {
+   /* sanity_check_nid failed, node should be removed */
+   ASSERT_MSG("[0x%x] wrong quota inode", ino);
+   if (c.fix_on)
+   F2FS_FSCK(sbi)->corrupt_quotas = 1 << qtype;
+   }
}
return ret;
  }
  
+static nid_t prepare_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)

+{
+   struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+   struct f2fs_summary sum;
+   struct f2fs_node *qf_node;
+   nid_t nid = QUOTA_INO(F2FS_RAW_SUPER(sbi), qtype);
+   block_t node_blkaddr;
+   int ret;
+
+   DBG(1, "Rebuild Quota file (qtype [%3d] ino [0x%x])\n", qtype, nid);
+
+   qf_node = calloc(F2FS_BLKSIZE, 1);
+   if (!qf_node) {
+   MSG(0, "\tError: calloc failed for qf_inode!!!\n");
+   return 0;
+   }
+
+   /* prepare qf_node */
+   qf_node->footer.nid = cpu_to_le32(nid);
+   qf_node->footer.ino = cpu_to_le32(nid);
+   qf_node->footer.cp_ver = cpu_to_le64(get_cp(checkpoint_ver));
+
+   qf_node->i.i_mode = cpu_to_le16(0x8180);
+   qf_node->i.i_links = cpu_to_le32(1);
+   qf_node->i.i_uid = cpu_to_le32(getuid());
+   qf_node->i.i_gid = cpu_to_le32(getgid());
+   qf_node->i.i_size = 0;
+   qf_node->i.i_blocks = 1;
+   qf_node->i.i_atime = cpu_to_le32(time(NULL));
+   qf_node->i.i_atime_nsec = 0;
+   qf_node->i.i_ctime = cpu_to_le32(time(NULL));
+   qf_node->i.i_ctime_nsec = 0;
+   qf_node->i.i_mtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_mtime_nsec = 0;
+   qf_node->i.i_generation = 0;
+   qf_node->i.i_xattr_nid = 0;
+   qf_node->i.i_flags = FS_IMMUTABLE_FL;
+   qf_node->i.i_current_depth = cpu_to_le32(1);
+   qf_node->i.i_dir_level = DEF_DIR_LEVEL;
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   qf_node->i.i_inline = F2FS_EXTRA_ATTR;
+   qf_node->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   }
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
+   qf_node->i.i_crtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_crtime_nsec = 0;
+   }
+
+   /* write back qf inode */
+   node_blkaddr = 0;
+   set_summary(, nid, 0, 0);
+   reserve_new_block(sbi, _blkaddr, , CURSEG_HOT_NODE);
+   update_nat_blkaddr(sbi, nid, nid, node_blkaddr);
+   DBG(1, "Write new qf_node to blk %#x\n", node_blkaddr);
+
+   ret = dev_write_block(qf_node, node_blkaddr);


Ah.. It should be write_inode instead of dev_write_block.


+   ASSERT(ret >= 0);
+   f2fs_clear_bit(nid, F2FS_FSCK(sbi)->nat_area_bitmap);
+
+   free(qf_node);
+   return nid;
+}
+
  int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
  {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -1722,6 +1790,12 @@ int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
if (!ino)
continue;
  
+		if (fsck->corrupt_quotas & (1 << qtype) && c.fix_on) {

+

[f2fs-dev] [PATCH] fsck.f2fs: rebuild qf_ino if quota node is corrupted

2018-07-22 Thread Sheng Yong
If a quota node is corrupted, it may be removed. But its qf_ino in
super blocks is not cleared. To keep quota feature available, let's
try to rebuild a new quota node.

Signed-off-by: Sheng Yong 
---
 fsck/fsck.c  | 82 +---
 fsck/fsck.h  |  1 +
 fsck/mount.c |  7 +++--
 3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index e95dedf..dd10182 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
  */
 #include "fsck.h"
 #include "quotaio.h"
+#include "quotaio_v2.h"
 #include 
 
 char *tree_mark;
@@ -1697,13 +1698,80 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
}
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_REG_FILE, TYPE_INODE, _cnt, NULL);
-   if (ret)
-   ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
-   qtype, ino);
+   if (ret) {
+   /* sanity_check_nid failed, node should be removed */
+   ASSERT_MSG("[0x%x] wrong quota inode", ino);
+   if (c.fix_on)
+   F2FS_FSCK(sbi)->corrupt_quotas = 1 << qtype;
+   }
}
return ret;
 }
 
+static nid_t prepare_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)
+{
+   struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+   struct f2fs_summary sum;
+   struct f2fs_node *qf_node;
+   nid_t nid = QUOTA_INO(F2FS_RAW_SUPER(sbi), qtype);
+   block_t node_blkaddr;
+   int ret;
+
+   DBG(1, "Rebuild Quota file (qtype [%3d] ino [0x%x])\n", qtype, nid);
+
+   qf_node = calloc(F2FS_BLKSIZE, 1);
+   if (!qf_node) {
+   MSG(0, "\tError: calloc failed for qf_inode!!!\n");
+   return 0;
+   }
+
+   /* prepare qf_node */
+   qf_node->footer.nid = cpu_to_le32(nid);
+   qf_node->footer.ino = cpu_to_le32(nid);
+   qf_node->footer.cp_ver = cpu_to_le64(get_cp(checkpoint_ver));
+
+   qf_node->i.i_mode = cpu_to_le16(0x8180);
+   qf_node->i.i_links = cpu_to_le32(1);
+   qf_node->i.i_uid = cpu_to_le32(getuid());
+   qf_node->i.i_gid = cpu_to_le32(getgid());
+   qf_node->i.i_size = 0;
+   qf_node->i.i_blocks = 1;
+   qf_node->i.i_atime = cpu_to_le32(time(NULL));
+   qf_node->i.i_atime_nsec = 0;
+   qf_node->i.i_ctime = cpu_to_le32(time(NULL));
+   qf_node->i.i_ctime_nsec = 0;
+   qf_node->i.i_mtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_mtime_nsec = 0;
+   qf_node->i.i_generation = 0;
+   qf_node->i.i_xattr_nid = 0;
+   qf_node->i.i_flags = FS_IMMUTABLE_FL;
+   qf_node->i.i_current_depth = cpu_to_le32(1);
+   qf_node->i.i_dir_level = DEF_DIR_LEVEL;
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   qf_node->i.i_inline = F2FS_EXTRA_ATTR;
+   qf_node->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   }
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
+   qf_node->i.i_crtime = cpu_to_le32(time(NULL));
+   qf_node->i.i_crtime_nsec = 0;
+   }
+
+   /* write back qf inode */
+   node_blkaddr = 0;
+   set_summary(, nid, 0, 0);
+   reserve_new_block(sbi, _blkaddr, , CURSEG_HOT_NODE);
+   update_nat_blkaddr(sbi, nid, nid, node_blkaddr);
+   DBG(1, "Write new qf_node to blk %#x\n", node_blkaddr);
+
+   ret = dev_write_block(qf_node, node_blkaddr);
+   ASSERT(ret >= 0);
+   f2fs_clear_bit(nid, F2FS_FSCK(sbi)->nat_area_bitmap);
+
+   free(qf_node);
+   return nid;
+}
+
 int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -1722,6 +1790,12 @@ int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
if (!ino)
continue;
 
+   if (fsck->corrupt_quotas & (1 << qtype) && c.fix_on) {
+   ino = prepare_rebuild_qf_inode(sbi, qtype);
+   if (!ino)
+   continue;
+   }
+
DBG(1, "Checking Quota file ([%3d] ino [0x%x])\n", qtype, ino);
needs_writeout = 0;
ret = quota_compare_and_update(sbi, qtype, _writeout,
@@ -1733,7 +1807,7 @@ int fsck_chk_quota_files(struct f2fs_sb_info *sbi)
 
/* Something is wrong */
if (c.fix_on) {
-   DBG(0, "Fixing Quota file ([%3d] ino [0x%x])\n",
+   FIX_MSG("Fixing Quota file ([%3d] ino [0x%x])\n",
qtyp

[f2fs-dev] [PATCH] fsck.f2fs: init quota_file before re-create quota file

2018-07-11 Thread Sheng Yong
`quota_handle->qh_qf->filesize' is not initialized by quota_create_file().
It contains random value, which is updated to quota file's i_size in
quota_file_close(). Since quota file is re-created, `filesize' can be
initialized as 0.

Signed-off-by: Sheng Yong 
---
 fsck/quotaio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fsck/quotaio.c b/fsck/quotaio.c
index afadf56..26f8a71 100644
--- a/fsck/quotaio.c
+++ b/fsck/quotaio.c
@@ -160,6 +160,7 @@ errcode_t quota_file_create(struct f2fs_sb_info *sbi, 
struct quota_handle *h,
f2fs_ino_t qf_inum = sb->qf_ino[qtype];
errcode_t err = 0;
 
+   memset(>qh_qf, 0, sizeof(h->qh_qf));
h->qh_qf.sbi = sbi;
h->qh_qf.ino = qf_inum;
h->write = quota_write_nomount;
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs-tools: set namelen parameter of convert_encrypted_name as unsigned

2018-07-10 Thread Sheng Yong
To avoid overflow, set namelen parameter of convert_encrypted_name as
unsigned int. convert_encrypted_name() will check if namelen exceeds the
limitation.

Signed-off-by: Sheng Yong 
---
 fsck/fsck.c  | 6 +++---
 fsck/fsck.h  | 2 +-
 fsck/mount.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 6fd9dc2..f6fd1d8 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -657,7 +657,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
int ofs;
unsigned char *en;
-   int namelen;
+   u32 namelen;
unsigned int idx = 0;
int need_fix = 0;
int ret;
@@ -1139,7 +1139,7 @@ static int digest_encode(const char *src, int len, char 
*dst)
return cp - dst;
 }
 
-int convert_encrypted_name(unsigned char *name, int len,
+int convert_encrypted_name(unsigned char *name, u32 len,
unsigned char *new, int enc_name)
 {
if (!enc_name) {
@@ -1160,7 +1160,7 @@ static void print_dentry(__u32 depth, __u8 *name,
 {
int last_de = 0;
int next_idx = 0;
-   int name_len;
+   u32 name_len;
unsigned int i;
int bit_offset;
unsigned char new[F2FS_NAME_LEN + 1];
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 5530aff..185e157 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -145,7 +145,7 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *, struct 
f2fs_node *,
struct child_info *);
 int fsck_chk_meta(struct f2fs_sb_info *sbi);
 int fsck_chk_curseg_info(struct f2fs_sb_info *);
-int convert_encrypted_name(unsigned char *, int, unsigned char *, int);
+int convert_encrypted_name(unsigned char *, u32, unsigned char *, int);
 
 extern void update_free_segments(struct f2fs_sb_info *);
 void print_cp_state(u32);
diff --git a/fsck/mount.c b/fsck/mount.c
index 0767a8f..5040764 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -175,7 +175,7 @@ void print_inode_info(struct f2fs_sb_info *sbi,
struct f2fs_xattr_entry *ent;
unsigned char en[F2FS_NAME_LEN + 1];
unsigned int i = 0;
-   int namelen = le32_to_cpu(inode->i_namelen);
+   u32 namelen = le32_to_cpu(inode->i_namelen);
int enc_name = file_enc_name(inode);
int ofs = __get_extra_isize(inode);
 
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH v2] fsck.f2fs: fix to do sanity check with extra_attr feature

2018-07-09 Thread Sheng Yong

Hi, Chao,

On 2018/7/9 23:25, Chao Yu wrote:

From: Chao Yu 

This patch tries to fix incorrect extra_attr bit or i_extra_isize value
in fsck.

Signed-off-by: Chao Yu 
---
v2:
- fix to replace F2FS_INLINE_DATA with F2FS_EXTRA_ATTR.
  fsck/fsck.c | 18 +-
  1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 05a6301..36d1977 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -655,7 +655,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_size = le64_to_cpu(node_blk->i.i_size);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
-   int ofs = get_extra_isize(node_blk);
+   int ofs;
unsigned char *en;
int namelen;
unsigned int idx = 0;
@@ -719,6 +719,22 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK)
goto check;
  
+	if (f2fs_has_extra_isize(_blk->i)) {

+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   if (node_blk->i.i_extra_isize >
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE)) {
+   node_blk->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   need_fix = 1;
+   }
+   } else {
+   /* we don't support tuning F2FS_FEATURE_EXTRA_ATTR now 
*/
+   node_blk->i.i_inline |= ~F2FS_EXTRA_ATTR;


node_blk->i.i_inline &= ~F2FS_EXTRA_ATTR;

thanks :-)
.


+   need_fix = 1;
+   }
+   }
+   ofs = get_extra_isize(node_blk);
+
if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) {
if (le32_to_cpu(node_blk->i.i_addr[ofs]) != 0) {
/* should fix this bug all the time */




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] f2fs-tools: avoid mounting f2fs if tools already open the device

2018-07-09 Thread Sheng Yong

Hi, Chao,

On 2018/7/9 23:14, Chao Yu wrote:

On 2018/7/4 17:50, Sheng Yong wrote:

If the block device is opened by tools, F2FS should not be mounted.
Especially when fsck is running, errors unexpected may happen. So if
tools open a block device, we give it the O_EXCL flag to make sure
the block device is opened exclusivly.


Should we treat block inode and regular inode as the same?


I'm afraid not, the behavior of O_EXCL is not defined for regular inode
if it is used without O_CREAT. If f2fs is installed in a image file (not
a block device), we may still find a another way to avoid fsck and f2fs
run concurrently :(

thanks


Not sure about this, since for debuging, if we can't umount due to panic in
f2fs, still we can dump last data in device.

Thanks,



Signed-off-by: Sheng Yong 
---
  lib/libf2fs.c | 27 +--
  1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index b25fbf2..5625cff 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -783,21 +783,35 @@ int get_device_info(int i)
  #endif
struct device_info *dev = c.devices + i;
  
+	stat_buf = malloc(sizeof(struct stat));

+   ASSERT(stat_buf);
+   if (stat(dev->path, stat_buf) < 0 ) {
+   MSG(0, "\tError: Failed to get the device stat!\n");
+   free(stat_buf);
+   return -1;
+   }
+
if (c.sparse_mode) {
-   fd = open((char *)dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
+   fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
} else {
-   fd = open((char *)dev->path, O_RDWR);
+   if (S_ISBLK(stat_buf->st_mode))
+   fd = open(dev->path, O_RDWR | O_EXCL);
+   else
+   fd = open(dev->path, O_RDWR);
}
if (fd < 0) {
MSG(0, "\tError: Failed to open the device!\n");
+   free(stat_buf);
return -1;
}
  
  	dev->fd = fd;
  
  	if (c.sparse_mode) {

-   if (f2fs_init_sparse_file())
+   if (f2fs_init_sparse_file()) {
+   free(stat_buf);
return -1;
+   }
}
  
  	if (c.kd == -1) {

@@ -810,13 +824,6 @@ int get_device_info(int i)
}
}
  
-	stat_buf = malloc(sizeof(struct stat));

-   if (fstat(fd, stat_buf) < 0 ) {
-   MSG(0, "\tError: Failed to get the device stat!\n");
-   free(stat_buf);
-   return -1;
-   }
-
if (c.sparse_mode) {
dev->total_sectors = c.device_size / dev->sector_size;
} else if (S_ISREG(stat_buf->st_mode)) {



.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 2/2] fsck.f2fs: check extra_attr feature

2018-07-08 Thread Sheng Yong




On 2018/7/9 10:15, Chao Yu wrote:

Hi Sheng,

On 2018/7/3 18:10, Sheng Yong wrote:

Check extra_attr feature for inode. If it is corrupted, remove the
inode.


Could you check the patch:

[PATCH] fsck.f2fs: fix to do sanity check with extra_attr feature

Would it better to do sanity check with it in fsck_chk_inode_blk? since it is
about consistence of inode instead of nid.



Agree. And the patch has already checked the value of i_extra_isize, so this one
can be dropped :-)

Thanks


Thanks,



Link: https://bugzilla.kernel.org/show_bug.cgi?id=200219
Reported-by: Wen Xu 
Signed-off-by: Sheng Yong 
---
  fsck/fsck.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 15264b2..acbe25d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -460,6 +460,12 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
__check_inode_mode(nid, ftype, le32_to_cpu(node_blk->i.i_mode)))
return -EINVAL;
  
+	if (ntype == TYPE_INODE &&

+   ((f2fs_has_extra_isize(_blk->i) &&
+ !(c.feature & F2FS_FEATURE_EXTRA_ATTR)) ||
+get_extra_isize(node_blk) >= DEF_ADDRS_PER_INODE))
+   return -EINVAL;
+
/* workaround to fix later */
if (ftype != F2FS_FT_ORPHAN ||
f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs-tools: avoid mounting f2fs if tools already open the device

2018-07-04 Thread Sheng Yong
If the block device is opened by tools, F2FS should not be mounted.
Especially when fsck is running, errors unexpected may happen. So if
tools open a block device, we give it the O_EXCL flag to make sure
the block device is opened exclusivly.

Signed-off-by: Sheng Yong 
---
 lib/libf2fs.c | 27 +--
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index b25fbf2..5625cff 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -783,21 +783,35 @@ int get_device_info(int i)
 #endif
struct device_info *dev = c.devices + i;
 
+   stat_buf = malloc(sizeof(struct stat));
+   ASSERT(stat_buf);
+   if (stat(dev->path, stat_buf) < 0 ) {
+   MSG(0, "\tError: Failed to get the device stat!\n");
+   free(stat_buf);
+   return -1;
+   }
+
if (c.sparse_mode) {
-   fd = open((char *)dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
+   fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
} else {
-   fd = open((char *)dev->path, O_RDWR);
+   if (S_ISBLK(stat_buf->st_mode))
+   fd = open(dev->path, O_RDWR | O_EXCL);
+   else
+   fd = open(dev->path, O_RDWR);
}
if (fd < 0) {
MSG(0, "\tError: Failed to open the device!\n");
+   free(stat_buf);
return -1;
}
 
dev->fd = fd;
 
if (c.sparse_mode) {
-   if (f2fs_init_sparse_file())
+   if (f2fs_init_sparse_file()) {
+   free(stat_buf);
return -1;
+   }
}
 
if (c.kd == -1) {
@@ -810,13 +824,6 @@ int get_device_info(int i)
}
}
 
-   stat_buf = malloc(sizeof(struct stat));
-   if (fstat(fd, stat_buf) < 0 ) {
-   MSG(0, "\tError: Failed to get the device stat!\n");
-   free(stat_buf);
-   return -1;
-   }
-
if (c.sparse_mode) {
dev->total_sectors = c.device_size / dev->sector_size;
} else if (S_ISREG(stat_buf->st_mode)) {
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/2] fsck.f2fs: check extra_attr feature

2018-07-03 Thread Sheng Yong
Check extra_attr feature for inode. If it is corrupted, remove the
inode.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=200219
Reported-by: Wen Xu 
Signed-off-by: Sheng Yong 
---
 fsck/fsck.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 15264b2..acbe25d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -460,6 +460,12 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
__check_inode_mode(nid, ftype, le32_to_cpu(node_blk->i.i_mode)))
return -EINVAL;
 
+   if (ntype == TYPE_INODE &&
+   ((f2fs_has_extra_isize(_blk->i) &&
+ !(c.feature & F2FS_FEATURE_EXTRA_ATTR)) ||
+get_extra_isize(node_blk) >= DEF_ADDRS_PER_INODE))
+   return -EINVAL;
+
/* workaround to fix later */
if (ftype != F2FS_FT_ORPHAN ||
f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 1/2] fsck.f2fs: check extent of inline data/dentry inode

2018-07-03 Thread Sheng Yong
Check extent for inline data/dentry inode. If an inode contains inline
data/dentry, it should have no extent.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=200175
Reported-by: Wen Xu 
Signed-off-by: Sheng Yong 
---
 fsck/fsck.c | 16 +++-
 fsck/fsck.h |  1 +
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 6fd9dc2..15264b2 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -584,6 +584,9 @@ static void check_extent_info(struct child_info *child,
if (child->state & FSCK_UNMATCHED_EXTENT)
return;
 
+   if ((child->state & FSCK_INLINE_INODE) && ei->len)
+   goto unmatched;
+
if (last) {
/* hole exist in the back of extent */
if (child->last_blk != ei->blk + ei->len - 1)
@@ -735,6 +738,10 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
}
ofs = get_extra_isize(node_blk);
 
+   /* init extent info */
+   get_extent_info(, _blk->i.i_ext);
+   child.last_blk = 0;
+
if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) {
if (le32_to_cpu(node_blk->i.i_addr[ofs]) != 0) {
/* should fix this bug all the time */
@@ -756,6 +763,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
}
}
DBG(3, "ino[0x%x] has inline data!\n", nid);
+   child.state |= FSCK_INLINE_INODE;
goto check;
}
 
@@ -775,13 +783,10 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
/* should fix this bug all the time */
need_fix = 1;
}
+   child.state |= FSCK_INLINE_INODE;
goto check;
}
 
-   /* init extent info */
-   get_extent_info(, _blk->i.i_ext);
-   child.last_blk = 0;
-
/* check data blocks in inode */
for (idx = 0; idx < ADDRS_PER_INODE(_blk->i);
idx++, child.pgofs++) {
@@ -851,6 +856,7 @@ skip:
 
}
 
+check:
/* check uncovered range in the back of extent */
check_extent_info(, 0, 1);
 
@@ -860,7 +866,7 @@ skip:
if (c.fix_on)
need_fix = 1;
}
-check:
+
if (i_blocks != *blk_cnt) {
ASSERT_MSG("ino: 0x%x has i_blocks: %08"PRIx64", "
"but has %u blocks",
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 5530aff..f620912 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -16,6 +16,7 @@
 struct quota_ctx;
 
 #define FSCK_UNMATCHED_EXTENT  0x0001
+#define FSCK_INLINE_INODE  0x0002
 
 enum {
PREEN_MODE_0,
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] fsck.f2fs: clear qf_ino if quota node is removed

2018-06-21 Thread Sheng Yong
If a quota node is corrupted, it may be removed. Then its qf_ino should
also be removed.

Signed-off-by: Sheng Yong 
---
 fsck/fsck.c  | 19 +--
 fsck/fsck.h  |  1 +
 fsck/mount.c |  2 +-
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 8145199..8418bdb 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1675,8 +1675,13 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
}
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_REG_FILE, TYPE_INODE, _cnt, NULL);
-   if (ret)
-   ASSERT_MSG("[0x%x] wrong orphan inode", ino);
+   if (ret) {
+   /* sanity_check_nid failed, node should be removed */
+   ASSERT_MSG("[0x%x] wrong quota inode", ino);
+   sb->qf_ino[qtype] = 0;
+   if (c.fix_on)
+   F2FS_FSCK(sbi)->chk.fix_sb = 1;
+   }
}
return ret;
 }
@@ -2004,6 +2009,15 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
write_nat_bits(sbi, sb, cp, sbi->cur_cp);
 }
 
+static void fix_superblock(struct f2fs_sb_info *sbi)
+{
+   if (!F2FS_FSCK(sbi)->chk.fix_sb)
+   return;
+
+   write_superblock(F2FS_RAW_SUPER(sbi));
+   F2FS_FSCK(sbi)->chk.fix_sb = 0;
+}
+
 int check_curseg_offset(struct f2fs_sb_info *sbi)
 {
int i;
@@ -2584,6 +2598,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
flush_curseg_sit_entries(sbi);
}
fix_checkpoint(sbi);
+   fix_superblock(sbi);
} else if (is_set_ckpt_flags(cp, CP_FSCK_FLAG)) {
write_checkpoint(sbi);
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index f90bcf9..60cdf23 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -69,6 +69,7 @@ struct f2fs_fsck {
u32 multi_hard_link_files;
u64 sit_valid_blocks;
u32 sit_free_segs;
+   int fix_sb;
} chk;
 
struct hard_link_node *hard_link_list_head;
diff --git a/fsck/mount.c b/fsck/mount.c
index 7912605..7e908f1 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -2165,7 +2165,7 @@ void write_superblock(struct f2fs_super_block *new_sb)
ASSERT(ret >= 0);
}
free(buf);
-   DBG(0, "Info: Done to rebuild superblock\n");
+   MSG(0, "Info: Done to rebuild superblock\n");
 }
 
 void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v2] fsck.f2fs: introduce fsck_chk_curseg_info

2018-06-20 Thread Sheng Yong
If curseg is an empty segment, it will not be checked. This patch
introduces fsck_chk_curseg_info() to check SIT/SSA type of cursegs
to avoid curseg corruption.

Signed-off-by: Sheng Yong 
---
v2: check c.fix_on and c.preen_mode before updating se->type

 fsck/fsck.c | 39 +++
 fsck/fsck.h |  1 +
 fsck/main.c |  2 ++
 3 files changed, 42 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5b6dbc8..36b0b1d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -2422,6 +2422,45 @@ out:
return cnt;
 }
 
+int fsck_chk_curseg_info(struct f2fs_sb_info *sbi)
+{
+   struct curseg_info *curseg;
+   struct seg_entry *se;
+   struct f2fs_summary_block *sum_blk;
+   int i, ret = 0;
+
+   for (i = 0; i < NO_CHECK_TYPE; i++) {
+   curseg = CURSEG_I(sbi, i);
+   se = get_seg_entry(sbi, curseg->segno);
+   sum_blk = curseg->sum_blk;
+
+   if (se->type != i) {
+   ASSERT_MSG("Incorrect curseg [%d]: segno [0x%x] "
+  "type(SIT) [%d]", i, curseg->segno,
+  se->type);
+   if (c.fix_on || c.preen_mode)
+   se->type = i;
+   ret = -1;
+   }
+   if (i <= CURSEG_COLD_DATA && IS_SUM_DATA_SEG(sum_blk->footer)) {
+   continue;
+   } else if (i > CURSEG_COLD_DATA && 
IS_SUM_NODE_SEG(sum_blk->footer)) {
+   continue;
+   } else {
+   ASSERT_MSG("Incorrect curseg [%d]: segno [0x%x] "
+  "type(SSA) [%d]", i, curseg->segno,
+  sum_blk->footer.entry_type);
+   if (c.fix_on || c.preen_mode)
+   sum_blk->footer.entry_type =
+   i <= CURSEG_COLD_DATA ?
+   SUM_TYPE_DATA : SUM_TYPE_NODE;
+   ret = -1;
+   }
+   }
+
+   return ret;
+}
+
 int fsck_verify(struct f2fs_sb_info *sbi)
 {
unsigned int i = 0;
diff --git a/fsck/fsck.h b/fsck/fsck.h
index cbe7fc4..5530aff 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -144,6 +144,7 @@ extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, u32, 
struct child_info *,
 int fsck_chk_inline_dentries(struct f2fs_sb_info *, struct f2fs_node *,
struct child_info *);
 int fsck_chk_meta(struct f2fs_sb_info *sbi);
+int fsck_chk_curseg_info(struct f2fs_sb_info *);
 int convert_encrypted_name(unsigned char *, int, unsigned char *, int);
 
 extern void update_free_segments(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index 09026c9..f6d12b0 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -578,6 +578,8 @@ static void do_fsck(struct f2fs_sb_info *sbi)
 
print_cp_state(flag);
 
+   fsck_chk_curseg_info(sbi);
+
if (!c.fix_on && !c.bug_on) {
switch (c.preen_mode) {
case PREEN_MODE_1:
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs-tools: do not count free_segs in flush_sit_entries

2018-06-13 Thread Sheng Yong
flush_sit_entries() is always called before write_checkpoint(). Since
free_segs is counted in write_checkpoint, there is no need to do that
in flush_sit_entries. Besides, the value of free_segs may be not
correct if we skip uptodate seg_entries.

Signed-off-by: Sheng Yong 
---
 fsck/mount.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 68278c5..80a4849 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1867,11 +1867,9 @@ void flush_journal_entries(struct f2fs_sb_info *sbi)
 
 void flush_sit_entries(struct f2fs_sb_info *sbi)
 {
-   struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
struct sit_info *sit_i = SIT_I(sbi);
struct f2fs_sit_block *sit_blk;
unsigned int segno = 0;
-   u32 free_segs = 0;
 
sit_blk = calloc(BLOCK_SZ, 1);
ASSERT(sit_blk);
@@ -1891,14 +1889,9 @@ void flush_sit_entries(struct f2fs_sb_info *sbi)
sit->vblocks = cpu_to_le16((se->type << SIT_VBLOCKS_SHIFT) |
se->valid_blocks);
rewrite_current_sit_page(sbi, segno, sit_blk);
-
-   if (se->valid_blocks == 0x0 &&
-   !IS_CUR_SEGNO(sbi, segno, NO_CHECK_TYPE))
-   free_segs++;
}
 
free(sit_blk);
-   set_cp(free_segment_count, free_segs);
 }
 
 int find_next_free_block(struct f2fs_sb_info *sbi, u64 *to, int left, int type)
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 1/2] sload.f2fs: update sit entries of cursegs

2018-06-12 Thread Sheng Yong
move_curseg_info->reset_curseg changes cursegs, however, new segment
entries are not set as dirty. As a result, flush_sit_entries will not
update entries in SIT, especially when an empty segment is selected
as the new curseg, its seg_entry->type is lost.

Signed-off-by: Sheng Yong 
---
 fsck/mount.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fsck/mount.c b/fsck/mount.c
index 0a30adb..68278c5 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1149,6 +1149,7 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
se = get_seg_entry(sbi, curseg->segno);
se->type = type;
+   se->dirty = 1;
 }
 
 static void read_compacted_summaries(struct f2fs_sb_info *sbi)
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 2/2] fsck.f2fs: introduce fsck_chk_curseg_info

2018-06-12 Thread Sheng Yong
If curseg is an empty segment, it will not be checked. This patch
introduces fsck_chk_curseg_info() to check SIT/SSA type of cursegs
to avoid curseg corruption.

Signed-off-by: Sheng Yong 
---
 fsck/fsck.c | 34 ++
 fsck/fsck.h |  1 +
 fsck/main.c |  2 ++
 3 files changed, 37 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5b6dbc8..cfd939f 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -2422,6 +2422,40 @@ out:
return cnt;
 }
 
+int fsck_chk_curseg_info(struct f2fs_sb_info *sbi)
+{
+   struct curseg_info *curseg;
+   struct seg_entry *se;
+   struct f2fs_summary_block *sum_blk;
+   int i, ret = 0;
+
+   for (i = 0; i < NO_CHECK_TYPE; i++) {
+   curseg = CURSEG_I(sbi, i);
+   se = get_seg_entry(sbi, curseg->segno);
+   sum_blk = curseg->sum_blk;
+
+   if (se->type != i) {
+   ASSERT_MSG("Incorrect curseg [%d]: segno [0x%x] "
+  "type(SIT) [%d]", i, curseg->segno,
+  se->type);
+   se->type = i;
+   ret = -1;
+   }
+   if (i <= CURSEG_COLD_DATA && IS_SUM_DATA_SEG(sum_blk->footer)) {
+   continue;
+   } else if (i > CURSEG_COLD_DATA && 
IS_SUM_NODE_SEG(sum_blk->footer)) {
+   continue;
+   } else {
+   ASSERT_MSG("Incorrect curseg [%d]: segno [0x%x] "
+  "type(SSA) [%d]", i, curseg->segno,
+  sum_blk->footer.entry_type);
+   ret = -1;
+   }
+   }
+
+   return ret;
+}
+
 int fsck_verify(struct f2fs_sb_info *sbi)
 {
unsigned int i = 0;
diff --git a/fsck/fsck.h b/fsck/fsck.h
index cbe7fc4..5530aff 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -144,6 +144,7 @@ extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, u32, 
struct child_info *,
 int fsck_chk_inline_dentries(struct f2fs_sb_info *, struct f2fs_node *,
struct child_info *);
 int fsck_chk_meta(struct f2fs_sb_info *sbi);
+int fsck_chk_curseg_info(struct f2fs_sb_info *);
 int convert_encrypted_name(unsigned char *, int, unsigned char *, int);
 
 extern void update_free_segments(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index 09026c9..f6d12b0 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -578,6 +578,8 @@ static void do_fsck(struct f2fs_sb_info *sbi)
 
print_cp_state(flag);
 
+   fsck_chk_curseg_info(sbi);
+
if (!c.fix_on && !c.bug_on) {
switch (c.preen_mode) {
case PREEN_MODE_1:
-- 
2.17.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] resize.f2fs: skip cursegs when finding next free block

2018-06-04 Thread Sheng Yong

Hi, Jaegeuk

On 2018/6/5 4:55, Jaegeuk Kim wrote:

On 06/04, Sheng Yong wrote:

resize.f2fs (f2fs_defragment) tries to migrate blocks to new positions.
However, if a curseg is selected, and f2fs_defragment is broken by any
error, curseg->next_blkoff is left not updated.

To avoid this, we skip cursegs when finding next free block.


Don't we update the curseg at the end of resize/defrag?


Yes, we will if f2fs_defragment successfully moves all blocks. However,
if find_next_free_block fails because not enough space left (this happens
when sload fills too much data into the image), f2fs_defragment returns
without updating CP or cursegs.

thanks,
Sheng




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

diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index d0e08aa..d216444 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -380,16 +380,13 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info 
*sbi, u32 addr)
return 1;
  }
  
-static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno, int type)

+static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno)
  {
int i;
  
  	for (i = 0; i < NO_CHECK_TYPE; i++) {

struct curseg_info *curseg = CURSEG_I(sbi, i);
  
-		if (type == i)

-   continue;
-
if (segno == curseg->segno)
return 1;
}
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5b6dbc8..8145199 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1741,7 +1741,7 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi)
se = get_seg_entry(sbi, i);
if (se->valid_blocks != 0)
sit_valid_segs++;
-   else if (IS_CUR_SEGNO(sbi, i, NO_CHECK_TYPE)) {
+   else if (IS_CUR_SEGNO(sbi, i)) {
/* curseg has not been written back to device */
MSG(1, "\tInfo: curseg %u is counted in valid segs\n", 
i);
sit_valid_segs++;
diff --git a/fsck/mount.c b/fsck/mount.c
index 0a30adb..8d4704e 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -35,8 +35,7 @@ u32 get_free_segments(struct f2fs_sb_info *sbi)
for (i = 0; i < TOTAL_SEGS(sbi); i++) {
struct seg_entry *se = get_seg_entry(sbi, i);
  
-		if (se->valid_blocks == 0x0 &&

-   !IS_CUR_SEGNO(sbi, i, NO_CHECK_TYPE))
+   if (se->valid_blocks == 0x0 && !IS_CUR_SEGNO(sbi, i))
free_segs++;
}
return free_segs;
@@ -1891,8 +1890,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi)
se->valid_blocks);
rewrite_current_sit_page(sbi, segno, sit_blk);
  
-		if (se->valid_blocks == 0x0 &&

-   !IS_CUR_SEGNO(sbi, segno, NO_CHECK_TYPE))
+   if (se->valid_blocks == 0x0 && !IS_CUR_SEGNO(sbi, segno))
free_segs++;
}
  
@@ -1922,7 +1920,7 @@ int find_next_free_block(struct f2fs_sb_info *sbi, u64 *to, int left, int type)

se = get_seg_entry(sbi, segno);
  
  		if (se->valid_blocks == sbi->blocks_per_seg ||

-   IS_CUR_SEGNO(sbi, segno, type)) {
+   IS_CUR_SEGNO(sbi, segno)) {
*to = left ? START_BLOCK(sbi, segno) - 1:
START_BLOCK(sbi, segno + 1);
continue;
--
2.17.0


.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] resize.f2fs: skip cursegs when finding next free block

2018-06-04 Thread Sheng Yong
resize.f2fs (f2fs_defragment) tries to migrate blocks to new positions.
However, if a curseg is selected, and f2fs_defragment is broken by any
error, curseg->next_blkoff is left not updated.

To avoid this, we skip cursegs when finding next free block.

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

diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index d0e08aa..d216444 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -380,16 +380,13 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info 
*sbi, u32 addr)
return 1;
 }
 
-static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno, int type)
+static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno)
 {
int i;
 
for (i = 0; i < NO_CHECK_TYPE; i++) {
struct curseg_info *curseg = CURSEG_I(sbi, i);
 
-   if (type == i)
-   continue;
-
if (segno == curseg->segno)
return 1;
}
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5b6dbc8..8145199 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1741,7 +1741,7 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi)
se = get_seg_entry(sbi, i);
if (se->valid_blocks != 0)
sit_valid_segs++;
-   else if (IS_CUR_SEGNO(sbi, i, NO_CHECK_TYPE)) {
+   else if (IS_CUR_SEGNO(sbi, i)) {
/* curseg has not been written back to device */
MSG(1, "\tInfo: curseg %u is counted in valid segs\n", 
i);
sit_valid_segs++;
diff --git a/fsck/mount.c b/fsck/mount.c
index 0a30adb..8d4704e 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -35,8 +35,7 @@ u32 get_free_segments(struct f2fs_sb_info *sbi)
for (i = 0; i < TOTAL_SEGS(sbi); i++) {
struct seg_entry *se = get_seg_entry(sbi, i);
 
-   if (se->valid_blocks == 0x0 &&
-   !IS_CUR_SEGNO(sbi, i, NO_CHECK_TYPE))
+   if (se->valid_blocks == 0x0 && !IS_CUR_SEGNO(sbi, i))
free_segs++;
}
return free_segs;
@@ -1891,8 +1890,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi)
se->valid_blocks);
rewrite_current_sit_page(sbi, segno, sit_blk);
 
-   if (se->valid_blocks == 0x0 &&
-   !IS_CUR_SEGNO(sbi, segno, NO_CHECK_TYPE))
+   if (se->valid_blocks == 0x0 && !IS_CUR_SEGNO(sbi, segno))
free_segs++;
}
 
@@ -1922,7 +1920,7 @@ int find_next_free_block(struct f2fs_sb_info *sbi, u64 
*to, int left, int type)
se = get_seg_entry(sbi, segno);
 
if (se->valid_blocks == sbi->blocks_per_seg ||
-   IS_CUR_SEGNO(sbi, segno, type)) {
+   IS_CUR_SEGNO(sbi, segno)) {
*to = left ? START_BLOCK(sbi, segno) - 1:
START_BLOCK(sbi, segno + 1);
continue;
-- 
2.17.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: clear discard_wake earlier

2018-05-08 Thread Sheng Yong
If SBI_NEED_FSCK is set, discard_wake will never be cleared. As a
result, the condition of wait_event_interruptible_timeout() is always
true, which gets discard thread run too frequently.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/segment.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 503a98abdb2f..e53e28fd397e 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1404,6 +1404,10 @@ static int issue_discard_thread(void *data)
kthread_should_stop() || freezing(current) ||
dcc->discard_wake,
msecs_to_jiffies(wait_ms));
+
+   if (dcc->discard_wake)
+   dcc->discard_wake = 0;
+
if (try_to_freeze())
continue;
if (f2fs_readonly(sbi->sb))
@@ -1415,9 +1419,6 @@ static int issue_discard_thread(void *data)
continue;
}
 
-   if (dcc->discard_wake)
-   dcc->discard_wake = 0;
-
if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
init_discard_policy(, DPOLICY_FORCE, 1);
 
-- 
2.17.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: do not check F2FS_INLINE_DOTS in recover

2018-04-22 Thread Sheng Yong
Only dir may have F2FS_INLINE_DOTS flag, so there is no need to check
the flag in recover flow.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/recovery.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 1b23d3febe4c..709dd4daaf29 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -204,8 +204,6 @@ static void recover_inline_flags(struct inode *inode, 
struct f2fs_inode *ri)
set_inode_flag(inode, FI_DATA_EXIST);
else
clear_inode_flag(inode, FI_DATA_EXIST);
-   if (!(ri->i_inline & F2FS_INLINE_DOTS))
-   clear_inode_flag(inode, FI_INLINE_DOTS);
 }
 
 static void recover_inode(struct inode *inode, struct page *page)
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: remove duplicated dquot_initialize and fix error handling

2018-04-21 Thread Sheng Yong
This patch removes duplicated dquot_initialize in recover_orphan_inode(),
and fix the error handling if dquot_initialize fails.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/checkpoint.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 2e23b953d304..b1e61a125cc7 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -589,10 +589,11 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, 
nid_t ino)
}
 
err = dquot_initialize(inode);
-   if (err)
+   if (err) {
+   iput(inode);
goto err_out;
+   }
 
-   dquot_initialize(inode);
clear_nlink(inode);
 
/* truncate all the data during iput */
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: check if inmem_pages list is empty correctly

2018-04-17 Thread Sheng Yong
`cur' will never be NULL, we should check inmem_pages list instead.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/segment.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 5854cc4e1d67..bf9dab55b370 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -328,7 +328,7 @@ void drop_inmem_page(struct inode *inode, struct page *page)
break;
}
 
-   f2fs_bug_on(sbi, !cur || cur->page != page);
+   f2fs_bug_on(sbi, list_empty(head) || cur->page != page);
list_del(>list);
mutex_unlock(>inmem_lock);
 
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/2] f2fs-tools: remove duplicated declaration of f2fs_configuration c

2018-04-09 Thread Sheng Yong
The variable `c' is declared twice in f2fs_fs.h. This patch removes
the second declaration.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 include/f2fs_fs.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 2b0be2d..cbfdab5 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1232,8 +1232,6 @@ extern int f2fs_get_zone_blocks(int);
 extern int f2fs_check_zones(int);
 extern int f2fs_reset_zones(int);
 
-extern struct f2fs_configuration c;
-
 #define SIZE_ALIGN(val, size)  ((val) + (size) - 1) / (size)
 #define SEG_ALIGN(blks)SIZE_ALIGN(blks, c.blks_per_seg)
 #define ZONE_ALIGN(blks)   SIZE_ALIGN(blks, c.blks_per_seg * \
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v2 1/2] f2fs-tools: introduce new option V to show version

2018-04-09 Thread Sheng Yong
This patch introduces a new option -V to show the version of f2fs tools
and exit after that.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v2->v1: add -V for all f2fs tools

 fsck/main.c | 30 +-
 include/f2fs_fs.h   |  6 ++
 mkfs/f2fs_format_main.c |  6 +-
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index bbf82c3..ca3b789 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -58,6 +58,7 @@ void fsck_usage()
MSG(0, "  -t show directory tree\n");
MSG(0, "  -q preserve quota limits\n");
MSG(0, "  -y fix all the time\n");
+   MSG(0, "  -V print the version number and exit\n");
MSG(0, "  --dry-run do not really fix corruptions\n");
exit(1);
 }
@@ -73,6 +74,7 @@ void dump_usage()
MSG(0, "  -S sparse_mode\n");
MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
MSG(0, "  -b blk_addr (in 4KB)\n");
+   MSG(0, "  -V print the version number and exit\n");
 
exit(1);
 }
@@ -87,6 +89,7 @@ void defrag_usage()
MSG(0, "  -l length [default:512 (2MB)]\n");
MSG(0, "  -t target block address [default: main_blkaddr + 2MB]\n");
MSG(0, "  -i set direction as shrink [default: expand]\n");
+   MSG(0, "  -V print the version number and exit\n");
exit(1);
 }
 
@@ -96,6 +99,7 @@ void resize_usage()
MSG(0, "[options]:\n");
MSG(0, "  -d debug level [default:0]\n");
MSG(0, "  -t target sectors [default: device size]\n");
+   MSG(0, "  -V print the version number and exit\n");
exit(1);
 }
 
@@ -111,6 +115,7 @@ void sload_usage()
MSG(0, "  -t mount point [prefix of target fs path, default:/]\n");
MSG(0, "  -T timestamp\n");
MSG(0, "  -d debug level [default:0]\n");
+   MSG(0, "  -V print the version number and exit\n");
exit(1);
 }
 
@@ -160,7 +165,7 @@ void f2fs_parse_options(int argc, char *argv[])
}
 
if (!strcmp("fsck.f2fs", prog)) {
-   const char *option_string = ":ad:fp:q:Sty";
+   const char *option_string = ":ad:fp:q:StyV";
int opt = 0;
struct option long_opt[] = {
{"dry-run", no_argument, 0, 1},
@@ -240,6 +245,9 @@ void f2fs_parse_options(int argc, char *argv[])
break;
}
break;
+   case 'V':
+   show_version(prog);
+   exit(0);
case '?':
option = optopt;
default:
@@ -250,7 +258,7 @@ void f2fs_parse_options(int argc, char *argv[])
break;
}
} else if (!strcmp("dump.f2fs", prog)) {
-   const char *option_string = "d:i:n:s:Sa:b:";
+   const char *option_string = "d:i:n:s:Sa:b:V";
static struct dump_option dump_opt = {
.nid = 0,   /* default root ino */
.start_nat = -1,
@@ -310,6 +318,9 @@ void f2fs_parse_options(int argc, char *argv[])
ret = sscanf(optarg, "%x",
_opt.blk_addr);
break;
+   case 'V':
+   show_version(prog);
+   exit(0);
default:
err = EUNKNOWN_OPT;
break;
@@ -321,7 +332,7 @@ void f2fs_parse_options(int argc, char *argv[])
 
c.private = _opt;
} else if (!strcmp("defrag.f2fs", prog)) {
-   const char *option_string = "d:s:Sl:t:i";
+   const char *option_string = "d:s:Sl:t:iV";
 
c.func = DEFRAG;
while ((option = getopt(argc, argv, option_string)) != EOF) {
@@ -367,6 +378,9 @@ void f2fs_parse_options(int argc, char *argv[])
case 'i':
c.defrag_shrink = 1;
break;
+   case 'V':
+   show_version(prog);
+   exit(0);
default:
err = EUNKNOWN_OPT;
break;
@@ -376,7 +390,7 @@ void f2fs_parse_options(int argc, char *argv[])
break;
}

Re: [f2fs-dev] [PATCH] mkfs.f2fs: introduce new option V to show version

2018-04-09 Thread Sheng Yong



On 2018/4/10 1:55, Jaegeuk Kim wrote:

On 04/08, Chao Yu wrote:

On 2018/4/8 10:15, Sheng Yong wrote:

This patch introduces a new option -V to show the version of mkfs.f2fs
and exit after that.


BTW, should we add -V for other misc tools?


Yes, could you please add this for others?


OK. I'll do that.

thanks,
Sheng




Signed-off-by: Sheng Yong <shengyo...@huawei.com>


Reviewed-by: Chao Yu <yuch...@huawei.com>

Thanks,


.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] mkfs.f2fs: introduce new option V to show version

2018-04-07 Thread Sheng Yong
This patch introduces a new option -V to show the version of mkfs.f2fs
and exit after that.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 mkfs/f2fs_format_main.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 3c70513..3520882 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -58,6 +58,7 @@ static void mkfs_usage()
MSG(0, "  -t 0: nodiscard, 1: discard [default:1]\n");
MSG(0, "  -w wanted sector size\n");
MSG(0, "  -z # of sections per zone [default:1]\n");
+   MSG(0, "  -V print the version number and exit\n");
MSG(0, "sectors: number of sectors. [default: determined by device 
size]\n");
exit(1);
 }
@@ -136,7 +137,7 @@ static void parse_feature(const char *features)
 
 static void f2fs_parse_options(int argc, char *argv[])
 {
-   static const char *option_string = "qa:c:d:e:E:il:mo:O:s:S:z:t:fw:";
+   static const char *option_string = "qa:c:d:e:E:il:mo:O:s:S:z:t:fw:V";
int32_t option=0;
 
while ((option = getopt(argc,argv,option_string)) != EOF) {
@@ -209,6 +210,10 @@ static void f2fs_parse_options(int argc, char *argv[])
case 'w':
c.wanted_sector_size = atoi(optarg);
break;
+   case 'V':
+   MSG(0, "mkfs.f2fs %s (%s)\n",
+   F2FS_TOOLS_VERSION, F2FS_TOOLS_DATE);
+   exit(0);
default:
MSG(0, "\tError: Unknown option %c\n",option);
mkfs_usage();
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] resize.f2fs: clear CP_COMPACT_SUM_FLAG when rebuilding checkpoint

2018-04-07 Thread Sheng Yong
Resize rebuilds checkpoint with 6 summary blocks, so if
CP_COMPACT_SUM_FLAG is set in the old checkpoint, clear it.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/resize.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fsck/resize.c b/fsck/resize.c
index 7643511..019da71 100644
--- a/fsck/resize.c
+++ b/fsck/resize.c
@@ -504,6 +504,8 @@ static void rebuild_checkpoint(struct f2fs_sb_info *sbi,
 
/* update nat_bits flag */
flags = update_nat_bits_flags(new_sb, cp, get_cp(ckpt_flags));
+   if (flags & CP_COMPACT_SUM_FLAG)
+   flags &= ~CP_COMPACT_SUM_FLAG;
set_cp(ckpt_flags, flags);
 
memcpy(new_cp, cp, (unsigned char *)cp->sit_nat_version_bitmap -
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/2] f2fs-tools: improve loggings

2018-03-18 Thread Sheng Yong

Hi, Ju Hyung and list,

On 2018/3/17 23:04, Park Ju Hyung wrote:

  - Print errors and warnings to stderr
  - Print errors and warnings regardless of debugging level
  - Make info/error/warning logs consistent
  - Print POSIX errors when possible
  - Use more consistent terms and grammar


Shall we handle the last '\n' in different print functions the same way?
ASSERT_MSG() and ASSERT() have '\n' by default, while others don't.
And what is the purpose of TRACE_ERR_MSG() and PERR_MSG()?

thanks,
Sheng


Signed-off-by: Park Ju Hyung 
---
  fsck/defrag.c|   4 +-
  fsck/dir.c   |  20 +++
  fsck/dump.c  |  12 ++--
  fsck/fsck.c  |  14 ++---
  fsck/main.c  |  73 
  fsck/mount.c |  62 ++---
  fsck/quotaio_tree.c  |   2 +-
  fsck/resize.c|   8 +--
  fsck/segment.c   |   4 +-
  fsck/sload.c |  29 +-
  include/f2fs_fs.h|  34 ++--
  lib/libf2fs.c|  51 +
  lib/libf2fs_io.c |  10 ++--
  lib/libf2fs_zoned.c  |  21 ---
  mkfs/f2fs_format.c   | 140 +++
  mkfs/f2fs_format_main.c  |  54 +-
  mkfs/f2fs_format_utils.c |  14 ++---
  17 files changed, 291 insertions(+), 261 deletions(-)

diff --git a/fsck/defrag.c b/fsck/defrag.c
index bea0293..6ceb1f5 100644
--- a/fsck/defrag.c
+++ b/fsck/defrag.c
@@ -78,12 +78,12 @@ int f2fs_defragment(struct f2fs_sb_info *sbi, u64 from, u64 
len, u64 to, int lef
continue;
  
  		if (find_next_free_block(sbi, , left, se->type)) {

-   MSG(0, "Not enough space to migrate blocks");
+   ERR_MSG("Not enough space to migrate blocks");
return -1;
}
  
  		if (migrate_block(sbi, idx, target)) {

-   ASSERT_MSG("Found inconsistency: please run FSCK");
+   ASSERT_MSG("Found inconsistency, please run FSCK");
return -1;
}
}
diff --git a/fsck/dir.c b/fsck/dir.c
index 567a4e9..2e45838 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -235,7 +235,7 @@ int f2fs_add_link(struct f2fs_sb_info *sbi, struct 
f2fs_node *parent,
return -EINVAL;
  
  	if (!pino) {

-   ERR_MSG("Wrong parent ino:%d \n", pino);
+   TRACE_ERR_MSG("Wrong parent ino: %d\n", pino);
return -EINVAL;
}
  
@@ -246,7 +246,7 @@ int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,

  start:
if (current_depth == MAX_DIR_HASH_DEPTH) {
free(dentry_blk);
-   ERR_MSG("\tError: MAX_DIR_HASH\n");
+   TRACE_ERR_MSG("MAX_DIR_HASH\n");
return -ENOSPC;
}
  
@@ -524,7 +524,7 @@ int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,

ret = dev_write_block(dentry_blk, dn.data_blkaddr);
ASSERT(ret >= 0);
  
-		MSG(1, "%s: copy inline entry to block\n", __func__);

+   MSG(1, "%s: copying inline entry to block\n", __func__);
  
  		free(dentry_blk);

return ret;
@@ -561,9 +561,9 @@ int convert_inline_dentry(struct f2fs_sb_info *sbi, struct 
f2fs_node *node,
le32_to_cpu(de->ino),
de->file_type, p_blkaddr, 0);
if (ret)
-   MSG(0, "Convert file \"%s\" ERR=%d\n", filename, ret);
+   MSG(0, "Failed to convert file \"%s\", ERR = %d\n", 
filename, ret);
else
-   MSG(1, "%s: add inline entry to block\n", __func__);
+   MSG(1, "%s: adding inline entry to block\n", __func__);
  
  		bit_pos += GET_DENTRY_SLOTS(namelen);

}
@@ -582,7 +582,7 @@ int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
/* Find if there is a */
get_node_info(sbi, de->pino, );
if (ni.blk_addr == NULL_ADDR) {
-   MSG(0, "No parent directory pino=%x\n", de->pino);
+   MSG(0, "No parent directory pino = %x\n", de->pino);
return -1;
}
  
@@ -595,13 +595,13 @@ int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)

/* Must convert inline dentry before the following opertions */
ret = convert_inline_dentry(sbi, parent, ni.blk_addr);
if (ret) {
-   MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
+   MSG(0, "Conversion of inline dentry for pino = %x failed\n", 
de->pino);
return -1;
}
  
  	ret = f2fs_find_entry(sbi, parent, de);

if (ret) {
-   MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
+   MSG(0, "Skipping existing \"%s\" pino = %x ERR = %d\n",
de->name, 

[f2fs-dev] [RFC PATCH v5 3/3] ext4: do not allow mount with test_dummy_encryption if encrypt not set

2018-03-15 Thread Sheng Yong
When mounting with test_dummy_encryption option, if encrypt feature
is not set, return fail instead of setting encrypt feature forcely.

Cc: linux-e...@vger.kernel.org
Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/ext4/super.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 39bf464c35f1..1a253342b09e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4149,10 +4149,9 @@ static int ext4_fill_super(struct super_block *sb, void 
*data, int silent)
goto failed_mount_wq;
}
 
-   if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
-   !ext4_has_feature_encrypt(sb)) {
-   ext4_set_feature_encrypt(sb);
-   ext4_commit_super(sb, 1);
+   if (DUMMY_ENCRYPTION_ENABLED(sbi) && !ext4_has_feature_encrypt(sb)) {
+   ext4_msg(sb, KERN_ERR, "Encrypt does not support");
+   goto failed_mount_wq;
}
 
/*
-- 
2.16.2


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v5 2/3] f2fs: introduce a new mount option test_dummy_encryption

2018-03-15 Thread Sheng Yong
This patch introduces a new mount option `test_dummy_encryption'
to allow fscrypt to create a fake fscrypt context. This is used
by xfstests.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 Documentation/filesystems/f2fs.txt |  2 ++
 fs/f2fs/dir.c  |  4 +++-
 fs/f2fs/f2fs.h |  8 
 fs/f2fs/namei.c|  9 ++---
 fs/f2fs/super.c| 28 
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/Documentation/filesystems/f2fs.txt 
b/Documentation/filesystems/f2fs.txt
index 514e44983a8e..12a147c9f87f 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -189,6 +189,8 @@ fsync_mode=%s  Control the policy of fsync. 
Currently supports "posix"
fsync will be heavy and behaves in line with xfs, ext4
and btrfs, where xfstest generic/342 will pass, but the
performance will regress.
+test_dummy_encryption  Enable dummy encryption, which provides a fake fscrypt
+   context. The fake fscrypt context is used by xfstests.
 
 

 DEBUGFS ENTRIES
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 9a0d103b5052..fe661274ff10 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -361,6 +361,7 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
struct page *dpage)
 {
struct page *page;
+   int dummy_encrypt = DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(dir));
int err;
 
if (is_inode_flag_set(inode, FI_NEW_INODE)) {
@@ -387,7 +388,8 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
if (err)
goto put_error;
 
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
+   if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
+   f2fs_may_encrypt(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false);
if (err)
goto put_error;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index c0d74ff9a6d7..191ee5718369 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -133,6 +133,7 @@ struct f2fs_mount_info {
int whint_mode;
int alloc_mode; /* segment allocation policy */
int fsync_mode; /* fsync policy */
+   bool test_dummy_encryption; /* test dummy encryption */
 };
 
 #define F2FS_FEATURE_ENCRYPT   0x0001
@@ -1077,6 +1078,13 @@ enum fsync_mode {
FSYNC_MODE_STRICT,  /* fsync behaves in line with ext4 */
 };
 
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#define DUMMY_ENCRYPTION_ENABLED(sbi) \
+   (unlikely(F2FS_OPTION(sbi).test_dummy_encryption))
+#else
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+#endif
+
 struct f2fs_sb_info {
struct super_block *sb; /* pointer to VFS super block */
struct proc_dir_entry *s_proc;  /* proc entry */
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index f4ae46282eef..d5098efe577c 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -78,7 +78,8 @@ static struct inode *f2fs_new_inode(struct inode *dir, 
umode_t mode)
set_inode_flag(inode, FI_NEW_INODE);
 
/* If the directory encrypted, then we should encrypt the inode. */
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode))
+   if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+   f2fs_may_encrypt(inode))
f2fs_set_encrypted_inode(inode);
 
if (f2fs_sb_has_extra_attr(sbi->sb)) {
@@ -787,10 +788,12 @@ static int __f2fs_tmpfile(struct inode *dir, struct 
dentry *dentry,
 
 static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
-   if (unlikely(f2fs_cp_error(F2FS_I_SB(dir
+   struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+
+   if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
 
-   if (f2fs_encrypted_inode(dir)) {
+   if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
int err = fscrypt_get_encryption_info(dir);
if (err)
return err;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index dcdae3f932e2..98b2c7ff1804 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -132,6 +132,7 @@ enum {
Opt_whint,
Opt_alloc,
Opt_fsync,
+   Opt_test_dummy_encryption,
Opt_err,
 };
 
@@ -188,6 +189,7 @@ static match_table_t f2fs_tokens = {
{Opt_whint, "whint_mode=%s"},
{Opt_alloc, "alloc_mode=%s"},
{Opt_fsync, "fsync_mode=%s"},
+   {Opt_test_dummy_encryption, "t

[f2fs-dev] [RFC PATCH v5 0/3] f2fs: introduce F2FS_FEATURE_LOST_FOUND feature

2018-03-15 Thread Sheng Yong
v5->v4:
  * add doc for new mount option test_dummy_encryption
  * move test_dummy_encryption flag to f2fs_mount_info
  * move DUMMY_ENCRYPTION_ENABLED check to parse_option
  * remove readonly check since we don't enable encrypt feature forcely
v4->v3:
  * split f2fs patch into 2: one for LOST_FOUND feature, another for
test_dummy_encryption
  * do not set enc_name if dir is not encrypted
  * do not allow mounting with test_dummy_encryption if encrypt feature
is not set
v3->v2:
  * fix test_dummy_encryption
v2->v1:
  * introduce new mount option test_dummy_encryption
  * add sysfs entry for LOST_FOUND feature
---8<---

This patchset introduces LOST_FOUND feature in f2fs. If the feature is
enabled, f2fs should avoid to encrypt root directory.

A new mount option "test_dummy_encryption" is introduced, this is used by
xfstests.

Thanks,
Sheng

Sheng Yong (3):
  f2fs: introduce F2FS_FEATURE_LOST_FOUND feature
  f2fs: introduce a new mount option test_dummy_encryption
  ext4: do not allow mount with test_dummy_encryption if encrypt not set

 Documentation/filesystems/f2fs.txt |  2 ++
 fs/ext4/super.c|  7 +++
 fs/f2fs/dir.c  |  4 +++-
 fs/f2fs/f2fs.h | 10 ++
 fs/f2fs/namei.c|  9 ++---
 fs/f2fs/super.c| 40 ++
 fs/f2fs/sysfs.c|  7 +++
 7 files changed, 71 insertions(+), 8 deletions(-)

-- 
2.16.2


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v5 1/3] f2fs: introduce F2FS_FEATURE_LOST_FOUND feature

2018-03-15 Thread Sheng Yong
This patch introduces a new feature, F2FS_FEATURE_LOST_FOUND, which
is set by mkfs. mkfs creates a directory named lost+found, which saves
unreachable files. If fsck finds a file which has no parent, or its
parent is removed by fsck, the file will be placed under lost+found
directory by fsck.

lost+found directory could not be encrypted. As a result, the root
directory cannot be encrypted too. So if LOST_FOUND feature is enabled,
let's avoid to encrypt root directory.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
Reviewed-by: Chao Yu <yuch...@huawei.com>
---
 fs/f2fs/f2fs.h  |  2 ++
 fs/f2fs/super.c | 12 
 fs/f2fs/sysfs.c |  7 +++
 3 files changed, 21 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 641b4b98d373..c0d74ff9a6d7 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -144,6 +144,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -3214,6 +3215,7 @@ F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
 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);
 
 #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 419eaacf3366..dcdae3f932e2 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1891,6 +1891,18 @@ static int f2fs_get_context(struct inode *inode, void 
*ctx, size_t len)
 static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
 {
+   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+   /*
+* Encrypting the root directory is not allowed because fsck
+* expects lost+found directory to exist and remain unencrypted
+* if LOST_FOUND feature is enabled.
+*
+*/
+   if (f2fs_sb_has_lost_found(sbi->sb) &&
+   inode->i_ino == F2FS_ROOT_INO(sbi))
+   return -EPERM;
+
return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len, fs_data, XATTR_CREATE);
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 7d983ad19da4..f33a56d6e6dd 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -116,6 +116,9 @@ static ssize_t features_show(struct f2fs_attr *a,
if (f2fs_sb_has_inode_crtime(sb))
len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
len ? ", " : "", "inode_crtime");
+   if (f2fs_sb_has_lost_found(sb))
+   len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
+   len ? ", " : "", "lost_found");
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
return len;
 }
@@ -292,6 +295,7 @@ enum feat_id {
FEAT_FLEXIBLE_INLINE_XATTR,
FEAT_QUOTA_INO,
FEAT_INODE_CRTIME,
+   FEAT_LOST_FOUND,
 };
 
 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
@@ -307,6 +311,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a,
case FEAT_FLEXIBLE_INLINE_XATTR:
case FEAT_QUOTA_INO:
case FEAT_INODE_CRTIME:
+   case FEAT_LOST_FOUND:
return snprintf(buf, PAGE_SIZE, "supported\n");
}
return 0;
@@ -386,6 +391,7 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
 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);
 
 #define ATTR_LIST(name) (_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -441,6 +447,7 @@ static struct attribute *f2fs_feat_attrs[] = {
ATTR_LIST(flexible_inline_xattr),
ATTR_LIST(quota_ino),
ATTR_LIST(inode_crtime),
+   ATTR_LIST(lost_found),
NULL,
 };
 
-- 
2.16.2


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH v4 2/3] f2fs: introduce a new mount option test_dummy_encryption

2018-03-11 Thread Sheng Yong

Hi, Chao

On 2018/3/9 20:32, Chao Yu wrote:

On 2018/3/9 15:53, Sheng Yong wrote:

This patch introduces a new mount option `test_dummy_encryption' to
allow fscrypt to create a fake fscrypt context. This is used by xfstests.


It needs to add doc for this new mount option.


Oh. Right, I'll update the doc.




[...]

  static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t 
mode)
  {
-   if (unlikely(f2fs_cp_error(F2FS_I_SB(dir
+   struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+
+   if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
  
-	if (f2fs_encrypted_inode(dir)) {

+   if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {


Why we need to add this condition here?


I think it's both OK if we add the check or not. But since commit 304eecc3462e 
("f2fs crypto:
check encryption for tmpfile) add f2fs_encrypt_inode() to check encryption 
earlier, IMO, we
should do the same check if test_dummy_encryption is enabled according to the 
semantic.


int err = fscrypt_get_encryption_info(dir);
if (err)
return err;

[...]

@@ -2620,6 +2642,15 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
if (err)
goto free_options;
  
+	if (DUMMY_ENCRYPTION_ENABLED(sbi) &&

+   (sb_rdonly(sb) || !f2fs_sb_has_encrypt(sb))) {


Use f2fs_readonly() here which can wrap sb_rdonly()?
OK.



+   f2fs_msg(sb, KERN_ERR,
+   "Encrypt feature is off or filesystem is read-only");
+   err = -EINVAL;
+   retry = false;
+   goto free_options;
+   }


How about moving this check into parse_options(), so we can check this condition
in remount_fs() too.


OK.

Thanks,
Sheng


Thanks,


+
sbi->max_file_blocks = max_file_blocks();
sb->s_maxbytes = sbi->max_file_blocks <<
le32_to_cpu(raw_super->log_blocksize);


--
To unsubscribe from this list: send the line "unsubscribe linux-fscrypt" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v4 0/3] f2fs: introduce F2FS_FEATURE_LOST_FOUND feature

2018-03-08 Thread Sheng Yong
v4->v3:
  * split f2fs patch into 2: one for LOST_FOUND feature, another for
test_dummy_encryption
  * do not set enc_name if dir is not encrypted
  * do not allow mounting with test_dummy_encryption if encrypt feature
is not set
v3->v2:
  * fix test_dummy_encryption
v2->v1:
  * introduce new mount option test_dummy_encryption
  * add sysfs entry for LOST_FOUND feature
---8<---

This patchset introduces LOST_FOUND feature in f2fs. If the feature is
enabled, f2fs should avoid to encrypt root directory.

A new mount option "test_dummy_encryption" is introduced, this is used by
xfstests.

Thanks,
Sheng

Sheng Yong (3):
  f2fs: introduce F2FS_FEATURE_LOST_FOUND feature
  f2fs: introduce a new mount option test_dummy_encryption
  ext4: do not allow mount with test_dummy_encryption if encrypt not set

 fs/ext4/super.c |  5 +++--
 fs/f2fs/dir.c   |  4 +++-
 fs/f2fs/f2fs.h  | 13 +
 fs/f2fs/namei.c |  9 ++---
 fs/f2fs/super.c | 43 +++
 fs/f2fs/sysfs.c |  7 +++
 6 files changed, 75 insertions(+), 6 deletions(-)

-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 3/3] ext4: do not allow mount with test_dummy_encryption if encrypt not set

2018-03-08 Thread Sheng Yong
When mounting with test_dummy_encryption option, if encrypt feature
is not set, return fail instead of setting encrypt feature forcely.

CC: linux-e...@vger.kernel.org
Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/ext4/super.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 39bf464c35f1..c424af0ccda9 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4151,8 +4151,9 @@ static int ext4_fill_super(struct super_block *sb, void 
*data, int silent)
 
if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
!ext4_has_feature_encrypt(sb)) {
-   ext4_set_feature_encrypt(sb);
-   ext4_commit_super(sb, 1);
+   ext4_msg(sb, KERN_ERR,
+"Encrypt does not support or filesystem is read-only");
+   goto failed_mount_wq;
}
 
/*
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v4 2/3] f2fs: introduce a new mount option test_dummy_encryption

2018-03-08 Thread Sheng Yong
This patch introduces a new mount option `test_dummy_encryption' to
allow fscrypt to create a fake fscrypt context. This is used by xfstests.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/dir.c   |  4 +++-
 fs/f2fs/f2fs.h  | 11 +++
 fs/f2fs/namei.c |  9 ++---
 fs/f2fs/super.c | 31 +++
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 797eb05cb538..73ddc35fba4f 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -361,6 +361,7 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
struct page *dpage)
 {
struct page *page;
+   int dummy_encrypt = DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(dir));
int err;
 
if (is_inode_flag_set(inode, FI_NEW_INODE)) {
@@ -387,7 +388,8 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
if (err)
goto put_error;
 
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
+   if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
+   f2fs_may_encrypt(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false);
if (err)
goto put_error;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 31f39ab7fce4..c0dbd8b6050b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1053,6 +1053,15 @@ enum {
ALLOC_MODE_REUSE,   /* reuse segments as much as possible */
 };
 
+#define F2FS_MF_TEST_DUMMY_ENCRYPTION  0x0001
+
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->mount_flags & \
+   F2FS_MF_TEST_DUMMY_ENCRYPTION))
+#else
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+#endif
+
 struct f2fs_sb_info {
struct super_block *sb; /* pointer to VFS super block */
struct proc_dir_entry *s_proc;  /* proc entry */
@@ -1242,6 +1251,8 @@ struct f2fs_sb_info {
 
/* segment allocation policy */
int alloc_mode;
+
+   unsigned int mount_flags;
 };
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 318dfe870cb5..5dd6a112e13d 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -78,7 +78,8 @@ static struct inode *f2fs_new_inode(struct inode *dir, 
umode_t mode)
set_inode_flag(inode, FI_NEW_INODE);
 
/* If the directory encrypted, then we should encrypt the inode. */
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode))
+   if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+   f2fs_may_encrypt(inode))
f2fs_set_encrypted_inode(inode);
 
if (f2fs_sb_has_extra_attr(sbi->sb)) {
@@ -788,10 +789,12 @@ static int __f2fs_tmpfile(struct inode *dir, struct 
dentry *dentry,
 
 static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
-   if (unlikely(f2fs_cp_error(F2FS_I_SB(dir
+   struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+
+   if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
 
-   if (f2fs_encrypted_inode(dir)) {
+   if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
int err = fscrypt_get_encryption_info(dir);
if (err)
return err;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b9a6b97c3bd3..345e4f63f6fc 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -131,6 +131,7 @@ enum {
Opt_jqfmt_vfsv1,
Opt_whint,
Opt_alloc,
+   Opt_test_dummy_encryption,
Opt_err,
 };
 
@@ -186,6 +187,7 @@ static match_table_t f2fs_tokens = {
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
{Opt_whint, "whint_mode=%s"},
{Opt_alloc, "alloc_mode=%s"},
+   {Opt_test_dummy_encryption, "test_dummy_encryption"},
{Opt_err, NULL},
 };
 
@@ -719,6 +721,16 @@ static int parse_options(struct super_block *sb, char 
*options)
}
kfree(name);
break;
+   case Opt_test_dummy_encryption:
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+   sbi->mount_flags |= F2FS_MF_TEST_DUMMY_ENCRYPTION;
+   f2fs_msg(sb, KERN_INFO,
+   "Test dummy encryption mode enabled");
+#else
+   f2fs_msg(sb, KERN_INFO,
+   "Test dummy encryption mount option 
ignored");
+#endif
+   break;
default:
f2fs_msg(sb, KERN_ERR,
"Unrecognized mount option \"%s\" or missing 
value",
@@ -1282,6 +1294,10 @@ sta

Re: [f2fs-dev] [PATCH] dump.f2fs: fix a wrong report for dump an {d, id, did}node

2018-03-06 Thread Sheng Yong



On 2018/3/7 11:30, heyunlei wrote:




-Original Message-
From: shengyong (A)
Sent: Wednesday, March 07, 2018 11:21 AM
To: heyunlei; jaeg...@kernel.org; Yuchao (T); 
linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] [PATCH] dump.f2fs: fix a wrong report for dump an {d, 
id, did}node

Hi, Yunlei,

On 2018/3/7 10:41, Yunlei He wrote:

fix a wrong report for dump an {d,id,did}node like this:

[print_node_info: 283] Node ID [0x6820:26656] is direct node or indirect node.
[0] [0x 16b6684 : 23815812]
[1] [0x 16b6685 : 23815813]
[2] [0x 16b6686 : 23815814]
[3] [0x 16b6687 : 23815815]
[4] [0x 16b6688 : 23815816]
[5] [0x 16b6689 : 23815817]
[6] [0x 16b668a : 23815818]
[7] [0x 16b668b : 23815819]
[8] [0x 16b668c : 23815820]
[9] [0x 16b668d : 23815821]
[10][0x 16b668e : 23815822]
Invalid (i)node block

Signed-off-by: Yunlei He 
---
   fsck/dump.c | 25 -
   1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index 23e4f47..5abdd6d 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -475,6 +475,18 @@ dump:
}
   }

+static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
+{
+   struct seg_entry *se;
+   u32 offset;
+
+   se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr));
+   offset = OFFSET_IN_SEG(sbi, blk_addr);
+
+   return f2fs_test_bit(offset,
+   (const char *)se->cur_valid_map) != 0;
+}
+
   void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
   {
struct node_info ni;
@@ -492,13 +504,14 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int 
force)

if (ni.blk_addr == 0x0)
MSG(force, "Invalid nat entry\n\n");
+   else if (!is_sit_bitmap_set(sbi, ni.blk_addr))
+   MSG(force, "Invalid node blk addr\n\n");

DBG(1, "node_blk.footer.ino [0x%x]\n", 
le32_to_cpu(node_blk->footer.ino));
DBG(1, "node_blk.footer.nid [0x%x]\n", 
le32_to_cpu(node_blk->footer.nid));

if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
-   le32_to_cpu(node_blk->footer.nid) == ni.nid &&
-   ni.ino == ni.nid) {
+   le32_to_cpu(node_blk->footer.nid) == ni.nid) {


I think we should not remove "ni.ino == ni.nid" here. dump_file() can only be
called on inode.

Thanks,
Sheng


print_node_info(sbi, node_blk, force);


How about move the judgement before dump_file?


OK. We could do that :)

thanks,
Sheng


Thanks.

dump_file(sbi, , node_blk, force);
} else {
@@ -678,8 +691,6 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
int type;
struct f2fs_summary sum_entry;
struct node_info ni, ino_ni;
-   struct seg_entry *se;
-   u32 offset;
int enc_name;
int ret = 0;

@@ -712,12 +723,8 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
return ret;
}

-   se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr));
-   offset = OFFSET_IN_SEG(sbi, blk_addr);
-
-   if (f2fs_test_bit(offset, (const char *)se->cur_valid_map) == 0) {
+   if (!is_sit_bitmap_set(sbi, blk_addr))
MSG(0, "\nblkaddr is not valid\n");
-   }

type = get_sum_entry(sbi, blk_addr, _entry);
nid = le32_to_cpu(sum_entry.nid);






--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] dump.f2fs: fix a wrong report for dump an {d, id, did}node

2018-03-06 Thread Sheng Yong

Hi, Yunlei,

On 2018/3/7 10:41, Yunlei He wrote:

fix a wrong report for dump an {d,id,did}node like this:

[print_node_info: 283] Node ID [0x6820:26656] is direct node or indirect node.
[0] [0x 16b6684 : 23815812]
[1] [0x 16b6685 : 23815813]
[2] [0x 16b6686 : 23815814]
[3] [0x 16b6687 : 23815815]
[4] [0x 16b6688 : 23815816]
[5] [0x 16b6689 : 23815817]
[6] [0x 16b668a : 23815818]
[7] [0x 16b668b : 23815819]
[8] [0x 16b668c : 23815820]
[9] [0x 16b668d : 23815821]
[10][0x 16b668e : 23815822]
Invalid (i)node block

Signed-off-by: Yunlei He 
---
  fsck/dump.c | 25 -
  1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index 23e4f47..5abdd6d 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -475,6 +475,18 @@ dump:
}
  }
  
+static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)

+{
+   struct seg_entry *se;
+   u32 offset;
+
+   se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr));
+   offset = OFFSET_IN_SEG(sbi, blk_addr);
+
+   return f2fs_test_bit(offset,
+   (const char *)se->cur_valid_map) != 0;
+}
+
  void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
  {
struct node_info ni;
@@ -492,13 +504,14 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int 
force)
  
  	if (ni.blk_addr == 0x0)

MSG(force, "Invalid nat entry\n\n");
+   else if (!is_sit_bitmap_set(sbi, ni.blk_addr))
+   MSG(force, "Invalid node blk addr\n\n");
  
  	DBG(1, "node_blk.footer.ino [0x%x]\n", le32_to_cpu(node_blk->footer.ino));

DBG(1, "node_blk.footer.nid [0x%x]\n", 
le32_to_cpu(node_blk->footer.nid));
  
  	if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&

-   le32_to_cpu(node_blk->footer.nid) == ni.nid &&
-   ni.ino == ni.nid) {
+   le32_to_cpu(node_blk->footer.nid) == ni.nid) {


I think we should not remove "ni.ino == ni.nid" here. dump_file() can only be
called on inode.

Thanks,
Sheng


print_node_info(sbi, node_blk, force);
dump_file(sbi, , node_blk, force);
} else {
@@ -678,8 +691,6 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
int type;
struct f2fs_summary sum_entry;
struct node_info ni, ino_ni;
-   struct seg_entry *se;
-   u32 offset;
int enc_name;
int ret = 0;
  
@@ -712,12 +723,8 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)

return ret;
}
  
-	se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr));

-   offset = OFFSET_IN_SEG(sbi, blk_addr);
-
-   if (f2fs_test_bit(offset, (const char *)se->cur_valid_map) == 0) {
+   if (!is_sit_bitmap_set(sbi, blk_addr))
MSG(0, "\nblkaddr is not valid\n");
-   }
  
  	type = get_sum_entry(sbi, blk_addr, _entry);

nid = le32_to_cpu(sum_entry.nid);




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v3 0/2] f2fs-tools: introduce F2FS_FEATURE_LOST_FOUND feature

2018-03-05 Thread Sheng Yong
v3->v2:
  * mkfs: remove extra newline, fix return value and incorrect data types
  * fsck: get file type according to i_mode instead of F2FS_FT_REG_FILE

v2->v1:
  * discard obsolete dnodes after all inodes are created.
  * add new error message if file type (i_mode) is totally wrong.
  * change "-O lost+found" to "-O lost_found".
  * only set filename and bitmap in the second slot of lost+found dentry.
  * handle inode_crtime when creating lost+found inode.
  * fix endiain issue.
  * fix memory leak in fsck_failed_reconnect_file{_dnode|_idnode|_didnode}.
  * translate i_mode to FILE_TYPE instead of F2FS_FT_REG_FILE when
reconnecting files.
  * get_node_info() reads nat block again if nat entry is invalid.
---8<---

Commit 390fe587b1 ("fsck.f2fs: support restore lost files into
./lost_found/") restores unreachable files, which have no parent directory
or their parent directories are removed by fsck, to ./lost_found directory.

However, it has several limitations:
  1. ./lost_found dir does not locate inside f2fs, thus it may needs
 another partition to save ./lost_found.
  2. encrypted files are not supported to be restored.
  3. some xattrs may be lost, it depends on whether dump_node() enables
 dumping such xattrs.
  4. not support restoring files on Android devices (the same reason as
 #1).

In order to address the above limitations, the LOST_FOUND feature is
introduced. This is an ext4-style lost+found. It tries to restore
unreachable files into /lost+found directory inside f2fs.

If LOST_FOUND feature is switched on when mkfs, /lost+found directory is
created by mkfs. It can also be created by mkdir manually. It should be
located right under root directory.

If fsck detects unreachable nids, it scans all these nids, and skips non-
inode or directory inode nodes. For the left nids, they are all file inodes.
Fsck then checks these inodes and update corresponding counters and bitmaps.

From now on, the filesystem is in a "consistent" state, fsck can allocate
blocks safely and start reconnecting files to lost+found. The reconnection
adds new dentry in lost+found and update metadata (i_name, i_pino) of file
inode. If reconnection fails, fsck will clear the counters and bitmaps.
Files reconnected to lost+found will be renamed after its ino number.

However, because of lost+found directory, f2fs should avoid to encrypting
root directory. So f2fs should also check if LOST_FOUND feature is enabled
or not.

I create testcases which inject faults to generate unreachable nids. To
enable LOST_FOUND, we should give "-O lost_found" to mkfs.

# mkfs.f2fs -O lost_found -O encrypt test.img
# tree /data/
/data/
├── dir
│   ├── foo
│   └── subdir
│   └── bar
├── encrypt-dir
│   ├── encrypt-foo
│   └── encrypt-subdir
│   └── encrypt-bar
└── lost+found

5 directories, 4 files

Testcases:
1) corrupt nat_entry->blk_addr of dir [PASS]
2) corrupt nat_entry->blk_addr of encrypt-dir [PASS]
3) remove lost+found, then corrupt nat_entry->blk_addr of dir [PASS]

Any comments and tests are appreciated.

Thanks,
Sheng

Sheng Yong (2):
  mkfs.f2fs: create lost+found directory
  fsck.f2fs: reconnect unreachable files to lost+found

 fsck/dir.c  |  19 ++-
 fsck/fsck.c | 389 +++-
 fsck/fsck.h |   3 +
 fsck/mount.c|   5 +
 include/f2fs_fs.h   |   6 +
 mkfs/f2fs_format.c  | 223 +--
 mkfs/f2fs_format_main.c |   2 +
 7 files changed, 632 insertions(+), 15 deletions(-)

-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v3 1/2] mkfs.f2fs: create lost+found directory

2018-03-05 Thread Sheng Yong
This patch introduces a new feature F2FS_FEATURE_LOST_FOUND. It can be
switched on by indicating `-O lost_found'. If LOST_FOUND feature is
enabled, an empty directory lost+found is created by mkfs.

This is a preparation for fsck. During fsck, the directory is used to
save unreachable files, which have no parent directory or their parent
directory is removed by fsck. Encrypted files are also allowed to be
saved here.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
Reviewed-by: Chao Yu <yuch...@huawei.com>
---
 fsck/mount.c|   3 +
 include/f2fs_fs.h   |   6 ++
 mkfs/f2fs_format.c  | 223 +---
 mkfs/f2fs_format_main.c |   2 +
 4 files changed, 222 insertions(+), 12 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 7c3f312..b8e7643 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -460,6 +460,9 @@ void print_sb_state(struct f2fs_super_block *sb)
if (f & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
MSG(0, "%s", " inode_crtime");
}
+   if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
+   MSG(0, "%s", " lost_found");
+   }
MSG(0, "\n");
MSG(0, "Info: superblock encrypt level = %d, salt = ",
sb->encryption_level);
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index ca4522d..093c402 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -291,6 +291,8 @@ static inline uint64_t bswap_64(uint64_t val)
 
 #define VERSION_LEN256
 
+#define LPF "lost+found"
+
 enum f2fs_config_func {
MKFS,
FSCK,
@@ -369,6 +371,9 @@ struct f2fs_configuration {
u_int32_t next_free_nid;
u_int32_t quota_inum;
u_int32_t quota_dnum;
+   u_int32_t lpf_inum;
+   u_int32_t lpf_dnum;
+   u_int32_t lpf_ino;
 
/* defragmentation parameters */
int defrag_shrink;
@@ -557,6 +562,7 @@ enum {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define MAX_VOLUME_NAME512
 
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index c9492f6..d277740 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -426,6 +426,9 @@ static int f2fs_prepare_super_block(void)
qtype, c.next_free_nid - 1);
}
 
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_LOST_FOUND))
+   c.lpf_ino = c.next_free_nid++;
+
if (total_zones <= 6) {
MSG(1, "\tError: %d zones: Need more zones "
"by shrinking zone size\n", total_zones);
@@ -608,9 +611,10 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_segno[i], 0x);
}
 
-   set_cp(cur_node_blkoff[0], 1 + c.quota_inum);
-   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum);
-   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum);
+   set_cp(cur_node_blkoff[0], 1 + c.quota_inum + c.lpf_inum);
+   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum + c.lpf_dnum);
+   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum +
+   c.lpf_inum + c.lpf_dnum);
set_cp(rsvd_segment_count, c.reserved_segments);
set_cp(overprov_segment_count, (get_sb(segment_count_main) -
get_cp(rsvd_segment_count)) *
@@ -642,8 +646,8 @@ static int f2fs_write_check_point_pack(void)
 
set_cp(ckpt_flags, flags);
set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload));
-   set_cp(valid_node_count, 1 + c.quota_inum);
-   set_cp(valid_inode_count, 1 + c.quota_inum);
+   set_cp(valid_node_count, 1 + c.quota_inum + c.lpf_inum);
+   set_cp(valid_inode_count, 1 + c.quota_inum + c.lpf_inum);
set_cp(next_free_nid, c.next_free_nid);
set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) <<
get_sb(log_blocks_per_seg)) / 8);
@@ -702,7 +706,7 @@ static int f2fs_write_check_point_pack(void)
SET_SUM_TYPE((>footer), SUM_TYPE_DATA);
 
journal = >journal;
-   journal->n_nats = cpu_to_le16(1 + c.quota_inum);
+   journal->n_nats = cpu_to_le16(1 + c.quota_inum + c.lpf_inum);
journal->nat_j.entries[0].nid = sb->root_ino;
journal->nat_j.entries[0].ne.version = 0;
journal->nat_j.entries[0].ne.ino = sb->root_ino;
@@ -723,6 +727,16 @@ static int f2fs_write_check_point_pack(void)
i++;
}
 
+   if (c.lpf_inum) {
+   journal->nat_j.entries[i].nid = cpu_to_le32(c.lpf_ino);
+   journal->nat_j.entries[i].ne.version = 0;
+   journal->nat_j.entries[i].ne.ino = cpu_to_le32(c.lpf_ino);
+   jou

[f2fs-dev] [RFC PATCH v3] f2fs: introduce F2FS_FEATURE_LOST_FOUND feature

2018-03-05 Thread Sheng Yong
This patch introduces a new feature, F2FS_FEATURE_LOST_FOUND, which
is set by mkfs. It creates a directory named lost+found, which saves
unreachable files. If fsck finds a file which has no parent, or its
parent is removed by fsck, the file will be placed under lost+found
directory by fsck.

lost+found directory could not be encrypted. As a result, the root
directory cannot be encrypted too. So if LOST_FOUND feature is enabled,
let's avoid to encrypt root directory.

This patch also introduces a new mount option `test_dummy_encryption'
to allow fscrypt to create a fake fscrypt context. This is used by
xfstests.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v3->v2:
 * fix test_dummy_encryption
v2->v1:
 * introduce new mount option test_dummy_encryption
 * add sysfs entry for LOST_FOUND feature

 fs/f2fs/dir.c   |  6 --
 fs/f2fs/f2fs.h  | 17 +
 fs/f2fs/namei.c |  9 ++---
 fs/f2fs/super.c | 56 +++-
 fs/f2fs/sysfs.c |  7 +++
 5 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 797eb05cb538..7f908be8d525 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -361,6 +361,7 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
struct page *dpage)
 {
struct page *page;
+   int encrypt = DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(dir));
int err;
 
if (is_inode_flag_set(inode, FI_NEW_INODE)) {
@@ -387,7 +388,8 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
if (err)
goto put_error;
 
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
+   if ((f2fs_encrypted_inode(dir) || encrypt) &&
+   f2fs_may_encrypt(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false);
if (err)
goto put_error;
@@ -402,7 +404,7 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
 
if (new_name) {
init_dent_inode(new_name, page);
-   if (f2fs_encrypted_inode(dir))
+   if (f2fs_encrypted_inode(dir) || encrypt)
file_set_enc_name(inode);
}
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f6dc70666ebb..77af79d0376b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -125,6 +125,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -1052,6 +1053,15 @@ enum {
ALLOC_MODE_REUSE,   /* reuse segments as much as possible */
 };
 
+#define F2FS_MF_TEST_DUMMY_ENCRYPTION  0x0001
+
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->mount_flags & \
+   F2FS_MF_TEST_DUMMY_ENCRYPTION))
+#else
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+#endif
+
 struct f2fs_sb_info {
struct super_block *sb; /* pointer to VFS super block */
struct proc_dir_entry *s_proc;  /* proc entry */
@@ -1241,6 +1251,8 @@ struct f2fs_sb_info {
 
/* segment allocation policy */
int alloc_mode;
+
+   unsigned int mount_flags;
 };
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
@@ -3201,6 +3213,10 @@ static inline bool f2fs_bio_encrypted(struct bio *bio)
 static inline int f2fs_sb_has_##name(struct super_block *sb) \
 { \
return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_##flagname); \
+} \
+static inline int f2fs_sb_set_##name(struct super_block *sb) \
+{ \
+   return F2FS_SET_FEATURE(sb, F2FS_FEATURE_##flagname); \
 }
 
 F2FS_FEATURE_FUNCS(encrypt, ENCRYPT);
@@ -3211,6 +3227,7 @@ F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
 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);
 
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline int get_blkz_type(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 318dfe870cb5..5dd6a112e13d 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -78,7 +78,8 @@ static struct inode *f2fs_new_inode(struct inode *dir, 
umode_t mode)
set_inode_flag(inode, FI_NEW_INODE);
 
/* If the directory encrypted, then we should encrypt the inode. */
-   if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode))
+   if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+   f2fs_may_e

[f2fs-dev] [RFC PATCH v3 2/2] fsck.f2fs: reconnect unreachable files to lost+found

2018-03-05 Thread Sheng Yong
This patch introduces lost_found feature to fsck. If a file is found
unreachable by fsck. Fsck tries to reconnect the file to lost+found
directory:
  1. Scan all unreachable file inodes, ignore non-inodes ones and
 directories.
  2. Check them and fix incorrupted data to make sure filesystem
 metadata (mainly counters and main/nat bitmap) are all consistent.
  3. Reconnect these files to lost+found. If lost+found does not exist,
 create it first. During reconnecting, expand lost+found's dentry
 block automatically. Reconnected files are renamed after its ino
 number.
  4. If reconnect fails drop the node and restore filesystem metadata.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/dir.c   |  19 ++-
 fsck/fsck.c  | 389 ++-
 fsck/fsck.h  |   3 +
 fsck/mount.c |   2 +
 4 files changed, 410 insertions(+), 3 deletions(-)

diff --git a/fsck/dir.c b/fsck/dir.c
index b2ea18f..567a4e9 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -176,6 +176,23 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,
return 0;
 }
 
+/* return ino if file exists, otherwise return 0 */
+nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
+   u8 *name, int len)
+{
+   int err;
+   struct dentry de = {
+   .name = name,
+   .len = len,
+   };
+
+   err = f2fs_find_entry(sbi, dir, );
+   if (err == 1)
+   return de.ino;
+   else
+   return 0;
+}
+
 static void f2fs_update_dentry(nid_t ino, int file_type,
struct f2fs_dentry_ptr *d,
const unsigned char *name, int len, f2fs_hash_t name_hash,
@@ -199,7 +216,7 @@ static void f2fs_update_dentry(nid_t ino, int file_type,
 /*
  * f2fs_add_link - Add a new file(dir) to parent dir.
  */
-static int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
+int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
const unsigned char *name, int name_len, nid_t ino,
int file_type, block_t p_blkaddr, int inc_link)
 {
diff --git a/fsck/fsck.c b/fsck/fsck.c
index f6391e9..bc91839 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
  */
 #include "fsck.h"
 #include "quotaio.h"
+#include 
 
 char *tree_mark;
 uint32_t tree_mark_size = 256;
@@ -43,6 +44,14 @@ static inline int f2fs_test_main_bitmap(struct f2fs_sb_info 
*sbi, u32 blk)
fsck->main_area_bitmap);
 }
 
+static inline int f2fs_clear_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+   return f2fs_clear_bit(BLKOFF_FROM_MAIN(sbi, blk),
+   fsck->main_area_bitmap);
+}
+
 static inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -453,9 +462,11 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
 
/* workaround to fix later */
if (ftype != F2FS_FT_ORPHAN ||
-   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {
f2fs_clear_bit(nid, fsck->nat_area_bitmap);
-   else
+   /* avoid reusing nid when reconnecting files */
+   f2fs_set_bit(nid, NM_I(sbi)->nid_bitmap);
+   } else
ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
nid);
 
@@ -2046,6 +2057,370 @@ int check_sit_types(struct f2fs_sb_info *sbi)
return err;
 }
 
+static struct f2fs_node *fsck_get_lpf(struct f2fs_sb_info *sbi)
+{
+   struct f2fs_node *node;
+   struct node_info ni;
+   nid_t lpf_ino;
+   int err;
+
+   /* read root inode first */
+   node = calloc(F2FS_BLKSIZE, 1);
+   ASSERT(node);
+   get_node_info(sbi, F2FS_ROOT_INO(sbi), );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+
+   /* lookup lost+found in root directory */
+   lpf_ino = f2fs_lookup(sbi, node, (u8 *)LPF, strlen(LPF));
+   if (lpf_ino) { /* found */
+   get_node_info(sbi, lpf_ino, );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+   DBG(1, "Found lost+found 0x%x at blkaddr [0x%x]\n",
+   lpf_ino, ni.blk_addr);
+   if (!S_ISDIR(le16_to_cpu(node->i.i_mode))) {
+   ASSERT_MSG("lost+found is not directory [0%o]\n",
+  le16_to_cpu(node->i.i_mode));
+   /* FIXME: give up? */
+   goto out;
+   }
+   } else { /* not found, create it */
+   struct dentry de;
+
+   memset(, 0, 

[f2fs-dev] [PATCH] fibmap: include f2fs_fs.h before other header files

2018-02-27 Thread Sheng Yong
GCC 7.2.0 is unhappy with the usage of major/minor:

fibmap.c: In function ‘print_stat’:
fibmap.c:70:13: warning: In the GNU C Library, "major" is defined
 by . For historical compatibility, it is
 currently defined by  as well, but we plan to
 remove this soon. To use "major", include 
 directly. If you did not intend to use a system-defined macro
 "major", you should undefine it after including .
  printf("dev   [%d:%d]\n", major(st->st_dev), minor(st->st_dev));
 ^

This is because config.h is not included first, as a result, macros
defined in config.h is not recognized. So let's include f2fs_fs.h
before other header files.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 tools/fibmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/fibmap.c b/tools/fibmap.c
index d17144a..9e96cb6 100644
--- a/tools/fibmap.c
+++ b/tools/fibmap.c
@@ -15,6 +15,7 @@
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
+#include 
 #include 
 #include 
 #include 
@@ -38,7 +39,6 @@
 #include 
 #endif
 #include 
-#include 
 
 #ifndef FIBMAP
 #define FIBMAP  _IO(0x00, 1)/* bmap access */
-- 
2.15.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2] f2fs: introduce F2FS_FEATURE_LOST_FOUND feature

2018-02-22 Thread Sheng Yong
This patch introduces a new feature, F2FS_FEATURE_LOST_FOUND, which
is set by mkfs. It creates a directory named lost+found, which saves
unreachable files. If fsck finds a file which has no parent, or its
parent is removed by fsck, the file will be placed under lost+found
directory by fsck.

lost+found directory could not be encrypted. As a result, the root
directory cannot be encrypted too. So if LOST_FOUND feature is enabled,
let's avoid to encrypt root directory.

This patch also introduces a new mount option `test_dummy_context'
to allow fscrypt to create a fake fscrypt context. This is used by
xfstests.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v2->v1:
 * introduce new mount option test_dummy_context
 * add sysfs entry for LOST_FOUND feature

 fs/f2fs/f2fs.h  |  6 ++
 fs/f2fs/super.c | 37 +
 fs/f2fs/sysfs.c |  7 +++
 3 files changed, 50 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 8b251bc8d38c..3e9283b3b3f5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -125,6 +125,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -1043,6 +1044,8 @@ enum {
WHINT_MODE_FS,  /* pass down hints with F2FS policy */
 };
 
+#define F2FS_MF_TEST_DUMMY_ENCRYPTION  0x0001
+
 struct f2fs_sb_info {
struct super_block *sb; /* pointer to VFS super block */
struct proc_dir_entry *s_proc;  /* proc entry */
@@ -1228,6 +1231,8 @@ struct f2fs_sb_info {
 #endif
/* For which write hints are passed down to block layer */
int whint_mode;
+
+   unsigned int mount_flags;
 };
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
@@ -3202,6 +3207,7 @@ F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
 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);
 
 #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 338a8cb8a489..d2d2a2768b91 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -130,6 +130,7 @@ enum {
Opt_jqfmt_vfsv0,
Opt_jqfmt_vfsv1,
Opt_whint,
+   Opt_test_dummy_encryption,
Opt_err,
 };
 
@@ -184,6 +185,7 @@ static match_table_t f2fs_tokens = {
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
{Opt_whint, "whint_mode=%s"},
+   {Opt_test_dummy_encryption, "test_dummy_encryption"},
{Opt_err, NULL},
 };
 
@@ -700,6 +702,18 @@ static int parse_options(struct super_block *sb, char 
*options)
}
kfree(name);
break;
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+   case Opt_test_dummy_encryption:
+   sbi->mount_flags |= F2FS_MF_TEST_DUMMY_ENCRYPTION;
+   f2fs_msg(sb, KERN_INFO,
+   "Test dummy encryption mode enabled");
+   break;
+#else
+   case Opt_test_dummy_encryption:
+   f2fs(sb, KERN_INFO,
+   "Test dummy encryption mount option 
ignored");
+   break;
+#endif
default:
f2fs_msg(sb, KERN_ERR,
"Unrecognized mount option \"%s\" or missing 
value",
@@ -1263,6 +1277,10 @@ static int f2fs_show_options(struct seq_file *seq, 
struct dentry *root)
seq_printf(seq, ",whint_mode=%s", "user-based");
else if (sbi->whint_mode == WHINT_MODE_FS)
seq_printf(seq, ",whint_mode=%s", "fs-based");
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+   if (sbi->mount_flags & F2FS_MF_TEST_DUMMY_ENCRYPTION)
+   seq_puts(seq, ",test_dummy_encryption");
+#endif
 
return 0;
 }
@@ -1837,11 +1855,29 @@ static int f2fs_get_context(struct inode *inode, void 
*ctx, size_t len)
 static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
 {
+   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+   /*
+* Encrypting the root directory is not allowed because fsck
+* expects lost+found directory to exist and remain unencrypted
+* if LOST_FOUND feature is enabled.
+*
+*/
+   if (f2fs_sb_has_lost_found(sbi-&g

[f2fs-dev] [RFC PATCH v2 4/7] fsck.f2fs: integrate sanity_check_inode to __check_inode_mode

2018-02-22 Thread Sheng Yong
In sanity_check_nid, __check_inode_mode will check i_mode value of an
inode. So integrate sanity_check_inode to __check_inode_mode to clean
up the code.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/fsck.c | 33 +++--
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 0a37f7a..f6391e9 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -334,6 +334,15 @@ static int __check_inode_mode(u32 nid, enum FILE_TYPE 
ftype, u32 mode)
 {
if (ftype >= F2FS_FT_MAX)
return 0;
+   /* f2fs_iget will return -EIO if mode is not valid file type */
+   if (!S_ISLNK(mode) && !S_ISREG(mode) && !S_ISDIR(mode) &&
+   !S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode) &&
+   !S_ISSOCK(mode)) {
+   ASSERT_MSG("inode [0x%x] unknown file type i_mode [0x%x]",
+  nid, mode);
+   return -1;
+   }
+
if (S_ISLNK(mode) && ftype != F2FS_FT_SYMLINK)
goto err;
if (S_ISREG(mode) && ftype != F2FS_FT_REG_FILE)
@@ -350,7 +359,8 @@ static int __check_inode_mode(u32 nid, enum FILE_TYPE 
ftype, u32 mode)
goto err;
return 0;
 err:
-   ASSERT_MSG("mismatch i_mode [0x%x] [0x%x vs. 0x%x]", nid, ftype, mode);
+   ASSERT_MSG("inode [0x%x] mismatch i_mode [0x%x vs. 0x%x]",
+  nid, ftype, mode);
return -1;
 }
 
@@ -465,25 +475,6 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
return 0;
 }
 
-static int sanity_check_inode(struct f2fs_sb_info *sbi, struct f2fs_node *node)
-{
-   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
-   struct f2fs_inode *fi = >i;
-
-   if (!(le16_to_cpu(fi->i_mode) & S_IFMT)) {
-   ASSERT_MSG("i_mode is not valid. [0x%x]", 
le16_to_cpu(fi->i_mode));
-   goto remove_node;
-   }
-
-   return 0;
-
-remove_node:
-   f2fs_set_bit(le32_to_cpu(node->footer.ino), fsck->nat_area_bitmap);
-   fsck->chk.valid_blk_cnt--;
-   fsck->chk.valid_node_cnt--;
-   return -EINVAL;
-}
-
 static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
u32 x_nid, u32 *blk_cnt)
 {
@@ -528,8 +519,6 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
if (ntype == TYPE_INODE) {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 
-   if (sanity_check_inode(sbi, node_blk))
-   goto err;
fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, , 
child);
quota_add_inode_usage(fsck->qctx, nid, _blk->i);
} else {
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2 6/7] fsck.f2fs: read nat block if nat entry is invalid

2018-02-22 Thread Sheng Yong
fsck will cache all valid nat entries in memory. But when we try to
get a nat entry which is not cached, for example allocate a new nid
during reconnecting files, we need to read the uncached nat entry
from nat block again.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/mount.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 6482721..b8e7643 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1600,7 +1600,9 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, 
struct node_info *ni)
ni->nid = nid;
if (c.func == FSCK) {
node_info_from_raw_nat(ni, &(F2FS_FSCK(sbi)->entries[nid]));
-   return;
+   if (ni->blk_addr)
+   return;
+   /* nat entry is not cached, read it */
}
 
get_nat_entry(sbi, nid, _nat);
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2 2/7] mkfs.f2fs: introduce mkfs parameters in f2fs_configuration

2018-02-22 Thread Sheng Yong
Introduce new parameters in f2fs_configuration for mkfs:
  * next_free_nid: save the next free nid
  * quota_inum: save how many blocks are used for quota inodes
  * quota_dnum: save how many blocks are used for quota data

Use these parameters to avoid duplicated count of these values. And
discard obsolete dnodes after all inodes are created.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 include/f2fs_fs.h  |  5 
 mkfs/f2fs_format.c | 85 ++
 2 files changed, 46 insertions(+), 44 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 548a3e8..ca4522d 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -365,6 +365,11 @@ struct f2fs_configuration {
int large_nat_bitmap;
__le32 feature; /* defined features */
 
+   /* mkfs parameters */
+   u_int32_t next_free_nid;
+   u_int32_t quota_inum;
+   u_int32_t quota_dnum;
+
/* defragmentation parameters */
int defrag_shrink;
u_int64_t defrag_start;
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 4fb429e..5eaeff4 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -159,7 +159,6 @@ static int f2fs_prepare_super_block(void)
u_int32_t sit_bitmap_size, max_sit_bitmap_size;
u_int32_t max_nat_bitmap_size, max_nat_segments;
u_int32_t total_zones;
-   u_int32_t next_ino;
enum quota_type qtype;
int i;
 
@@ -411,7 +410,7 @@ static int f2fs_prepare_super_block(void)
set_sb(node_ino, 1);
set_sb(meta_ino, 2);
set_sb(root_ino, 3);
-   next_ino = 4;
+   c.next_free_nid = 4;
 
if (c.feature & cpu_to_le32(F2FS_FEATURE_QUOTA_INO)) {
quotatype_bits = QUOTA_USR_BIT | QUOTA_GRP_BIT;
@@ -422,9 +421,9 @@ static int f2fs_prepare_super_block(void)
for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++) {
if (!((1 << qtype) & quotatype_bits))
continue;
-   sb->qf_ino[qtype] = cpu_to_le32(next_ino++);
+   sb->qf_ino[qtype] = cpu_to_le32(c.next_free_nid++);
MSG(0, "Info: add quota type = %u => %u\n",
-   qtype, next_ino - 1);
+   qtype, c.next_free_nid - 1);
}
 
if (total_zones <= 6) {
@@ -558,7 +557,6 @@ static int f2fs_write_check_point_pack(void)
char *sum_compact, *sum_compact_p;
struct f2fs_summary *sum_entry;
enum quota_type qtype;
-   u_int32_t quota_inum, quota_dnum;
int off;
int ret = -1;
 
@@ -610,16 +608,9 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_segno[i], 0x);
}
 
-   quota_inum = quota_dnum = 0;
-   for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++)
-   if (sb->qf_ino[qtype]) {
-   quota_inum++;
-   quota_dnum += QUOTA_DATA(qtype);
-   }
-
-   set_cp(cur_node_blkoff[0], 1 + quota_inum);
-   set_cp(cur_data_blkoff[0], 1 + quota_dnum);
-   set_cp(valid_block_count, 2 + quota_inum + quota_dnum);
+   set_cp(cur_node_blkoff[0], 1 + c.quota_inum);
+   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum);
+   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum);
set_cp(rsvd_segment_count, c.reserved_segments);
set_cp(overprov_segment_count, (get_sb(segment_count_main) -
get_cp(rsvd_segment_count)) *
@@ -651,9 +642,9 @@ static int f2fs_write_check_point_pack(void)
 
set_cp(ckpt_flags, flags);
set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload));
-   set_cp(valid_node_count, 1 + quota_inum);
-   set_cp(valid_inode_count, 1 + quota_inum);
-   set_cp(next_free_nid, get_sb(root_ino) + 1 + quota_inum);
+   set_cp(valid_node_count, 1 + c.quota_inum);
+   set_cp(valid_inode_count, 1 + c.quota_inum);
+   set_cp(next_free_nid, c.next_free_nid);
set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) <<
get_sb(log_blocks_per_seg)) / 8);
 
@@ -711,7 +702,7 @@ static int f2fs_write_check_point_pack(void)
SET_SUM_TYPE((>footer), SUM_TYPE_DATA);
 
journal = >journal;
-   journal->n_nats = cpu_to_le16(1 + quota_inum);
+   journal->n_nats = cpu_to_le16(1 + c.quota_inum);
journal->nat_j.entries[0].nid = sb->root_ino;
journal->nat_j.entries[0].ne.version = 0;
journal->nat_j.entries[0].ne.ino = sb->root_ino;
@@ -741,9 +732,9 @@ static int f2fs_write_check_point_pack(void)
journal->sit_j.entries[0].segno = cp->cur_node_segno[0];
journal->sit_j.entries[0].se.vblocks =
cpu_to_le16((CURSEG_HOT_NODE << 10) |
-   (1 + quota_inum));

[f2fs-dev] [RFC PATCH v2 3/7] f2fs-tools: init f2fs_configuration as 0

2018-02-22 Thread Sheng Yong
Signed-off-by: Sheng Yong <shengyo...@huawei.com>
Reviewed-by: Chao Yu <yuch...@huawei.com>
---
 lib/libf2fs.c | 18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index e8b1842..0c684d5 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -586,24 +586,17 @@ void f2fs_init_configuration(void)
 {
int i;
 
+   memset(, 0, sizeof(struct f2fs_configuration));
c.ndevs = 1;
-   c.total_sectors = 0;
-   c.sector_size = 0;
c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
c.rootdev_name = get_rootdev();
c.wanted_total_sectors = -1;
-   c.zoned_mode = 0;
-   c.zoned_model = 0;
-   c.zone_blocks = 0;
-#ifdef WITH_ANDROID
-   c.preserve_limits = 0;
-#else
+#ifndef WITH_ANDROID
c.preserve_limits = 1;
 #endif
 
for (i = 0; i < MAX_DEVICES; i++) {
-   memset([i], 0, sizeof(struct device_info));
c.devices[i].fd = -1;
c.devices[i].sector_size = DEFAULT_SECTOR_SIZE;
c.devices[i].end_blkaddr = -1;
@@ -611,19 +604,12 @@ void f2fs_init_configuration(void)
}
 
/* calculated by overprovision ratio */
-   c.reserved_segments = 0;
-   c.overprovision = 0;
c.segs_per_sec = 1;
c.secs_per_zone = 1;
c.segs_per_zone = 1;
-   c.heap = 0;
c.vol_label = "";
c.trim = 1;
-   c.trimmed = 0;
-   c.ro = 0;
c.kd = -1;
-   c.dry_run = 0;
-   c.large_nat_bitmap = 0;
c.fixed_time = -1;
 }
 
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2 5/7] mkfs.f2fs: create lost+found directory

2018-02-22 Thread Sheng Yong
This patch introduces a new feature F2FS_FEATURE_LOST_FOUND. It can be
switched on by indicating `-O lost_found'. If LOST_FOUND feature is
enabled, an empty directory lost+found is created by mkfs.

This is a preparation for fsck. During fsck, the directory is used to
save unreachable files, which have no parent directory or their parent
directory is removed by fsck. Encrypted files are also allowed to be
saved here.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/mount.c|   3 +
 include/f2fs_fs.h   |   6 ++
 mkfs/f2fs_format.c  | 224 +---
 mkfs/f2fs_format_main.c |   2 +
 4 files changed, 223 insertions(+), 12 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 46cb571..6482721 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -460,6 +460,9 @@ void print_sb_state(struct f2fs_super_block *sb)
if (f & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
MSG(0, "%s", " inode_crtime");
}
+   if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
+   MSG(0, "%s", " lost_found");
+   }
MSG(0, "\n");
MSG(0, "Info: superblock encrypt level = %d, salt = ",
sb->encryption_level);
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index ca4522d..093c402 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -291,6 +291,8 @@ static inline uint64_t bswap_64(uint64_t val)
 
 #define VERSION_LEN256
 
+#define LPF "lost+found"
+
 enum f2fs_config_func {
MKFS,
FSCK,
@@ -369,6 +371,9 @@ struct f2fs_configuration {
u_int32_t next_free_nid;
u_int32_t quota_inum;
u_int32_t quota_dnum;
+   u_int32_t lpf_inum;
+   u_int32_t lpf_dnum;
+   u_int32_t lpf_ino;
 
/* defragmentation parameters */
int defrag_shrink;
@@ -557,6 +562,7 @@ enum {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define MAX_VOLUME_NAME512
 
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 5eaeff4..4145c79 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -426,6 +426,9 @@ static int f2fs_prepare_super_block(void)
qtype, c.next_free_nid - 1);
}
 
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_LOST_FOUND))
+   c.lpf_ino = c.next_free_nid++;
+
if (total_zones <= 6) {
MSG(1, "\tError: %d zones: Need more zones "
"by shrinking zone size\n", total_zones);
@@ -608,9 +611,10 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_segno[i], 0x);
}
 
-   set_cp(cur_node_blkoff[0], 1 + c.quota_inum);
-   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum);
-   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum);
+   set_cp(cur_node_blkoff[0], 1 + c.quota_inum + c.lpf_inum);
+   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum + c.lpf_dnum);
+   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum +
+   c.lpf_inum + c.lpf_dnum);
set_cp(rsvd_segment_count, c.reserved_segments);
set_cp(overprov_segment_count, (get_sb(segment_count_main) -
get_cp(rsvd_segment_count)) *
@@ -642,8 +646,8 @@ static int f2fs_write_check_point_pack(void)
 
set_cp(ckpt_flags, flags);
set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload));
-   set_cp(valid_node_count, 1 + c.quota_inum);
-   set_cp(valid_inode_count, 1 + c.quota_inum);
+   set_cp(valid_node_count, 1 + c.quota_inum + c.lpf_inum);
+   set_cp(valid_inode_count, 1 + c.quota_inum + c.lpf_inum);
set_cp(next_free_nid, c.next_free_nid);
set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) <<
get_sb(log_blocks_per_seg)) / 8);
@@ -702,7 +706,7 @@ static int f2fs_write_check_point_pack(void)
SET_SUM_TYPE((>footer), SUM_TYPE_DATA);
 
journal = >journal;
-   journal->n_nats = cpu_to_le16(1 + c.quota_inum);
+   journal->n_nats = cpu_to_le16(1 + c.quota_inum + c.lpf_inum);
journal->nat_j.entries[0].nid = sb->root_ino;
journal->nat_j.entries[0].ne.version = 0;
journal->nat_j.entries[0].ne.ino = sb->root_ino;
@@ -723,6 +727,16 @@ static int f2fs_write_check_point_pack(void)
i++;
}
 
+   if (c.lpf_inum) {
+   journal->nat_j.entries[i].nid = cpu_to_le32(c.lpf_ino);
+   journal->nat_j.entries[i].ne.version = 0;
+   journal->nat_j.entries[i].ne.ino = cpu_to_le32(c.lpf_ino);
+   journal-&

[f2fs-dev] [RFC PATCH v2 7/7] fsck.f2fs: reconnect unreachable files to lost+found

2018-02-22 Thread Sheng Yong
This patch introduces lost_found feature to fsck. If a file is found
unreachable by fsck. Fsck tries to reconnect the file to lost+found
directory:
  1. Scan all unreachable file inodes, ignore non-inodes ones and
 directories.
  2. Check them and fix incorrupted data to make sure filesystem
 metadata (mainly counters and main/nat bitmap) are all consistent.
  3. Reconnect these files to lost+found. If lost+found does not exist,
 create it first. During reconnecting, expand lost+found's dentry
 block automatically. Reconnected files are renamed after its ino
 number.
  4. If reconnect fails drop the node and restore filesystem metadata.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/dir.c   |  19 ++-
 fsck/fsck.c  | 388 ++-
 fsck/fsck.h  |   3 +
 fsck/mount.c |   2 +
 4 files changed, 409 insertions(+), 3 deletions(-)

diff --git a/fsck/dir.c b/fsck/dir.c
index b2ea18f..567a4e9 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -176,6 +176,23 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,
return 0;
 }
 
+/* return ino if file exists, otherwise return 0 */
+nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
+   u8 *name, int len)
+{
+   int err;
+   struct dentry de = {
+   .name = name,
+   .len = len,
+   };
+
+   err = f2fs_find_entry(sbi, dir, );
+   if (err == 1)
+   return de.ino;
+   else
+   return 0;
+}
+
 static void f2fs_update_dentry(nid_t ino, int file_type,
struct f2fs_dentry_ptr *d,
const unsigned char *name, int len, f2fs_hash_t name_hash,
@@ -199,7 +216,7 @@ static void f2fs_update_dentry(nid_t ino, int file_type,
 /*
  * f2fs_add_link - Add a new file(dir) to parent dir.
  */
-static int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
+int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
const unsigned char *name, int name_len, nid_t ino,
int file_type, block_t p_blkaddr, int inc_link)
 {
diff --git a/fsck/fsck.c b/fsck/fsck.c
index f6391e9..9a822ef 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
  */
 #include "fsck.h"
 #include "quotaio.h"
+#include 
 
 char *tree_mark;
 uint32_t tree_mark_size = 256;
@@ -43,6 +44,14 @@ static inline int f2fs_test_main_bitmap(struct f2fs_sb_info 
*sbi, u32 blk)
fsck->main_area_bitmap);
 }
 
+static inline int f2fs_clear_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+   return f2fs_clear_bit(BLKOFF_FROM_MAIN(sbi, blk),
+   fsck->main_area_bitmap);
+}
+
 static inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -453,9 +462,11 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
 
/* workaround to fix later */
if (ftype != F2FS_FT_ORPHAN ||
-   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {
f2fs_clear_bit(nid, fsck->nat_area_bitmap);
-   else
+   /* avoid reusing nid when reconnecting files */
+   f2fs_set_bit(nid, NM_I(sbi)->nid_bitmap);
+   } else
ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
nid);
 
@@ -2046,6 +2057,369 @@ int check_sit_types(struct f2fs_sb_info *sbi)
return err;
 }
 
+static struct f2fs_node *fsck_get_lpf(struct f2fs_sb_info *sbi)
+{
+   struct f2fs_node *node;
+   struct node_info ni;
+   nid_t lpf_ino;
+   int err;
+
+   /* read root inode first */
+   node = calloc(F2FS_BLKSIZE, 1);
+   ASSERT(node);
+   get_node_info(sbi, F2FS_ROOT_INO(sbi), );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+
+   /* lookup lost+found in root directory */
+   lpf_ino = f2fs_lookup(sbi, node, (u8 *)LPF, strlen(LPF));
+   if (lpf_ino) { /* found */
+   get_node_info(sbi, lpf_ino, );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+   DBG(1, "Found lost+found 0x%x at blkaddr [0x%x]\n",
+   lpf_ino, ni.blk_addr);
+   if (!S_ISDIR(le16_to_cpu(node->i.i_mode))) {
+   ASSERT_MSG("lost+found is not directory [0%o]\n",
+  le16_to_cpu(node->i.i_mode));
+   /* FIXME: give up? */
+   goto out;
+   }
+   } else { /* not found, create it */
+   struct dentry de;
+
+   memset(, 0, 

[f2fs-dev] [RFC PATCH v2 0/7] f2fs-tools: introduce F2FS_FEATURE_LOST_FOUND feature

2018-02-22 Thread Sheng Yong
v2->v1:
  * discard obsolete dnodes after all inodes are created.
  * add new error message if file type (i_mode) is totally wrong.
  * change "-O lost+found" to "-O lost_found".
  * only set filename and bitmap in the second slot of lost+found dentry.
  * handle inode_crtime when creating lost+found inode.
  * fix endiain issue.
  * fix memory leak in fsck_failed_reconnect_file{_dnode|_idnode|_didnode}.
  * translate i_mode to FILE_TYPE instead of F2FS_FT_REG_FILE when
reconnecting files.
  * get_node_info() reads nat block again if nat entry is invalid.
---o<---

Commit 390fe587b1 ("fsck.f2fs: support restore lost files into
./lost_found/") restores unreachable files, which have no parent directory
or their parent directories are removed by fsck, to ./lost_found directory.

However, it has several limitations:
  1. ./lost_found dir does not locate inside f2fs, thus it may needs
 another partition to save ./lost_found.
  2. encrypted files are not supported to be restored.
  3. some xattrs may be lost, it depends on whether dump_node() enables
 dumping such xattrs.
  4. not support restoring files on Android devices (the same reason as
 #1).

In order to address the above limitations, the LOST_FOUND feature is
introduced. This is an ext4-style lost+found. It tries to restore
unreachable files into /lost+found directory inside f2fs.

If LOST_FOUND feature is switched on when mkfs, /lost+found directory is
created by mkfs. It can also be created by mkdir manually. It should be
located right under root directory.

If fsck detects unreachable nids, it scans all these nids, and skips non-
inode or directory inode nodes. For the left nids, they are all file inodes.
Fsck then checks these inodes and update corresponding counters and bitmaps.

From now on, the filesystem is in a "consistent" state, fsck can allocate
blocks safely and start reconnecting files to lost+found. The reconnection
adds new dentry in lost+found and update metadata (i_name, i_pino) of file
inode. If reconnection fails, fsck will clear the counters and bitmaps.
Files reconnected to lost+found will be renamed after its ino number.

However, because of lost+found directory, f2fs should avoid to encrypting
root directory. So f2fs should also check if LOST_FOUND feature is enabled
or not.

I create testcases which inject faults to generate unreachable nids. To
enable LOST_FOUND, we should give "-O lost_found" to mkfs.

# mkfs.f2fs -O lost_found -O encrypt test.img
# tree /data/
/data/
├── dir
│   ├── foo
│   └── subdir
│   └── bar
├── encrypt-dir
│   ├── encrypt-foo
│   └── encrypt-subdir
│   └── encrypt-bar
└── lost+found

5 directories, 4 files

Testcases:
1) corrupt nat_entry->blk_addr of dir [PASS]
2) corrupt nat_entry->blk_addr of encrypt-dir [PASS]
3) remove lost+found, then corrupt nat_entry->blk_addr of dir [PASS]

Any comments and tests are appreciated.

Thanks,
Sheng


Sheng Yong (7):
  fsck.f2fs: fix typo
  mkfs.f2fs: introduce mkfs parameters in f2fs_configuration
  f2fs-tools: init f2fs_configuration as 0
  fsck.f2fs: integrate sanity_check_inode to __check_inode_mode
  mkfs.f2fs: create lost+found directory
  fsck.f2fs: read nat block if nat entry is invalid
  fsck.f2fs: reconnect unreachable files to lost+found

 fsck/dir.c  |  19 ++-
 fsck/fsck.c | 421 +---
 fsck/fsck.h |   3 +
 fsck/main.c |   2 +-
 fsck/mount.c|   9 +-
 include/f2fs_fs.h   |  11 ++
 lib/libf2fs.c   |  18 +--
 mkfs/f2fs_format.c  | 291 +++--
 mkfs/f2fs_format_main.c |   2 +
 9 files changed, 686 insertions(+), 90 deletions(-)

-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2 1/7] fsck.f2fs: fix typo

2018-02-22 Thread Sheng Yong
Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fsck/main.c b/fsck/main.c
index 804f71a..bbf82c3 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -137,7 +137,7 @@ static void error_out(char *prog)
else if (!strcmp("sload.f2fs", prog))
sload_usage();
else
-   MSG(0, "\nWrong progam.\n");
+   MSG(0, "\nWrong program.\n");
 }
 
 void f2fs_parse_options(int argc, char *argv[])
-- 
2.14.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 0/2] f2fs: introduce lost+found feature

2018-02-10 Thread Sheng Yong

Hi, Jaegeuk

On 2018/2/10 10:50, Jaegeuk Kim wrote:

On 02/06, Sheng Yong wrote:

This patchset introduces lost+found feature in f2fs. If the feature is
enabled, f2fs should avoid to encrypting root directory.


In that case, we need to add test_dummy_encryption likewise ext4.


If the test_dummy_encryption is only used for some a testcase, I think
it's ok not to add it. The lost_found feature is not enabled by default,
so if we don't specify "-O lost_found" for mkfs, root directory is allowed
to be encrypted. If I miss something, please let me know :)

thanks,
Sheng



For more information, please check the mail "f2fs-tools: introduce lost+
found feature".

Thanks,
Sheng

Sheng Yong (2):
   f2fs: clean up f2fs_sb_has_xxx functions
   f2fs: introduce lost+found feature

  fs/f2fs/data.c|  2 +-
  fs/f2fs/f2fs.h| 53 +++--
  fs/f2fs/file.c|  6 +++---
  fs/f2fs/segment.c |  4 ++--
  fs/f2fs/super.c   | 26 +++---
  fs/f2fs/sysfs.c   |  4 ++--
  6 files changed, 42 insertions(+), 53 deletions(-)

--
2.11.0


.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 2/2] f2fs: introduce lost+found feature

2018-02-08 Thread Sheng Yong

Hi, Chao

On 2018/2/8 21:29, Chao Yu wrote:

On 2018/2/6 12:31, Sheng Yong wrote:

Introduce lost+found feature. The lost+found is a directory which saves


Nitpick, lost_found feature...

Needs to add /sys/fs/f2fs/features/lost_found sysfs entry, and show
'lost_found' in /sys/fs/f2fs//features.


I will add this sysfs entry in the next version :)

Thanks,
Sheng


Thanks,


unreachable files. If f2fsck finds a file which has no parent, or the
parent is removed by f2fsck, the file will be placed in lost+found
directory.

According fscrypt policy, lost+found could not be encrypted. As a
result, the root directory cannot be encrypted. So if lost+found
feature is enabled, let's avoid to encrypt root directory.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
  fs/f2fs/f2fs.h  |  2 ++
  fs/f2fs/super.c | 12 
  2 files changed, 14 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index a60d56a96f9b..d9c9be6ea5d5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -125,6 +125,7 @@ struct f2fs_mount_info {
  #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR0x0040
  #define F2FS_FEATURE_QUOTA_INO0x0080
  #define F2FS_FEATURE_INODE_CRTIME 0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
  
  #define F2FS_HAS_FEATURE(sb, mask)	\

((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -3186,6 +3187,7 @@ F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
  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);
  
  #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 b39ab55ab1b5..5f536e878d21 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1797,6 +1797,18 @@ static int f2fs_get_context(struct inode *inode, void 
*ctx, size_t len)
  static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
  {
+   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+   /*
+* Encrypting the root directory is not allowed because f2fsck
+* expects lost+found directory to exist and remain unencrypted
+* if LOST_FOUND feature is enabled.
+*
+*/
+   if (f2fs_sb_has_lost_found(sbi->sb) &&
+   inode->i_ino == F2FS_ROOT_INO(sbi))
+   return -EPERM;
+
return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len, fs_data, XATTR_CREATE);



.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 4/5] mkfs.f2fs: create lost+found directory

2018-02-08 Thread Sheng Yong

Hi, Chao

On 2018/2/8 23:08, Chao Yu wrote:

On 2018/2/6 12:31, Sheng Yong wrote:

This patch introduces a new feature F2FS_FEATURE_LOST_FOUND. It can be
switched on by indicating a new option `lost+found' with -O. If


Not sure, do we need to change this option to 'lost_found' to follow other
generic -O options?


I'm also not sure about this, since there is already a `lost_found' in fsck :(




F2FS_FEATUER_LOST_FOUND is enabled, an empty directory lost+found is
created during mkfs.

This is a preparation for fsck. During fsck, the directory is used to
save unreachable files, which have no parent directory or their parent
directory is removed by fsck. Encrypted files are also allowed to be
saved here.


[...]

+static int f2fs_write_lpf_inode(void)
+{
+   struct f2fs_node *raw_node;
+   u_int64_t blk_size_bytes, data_blk_nor;
+   u_int64_t main_area_node_seg_blk_offset;
+   int err = 0;
+
+   ASSERT(c.lpf_ino);
+
+   raw_node = calloc(F2FS_BLKSIZE, 1);
+   if (raw_node == NULL) {
+   MSG(1, "\tError: Calloc Failed for raw_node!!!\n");
+   return -1;
+   }
+
+   raw_node->footer.nid = cpu_to_le32(c.lpf_ino);
+   raw_node->footer.ino = raw_node->footer.nid;
+   raw_node->footer.cp_ver = cpu_to_le64(1);
+   raw_node->footer.next_blkaddr = cpu_to_le32(
+   get_sb(main_blkaddr) +
+   c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg +
+   1 + c.quota_inum + 1);
+
+   raw_node->i.i_mode = cpu_to_le16(0x41c0); /* 0700 */
+   raw_node->i.i_links = cpu_to_le32(2);
+   raw_node->i.i_uid = cpu_to_le32(getuid());
+   raw_node->i.i_gid = cpu_to_le32(getgid());
+
+   blk_size_bytes = 1 << get_sb(log_blocksize);
+   raw_node->i.i_size = cpu_to_le64(1 * blk_size_bytes); /* dentry */
+   raw_node->i.i_blocks = cpu_to_le64(2);
+
+   raw_node->i.i_atime = cpu_to_le32(time(NULL));
+   raw_node->i.i_atime_nsec = 0;
+   raw_node->i.i_ctime = cpu_to_le32(time(NULL));
+   raw_node->i.i_ctime_nsec = 0;
+   raw_node->i.i_mtime = cpu_to_le32(time(NULL));
+   raw_node->i.i_mtime_nsec = 0;
+   raw_node->i.i_generation = 0;
+   raw_node->i.i_xattr_nid = 0;
+   raw_node->i.i_flags = 0;
+   raw_node->i.i_pino = le32_to_cpu(sb->root_ino);
+   raw_node->i.i_namelen = le32_to_cpu(strlen(LPF));
+   memcpy(raw_node->i.i_name, LPF, strlen(LPF));
+   raw_node->i.i_current_depth = cpu_to_le32(1);
+   raw_node->i.i_dir_level = DEF_DIR_LEVEL;
+
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
+   raw_node->i.i_inline = F2FS_EXTRA_ATTR;
+   raw_node->i.i_extra_isize =
+   cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
+   }
+
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA))
+   raw_node->i.i_projid = cpu_to_le32(F2FS_DEF_PROJID);


Need to handle inode_crtime case?


Right, thanks.



+
+   data_blk_nor = f2fs_add_default_dentry_lpf();
+   if (data_blk_nor < 0) {
+   MSG(1, "\tError: Failed to add default dentries for 
lost+found!!!\n");
+   err = -1;
+   goto exit;
+   }
+   raw_node->i.i_addr[get_extra_isize(raw_node)] = 
cpu_to_le32(data_blk_nor);
+
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+   raw_node->i.i_inode_checksum =
+   cpu_to_le32(f2fs_inode_chksum(raw_node));
+
+   main_area_node_seg_blk_offset = get_sb(main_blkaddr);
+   main_area_node_seg_blk_offset += c.cur_seg[CURSEG_HOT_NODE] *
+   c.blks_per_seg + c.quota_inum + 1;
+
+   DBG(1, "\tWriting lost+found inode (hot node), %x %x %x at offset 
0x%08"PRIu64"\n",
+   get_sb(main_blkaddr),
+   c.cur_seg[CURSEG_HOT_NODE],
+   c.blks_per_seg, main_area_node_seg_blk_offset);
+   if (dev_write_block(raw_node, main_area_node_seg_blk_offset)) {
+   MSG(1, "\tError: While writing the raw_node to disk!!!\n");
+   err = -1;
+   goto exit;
+   }
+
+   c.lpf_inum++;
+exit:
+   free(raw_node);
+   return err;
+}
+
  static int f2fs_add_default_dentry_root(void)
  {
struct f2fs_dentry_block *dent_blk = NULL;
@@ -1326,6 +1495,27 @@ static int f2fs_add_default_dentry_root(void)
test_and_set_bit_le(0, dent_blk->dentry_bitmap);
test_and_set_bit_le(1, dent_blk->dentry_bitmap);
  
+	if (c.lpf_ino) {

+   int len = strlen(LPF);
+   f2fs_hash_t hash = f2fs_dentry_hash((unsigned char *)LPF, len);
+
+   dent_blk->dentry[2].hash_code = cpu_to_le32(hash);
+   dent_blk->dentry[2].ino = cpu_to_le32(c.lpf_ino);
+   

Re: [f2fs-dev] [RFC PATCH 1/5] mkfs.f2fs: introduce mkfs parameters in f2fs_configuration

2018-02-08 Thread Sheng Yong

Hi, Chao

Add Hyojun.

On 2018/2/8 21:30, Chao Yu wrote:

On 2018/2/6 12:31, Sheng Yong wrote:

/* only root inode was written before truncating dnodes */
last_inode_pos = start_inode_pos +
-   c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg + quota_inum;
+   c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg + c.quota_inum;


- f2fs_create_root_dir
  - f2fs_write_root_inode
   - discard_obsolete_dnode
 access c.quota_inum
  - f2fs_write_qf_inode
update c.quota_inum

Should c.quota_inum be initialized more early?


I think we should only count quota inodes if thye are already initialized.
Otherwise, if quota_ino is not enabled, there is only one inode (root) in
CURSEG_HOT_NODE, and two blocks next to root inode will not be discarded.

I'm a bit confused about the `offset' scale in discard_obsolete_dnode.
It seems `if (offset >= start_inode_pos || offset <= last_inode_pos)'
will always be true?

Hi, Hyojun, could you please also have a look at this, thanks :)

diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 0fc8b30..6c9ae22 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -963,7 +963,7 @@ static int discard_obsolete_dnode(struct f2fs_node 
*raw_node, u_int64_t offset)
}
offset = next_blkaddr;
/* should avoid recursive chain due to stale data */
-   if (offset >= start_inode_pos || offset <= last_inode_pos)
+   if (offset <= last_inode_pos)
break;
} while (1);

thanks,
Sheng


Thanks,

.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 5/5] fsck.f2fs: reconnect unreachable files to lost+found

2018-02-07 Thread Sheng Yong



On 2018/2/7 18:01, Sheng Yong wrote:



[...]

+
+/* lookup lost+found in root directory */
+lpf_ino = f2fs_lookup(sbi, node, (u8 *) LPF, strlen(LPF));


The 4th parameter should be namelen but not strlen(LPF).

Sorry for the noise. The comment here is wrong :(



[...]

+
+static int fsck_do_reconnect_file(struct f2fs_sb_info *sbi,
+  struct f2fs_node *lpf,
+  struct f2fs_node *fnode)
+{
+char name[80];
+size_t namelen;
+nid_t ino = le32_to_cpu(fnode->footer.ino);
+struct node_info ni;
+int ret;
+
+namelen = snprintf(name, 80, "%u", ino);
+if (namelen >= 80)
+/* ignore terminating '\0', should never happen */
+namelen = 79;
+
+if (f2fs_lookup(sbi, lpf, (u8 *) name, strlen(LPF))) {


The 4th parameter should be namelen but not strlen(LPF).


+ASSERT_MSG("Name %s already exist in lost+found", name);
+return -EEXIST;
+}
+

[...]





--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 5/5] fsck.f2fs: reconnect unreachable files to lost+found

2018-02-07 Thread Sheng Yong


On 2018/2/6 12:31, Sheng Yong wrote:

This patch introduces lost+found feature to fsck. If a file is found
unreachable by fsck. Fsck tries to reconnect the file to lost+found
directory:
   1. Scan all unreachable file inodes, ignore non-inodes ones and
  directories.
   2. Check them and fix incorrupted data to make sure filesystem
  metadata (mainly counters and main/nat bitmap) are all consistent.
   3. Reconnect these files to lost+found. If lost+found does not exist,
  create it first. During reconnecting, expand lost+found's dentry
  block automatically. Reconnected files are renamed after its ino
  number.
   4. If reconnect fails drop the node and restore filesystem metadata.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
  fsck/dir.c   |  19 ++-
  fsck/fsck.c  | 376 ++-
  fsck/fsck.h  |   3 +
  fsck/mount.c |   2 +
  4 files changed, 397 insertions(+), 3 deletions(-)

diff --git a/fsck/dir.c b/fsck/dir.c
index b2ea18f..567a4e9 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -176,6 +176,23 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,
return 0;
  }
  
+/* return ino if file exists, otherwise return 0 */

+nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
+   u8 *name, int len)
+{
+   int err;
+   struct dentry de = {
+   .name = name,
+   .len = len,
+   };
+
+   err = f2fs_find_entry(sbi, dir, );
+   if (err == 1)
+   return de.ino;
+   else
+   return 0;
+}
+
  static void f2fs_update_dentry(nid_t ino, int file_type,
struct f2fs_dentry_ptr *d,
const unsigned char *name, int len, f2fs_hash_t name_hash,
@@ -199,7 +216,7 @@ static void f2fs_update_dentry(nid_t ino, int file_type,
  /*
   * f2fs_add_link - Add a new file(dir) to parent dir.
   */
-static int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
+int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
const unsigned char *name, int name_len, nid_t ino,
int file_type, block_t p_blkaddr, int inc_link)
  {
diff --git a/fsck/fsck.c b/fsck/fsck.c
index fcaab14..81e1145 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
   */
  #include "fsck.h"
  #include "quotaio.h"
+#include 
  
  char *tree_mark;

  uint32_t tree_mark_size = 256;
@@ -43,6 +44,14 @@ static inline int f2fs_test_main_bitmap(struct f2fs_sb_info 
*sbi, u32 blk)
fsck->main_area_bitmap);
  }
  
+static inline int f2fs_clear_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)

+{
+   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+   return f2fs_clear_bit(BLKOFF_FROM_MAIN(sbi, blk),
+   fsck->main_area_bitmap);
+}
+
  static inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk)
  {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -448,9 +457,11 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
  
  	/* workaround to fix later */

if (ftype != F2FS_FT_ORPHAN ||
-   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {
f2fs_clear_bit(nid, fsck->nat_area_bitmap);
-   else
+   /* avoid reusing nid when reconnecting files */
+   f2fs_set_bit(nid, NM_I(sbi)->nid_bitmap);
+   } else
ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
nid);
  
@@ -2041,6 +2052,362 @@ int check_sit_types(struct f2fs_sb_info *sbi)

return err;
  }
  
+static struct f2fs_node *fsck_get_lpf(struct f2fs_sb_info *sbi)

+{
+   struct f2fs_node *node;
+   struct node_info ni;
+   nid_t lpf_ino;
+   int err;
+
+   /* read root inode first */
+   node = calloc(F2FS_BLKSIZE, 1);
+   ASSERT(node);
+   get_node_info(sbi, F2FS_ROOT_INO(sbi), );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+
+   /* lookup lost+found in root directory */
+   lpf_ino = f2fs_lookup(sbi, node, (u8 *) LPF, strlen(LPF));


The 4th parameter should be namelen but not strlen(LPF).


+   if (lpf_ino) { /* found */
+   get_node_info(sbi, lpf_ino, );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+   DBG(1, "Found lost+found 0x%x at blkaddr [0x%x]\n",
+   lpf_ino, ni.blk_addr);
+   if (!S_ISDIR(le16_to_cpu(node->i.i_mode))) {
+   ASSERT_MSG("lost+found is not directory [0%o]\n",
+  le16_to_cpu(node->i.i_mode));
+   /* FIXME: give up? */
+   goto out

[f2fs-dev] [RFC PATCH 0/2] f2fs: introduce lost+found feature

2018-02-05 Thread Sheng Yong
This patchset introduces lost+found feature in f2fs. If the feature is
enabled, f2fs should avoid to encrypting root directory.

For more information, please check the mail "f2fs-tools: introduce lost+
found feature".

Thanks,
Sheng

Sheng Yong (2):
  f2fs: clean up f2fs_sb_has_xxx functions
  f2fs: introduce lost+found feature

 fs/f2fs/data.c|  2 +-
 fs/f2fs/f2fs.h| 53 +++--
 fs/f2fs/file.c|  6 +++---
 fs/f2fs/segment.c |  4 ++--
 fs/f2fs/super.c   | 26 +++---
 fs/f2fs/sysfs.c   |  4 ++--
 6 files changed, 42 insertions(+), 53 deletions(-)

-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 1/2] f2fs: clean up f2fs_sb_has_xxx functions

2018-02-05 Thread Sheng Yong
This patch introduces F2FS_FEATURE_FUNCS to clean up the definitions of
different f2fs_sb_has_xxx functions.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/data.c|  2 +-
 fs/f2fs/f2fs.h| 51 +--
 fs/f2fs/file.c|  6 +++---
 fs/f2fs/segment.c |  4 ++--
 fs/f2fs/super.c   | 14 +++---
 fs/f2fs/sysfs.c   |  4 ++--
 6 files changed, 28 insertions(+), 53 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6cba74eb09a7..4eec9ad9493d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -196,7 +196,7 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
if (!is_read_io(bio_op(bio))) {
unsigned int start;
 
-   if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
+   if (f2fs_sb_has_blkzoned(sbi->sb) &&
current->plug && (type == DATA || type == NODE))
blk_finish_plug(current->plug);
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 6300ac5bcbe4..a60d56a96f9b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3172,45 +3172,20 @@ static inline bool f2fs_bio_encrypted(struct bio *bio)
return bio->bi_private != NULL;
 }
 
-static inline int f2fs_sb_has_crypto(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
-}
-
-static inline int f2fs_sb_mounted_blkzoned(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_BLKZONED);
+#define F2FS_FEATURE_FUNCS(name, flagname) \
+static inline int f2fs_sb_has_##name(struct super_block *sb) \
+{ \
+   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_##flagname); \
 }
 
-static inline int f2fs_sb_has_extra_attr(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_EXTRA_ATTR);
-}
-
-static inline int f2fs_sb_has_project_quota(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_PRJQUOTA);
-}
-
-static inline int f2fs_sb_has_inode_chksum(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CHKSUM);
-}
-
-static inline int f2fs_sb_has_flexible_inline_xattr(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR);
-}
-
-static inline int f2fs_sb_has_quota_ino(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_QUOTA_INO);
-}
-
-static inline int f2fs_sb_has_inode_crtime(struct super_block *sb)
-{
-   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CRTIME);
-}
+F2FS_FEATURE_FUNCS(encrypt, ENCRYPT);
+F2FS_FEATURE_FUNCS(blkzoned, BLKZONED);
+F2FS_FEATURE_FUNCS(extra_attr, EXTRA_ATTR);
+F2FS_FEATURE_FUNCS(project_quota, PRJQUOTA);
+F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
+F2FS_FEATURE_FUNCS(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
+F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
+F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
 
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline int get_blkz_type(struct f2fs_sb_info *sbi,
@@ -3230,7 +3205,7 @@ static inline bool f2fs_discard_en(struct f2fs_sb_info 
*sbi)
 {
struct request_queue *q = bdev_get_queue(sbi->sb->s_bdev);
 
-   return blk_queue_discard(q) || f2fs_sb_mounted_blkzoned(sbi->sb);
+   return blk_queue_discard(q) || f2fs_sb_has_blkzoned(sbi->sb);
 }
 
 static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 672a542e5464..29956e16c58c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1938,7 +1938,7 @@ static int f2fs_ioc_set_encryption_policy(struct file 
*filp, unsigned long arg)
 {
struct inode *inode = file_inode(filp);
 
-   if (!f2fs_sb_has_crypto(inode->i_sb))
+   if (!f2fs_sb_has_encrypt(inode->i_sb))
return -EOPNOTSUPP;
 
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
@@ -1948,7 +1948,7 @@ static int f2fs_ioc_set_encryption_policy(struct file 
*filp, unsigned long arg)
 
 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
 {
-   if (!f2fs_sb_has_crypto(file_inode(filp)->i_sb))
+   if (!f2fs_sb_has_encrypt(file_inode(filp)->i_sb))
return -EOPNOTSUPP;
return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
 }
@@ -1959,7 +1959,7 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file 
*filp, unsigned long arg)
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
int err;
 
-   if (!f2fs_sb_has_crypto(inode->i_sb))
+   if (!f2fs_sb_has_encrypt(inode->i_sb))
return -EOPNOTSUPP;
 
if (uuid_is_nonzero(sbi->raw_super->encrypt_pw_salt))
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b16a8e6625aa..860d0cfd624a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1485,7 +1485,7 @@ static int __issue_discard_async(struct f2fs_sb_info *sbi,
struct block_device *bdev, block_t blkstart, block_t blk

[f2fs-dev] [RFC PATCH 4/5] mkfs.f2fs: create lost+found directory

2018-02-05 Thread Sheng Yong
This patch introduces a new feature F2FS_FEATURE_LOST_FOUND. It can be
switched on by indicating a new option `lost+found' with -O. If
F2FS_FEATUER_LOST_FOUND is enabled, an empty directory lost+found is
created during mkfs.

This is a preparation for fsck. During fsck, the directory is used to
save unreachable files, which have no parent directory or their parent
directory is removed by fsck. Encrypted files are also allowed to be
saved here.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/mount.c|   3 +
 include/f2fs_fs.h   |   6 ++
 mkfs/f2fs_format.c  | 223 +---
 mkfs/f2fs_format_main.c |   2 +
 4 files changed, 222 insertions(+), 12 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 46cb571..df53c48 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -460,6 +460,9 @@ void print_sb_state(struct f2fs_super_block *sb)
if (f & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
MSG(0, "%s", " inode_crtime");
}
+   if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) {
+   MSG(0, "%s", " lost+found");
+   }
MSG(0, "\n");
MSG(0, "Info: superblock encrypt level = %d, salt = ",
sb->encryption_level);
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index ca4522d..093c402 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -291,6 +291,8 @@ static inline uint64_t bswap_64(uint64_t val)
 
 #define VERSION_LEN256
 
+#define LPF "lost+found"
+
 enum f2fs_config_func {
MKFS,
FSCK,
@@ -369,6 +371,9 @@ struct f2fs_configuration {
u_int32_t next_free_nid;
u_int32_t quota_inum;
u_int32_t quota_dnum;
+   u_int32_t lpf_inum;
+   u_int32_t lpf_dnum;
+   u_int32_t lpf_ino;
 
/* defragmentation parameters */
int defrag_shrink;
@@ -557,6 +562,7 @@ enum {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define MAX_VOLUME_NAME512
 
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index bda3c9d..33dd98c 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -426,6 +426,9 @@ static int f2fs_prepare_super_block(void)
qtype, c.next_free_nid - 1);
}
 
+   if (c.feature & cpu_to_le32(F2FS_FEATURE_LOST_FOUND))
+   c.lpf_ino = c.next_free_nid++;
+
if (total_zones <= 6) {
MSG(1, "\tError: %d zones: Need more zones "
"by shrinking zone size\n", total_zones);
@@ -608,9 +611,10 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_segno[i], 0x);
}
 
-   set_cp(cur_node_blkoff[0], 1 + c.quota_inum);
-   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum);
-   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum);
+   set_cp(cur_node_blkoff[0], 1 + c.quota_inum + c.lpf_inum);
+   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum + c.lpf_dnum);
+   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum +
+   c.lpf_inum + c.lpf_dnum);
set_cp(rsvd_segment_count, c.reserved_segments);
set_cp(overprov_segment_count, (get_sb(segment_count_main) -
get_cp(rsvd_segment_count)) *
@@ -642,8 +646,8 @@ static int f2fs_write_check_point_pack(void)
 
set_cp(ckpt_flags, flags);
set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload));
-   set_cp(valid_node_count, 1 + c.quota_inum);
-   set_cp(valid_inode_count, 1 + c.quota_inum);
+   set_cp(valid_node_count, 1 + c.quota_inum + c.lpf_inum);
+   set_cp(valid_inode_count, 1 + c.quota_inum + c.lpf_inum);
set_cp(next_free_nid, c.next_free_nid);
set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) <<
get_sb(log_blocks_per_seg)) / 8);
@@ -702,7 +706,7 @@ static int f2fs_write_check_point_pack(void)
SET_SUM_TYPE((>footer), SUM_TYPE_DATA);
 
journal = >journal;
-   journal->n_nats = cpu_to_le16(1 + c.quota_inum);
+   journal->n_nats = cpu_to_le16(1 + c.quota_inum + c.lpf_inum);
journal->nat_j.entries[0].nid = sb->root_ino;
journal->nat_j.entries[0].ne.version = 0;
journal->nat_j.entries[0].ne.ino = sb->root_ino;
@@ -723,6 +727,16 @@ static int f2fs_write_check_point_pack(void)
i++;
}
 
+   if (c.lpf_inum) {
+   journal->nat_j.entries[i].nid = cpu_to_le32(c.lpf_ino);
+   journal->nat_j.entries[i].ne.version = 0;
+   journal->nat_j.entries[i].ne.ino = cpu_to_le32(c.lpf_ino);
+   journal-&

[f2fs-dev] [RFC PATCH 2/5] f2fs-tools: init f2fs_configuration as 0

2018-02-05 Thread Sheng Yong
Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 lib/libf2fs.c | 18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index e8b1842..0c684d5 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -586,24 +586,17 @@ void f2fs_init_configuration(void)
 {
int i;
 
+   memset(, 0, sizeof(struct f2fs_configuration));
c.ndevs = 1;
-   c.total_sectors = 0;
-   c.sector_size = 0;
c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
c.rootdev_name = get_rootdev();
c.wanted_total_sectors = -1;
-   c.zoned_mode = 0;
-   c.zoned_model = 0;
-   c.zone_blocks = 0;
-#ifdef WITH_ANDROID
-   c.preserve_limits = 0;
-#else
+#ifndef WITH_ANDROID
c.preserve_limits = 1;
 #endif
 
for (i = 0; i < MAX_DEVICES; i++) {
-   memset([i], 0, sizeof(struct device_info));
c.devices[i].fd = -1;
c.devices[i].sector_size = DEFAULT_SECTOR_SIZE;
c.devices[i].end_blkaddr = -1;
@@ -611,19 +604,12 @@ void f2fs_init_configuration(void)
}
 
/* calculated by overprovision ratio */
-   c.reserved_segments = 0;
-   c.overprovision = 0;
c.segs_per_sec = 1;
c.secs_per_zone = 1;
c.segs_per_zone = 1;
-   c.heap = 0;
c.vol_label = "";
c.trim = 1;
-   c.trimmed = 0;
-   c.ro = 0;
c.kd = -1;
-   c.dry_run = 0;
-   c.large_nat_bitmap = 0;
c.fixed_time = -1;
 }
 
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 5/5] fsck.f2fs: reconnect unreachable files to lost+found

2018-02-05 Thread Sheng Yong
This patch introduces lost+found feature to fsck. If a file is found
unreachable by fsck. Fsck tries to reconnect the file to lost+found
directory:
  1. Scan all unreachable file inodes, ignore non-inodes ones and
 directories.
  2. Check them and fix incorrupted data to make sure filesystem
 metadata (mainly counters and main/nat bitmap) are all consistent.
  3. Reconnect these files to lost+found. If lost+found does not exist,
 create it first. During reconnecting, expand lost+found's dentry
 block automatically. Reconnected files are renamed after its ino
 number.
  4. If reconnect fails drop the node and restore filesystem metadata.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/dir.c   |  19 ++-
 fsck/fsck.c  | 376 ++-
 fsck/fsck.h  |   3 +
 fsck/mount.c |   2 +
 4 files changed, 397 insertions(+), 3 deletions(-)

diff --git a/fsck/dir.c b/fsck/dir.c
index b2ea18f..567a4e9 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -176,6 +176,23 @@ static int f2fs_find_entry(struct f2fs_sb_info *sbi,
return 0;
 }
 
+/* return ino if file exists, otherwise return 0 */
+nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
+   u8 *name, int len)
+{
+   int err;
+   struct dentry de = {
+   .name = name,
+   .len = len,
+   };
+
+   err = f2fs_find_entry(sbi, dir, );
+   if (err == 1)
+   return de.ino;
+   else
+   return 0;
+}
+
 static void f2fs_update_dentry(nid_t ino, int file_type,
struct f2fs_dentry_ptr *d,
const unsigned char *name, int len, f2fs_hash_t name_hash,
@@ -199,7 +216,7 @@ static void f2fs_update_dentry(nid_t ino, int file_type,
 /*
  * f2fs_add_link - Add a new file(dir) to parent dir.
  */
-static int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
+int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
const unsigned char *name, int name_len, nid_t ino,
int file_type, block_t p_blkaddr, int inc_link)
 {
diff --git a/fsck/fsck.c b/fsck/fsck.c
index fcaab14..81e1145 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -10,6 +10,7 @@
  */
 #include "fsck.h"
 #include "quotaio.h"
+#include 
 
 char *tree_mark;
 uint32_t tree_mark_size = 256;
@@ -43,6 +44,14 @@ static inline int f2fs_test_main_bitmap(struct f2fs_sb_info 
*sbi, u32 blk)
fsck->main_area_bitmap);
 }
 
+static inline int f2fs_clear_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+   return f2fs_clear_bit(BLKOFF_FROM_MAIN(sbi, blk),
+   fsck->main_area_bitmap);
+}
+
 static inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -448,9 +457,11 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
 
/* workaround to fix later */
if (ftype != F2FS_FT_ORPHAN ||
-   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+   f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) {
f2fs_clear_bit(nid, fsck->nat_area_bitmap);
-   else
+   /* avoid reusing nid when reconnecting files */
+   f2fs_set_bit(nid, NM_I(sbi)->nid_bitmap);
+   } else
ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
nid);
 
@@ -2041,6 +2052,362 @@ int check_sit_types(struct f2fs_sb_info *sbi)
return err;
 }
 
+static struct f2fs_node *fsck_get_lpf(struct f2fs_sb_info *sbi)
+{
+   struct f2fs_node *node;
+   struct node_info ni;
+   nid_t lpf_ino;
+   int err;
+
+   /* read root inode first */
+   node = calloc(F2FS_BLKSIZE, 1);
+   ASSERT(node);
+   get_node_info(sbi, F2FS_ROOT_INO(sbi), );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+
+   /* lookup lost+found in root directory */
+   lpf_ino = f2fs_lookup(sbi, node, (u8 *) LPF, strlen(LPF));
+   if (lpf_ino) { /* found */
+   get_node_info(sbi, lpf_ino, );
+   err = dev_read_block(node, ni.blk_addr);
+   ASSERT(err >= 0);
+   DBG(1, "Found lost+found 0x%x at blkaddr [0x%x]\n",
+   lpf_ino, ni.blk_addr);
+   if (!S_ISDIR(le16_to_cpu(node->i.i_mode))) {
+   ASSERT_MSG("lost+found is not directory [0%o]\n",
+  le16_to_cpu(node->i.i_mode));
+   /* FIXME: give up? */
+   goto out;
+   }
+   } else { /* not found, create it */
+   struct dentry de;
+
+   memset(, 0, 

[f2fs-dev] [RFC PATCH 2/2] f2fs: introduce lost+found feature

2018-02-05 Thread Sheng Yong
Introduce lost+found feature. The lost+found is a directory which saves
unreachable files. If f2fsck finds a file which has no parent, or the
parent is removed by f2fsck, the file will be placed in lost+found
directory.

According fscrypt policy, lost+found could not be encrypted. As a
result, the root directory cannot be encrypted. So if lost+found
feature is enabled, let's avoid to encrypt root directory.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/f2fs.h  |  2 ++
 fs/f2fs/super.c | 12 
 2 files changed, 14 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index a60d56a96f9b..d9c9be6ea5d5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -125,6 +125,7 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
 #define F2FS_FEATURE_QUOTA_INO 0x0080
 #define F2FS_FEATURE_INODE_CRTIME  0x0100
+#define F2FS_FEATURE_LOST_FOUND0x0200
 
 #define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -3186,6 +3187,7 @@ F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
 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);
 
 #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 b39ab55ab1b5..5f536e878d21 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1797,6 +1797,18 @@ static int f2fs_get_context(struct inode *inode, void 
*ctx, size_t len)
 static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
 {
+   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+   /*
+* Encrypting the root directory is not allowed because f2fsck
+* expects lost+found directory to exist and remain unencrypted
+* if LOST_FOUND feature is enabled.
+*
+*/
+   if (f2fs_sb_has_lost_found(sbi->sb) &&
+   inode->i_ino == F2FS_ROOT_INO(sbi))
+   return -EPERM;
+
return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len, fs_data, XATTR_CREATE);
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 0/5] f2fs-tools: introduce lost+found feature

2018-02-05 Thread Sheng Yong
Commit 390fe587b1 ("fsck.f2fs: support restore lost files into
./lost_found/") restores unreachable files, which have no parent directory
or their parent directories are removed by fsck, to ./lost_found directory.

However, it has several limitations:
  1. ./lost_found dir does not locate inside f2fs, thus it may needs
 another partition to save ./lost_found.
  2. encrypted files are not supported to be restored.
  3. some xattrs may be lost, it depends on whether dump_node() enables
 dumping such xattrs.
  4. not support restoring files on Android devices (the same reason as
 #1).

In order to address the above limitations, the lost+found feature is
introduced. This is an ext4-style lost+found. It tries to restore
unreachable files into /lost+found directory inside f2fs.

If lost+found feature is switched on when mkfs, /lost+found directory is
created by mkfs. It can also be created by mkdir manually. It should be
located right under root directory.

If fsck detects unreachable nids, it scans all these nids, and skips non-
inode or directory inode nodes. For the left nids, they are all file inodes.
Fsck then checks these inodes and update corresponding counters and bitmaps.

From now on, the filesystem is in a "consistent" state, fsck can allocate
blocks safely and start reconnecting files to lost+found. The reconnection
adds new dentry in lost+found and update metadata (i_name, i_pino) of file
inode. If reconnection fails, fsck will clear the counters and bitmaps.
Files reconnected to lost+found will be renamed after its ino number.

However, because of lost+found directory, f2fs should avoid to encrypting
root directory. So f2fs should also check if lost+found feature is enabled
or not.

I create a testcase which injects faults to generate unreachable nids.

$ mkfs.f2fs -O lost+found -O encrypt test.img
$ tree /data
/data
├── dir
│   ├── foo
│   └── subdir
│   └── bar
├── encrypt-dir
│   ├── foo
│   └── subdir
│   └── bar
└── lost+found

Inject nat_entry->blk_addr of dir/encrypt-dir to 0.

$ fsck.f2fs -f test.img
Info: Force to fix corruption
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.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 6.3.0 
20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017"
Info: FSCK version
  from "Linux version 4.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 
6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 
2017"
to "Linux version 4.10.0-42-generic (buildd@lgw01-amd64-012) (gcc version 
6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 
2017"
Info: superblock features = 201 :  encrypt lost+found
Info: superblock encrypt level = 0, salt = 
Info: total FS sectors = 204800 (100 MB)
Info: CKPT version = 2995f9d3
Info: Found valid nat_bits in checkpoint
Info: checkpoint state = 1c5 :  trimmed nat_bits crc compacted_summary unmount
[ASSERT] (sanity_check_nid: 386)  --> nid[0x5] ino is 0
[FIX] (__chk_dentries:1456)  --> Unlink [0x5] - dir len[0x3], type[0x2]
[ASSERT] (sanity_check_nid: 386)  --> nid[0xd] ino is 0
[FIX] (__chk_dentries:1456)  --> Unlink [0xd] - encrypt-dir len[0xb], type[0x2]
[ASSERT] (fsck_chk_inode_blk: 895)  --> ino: 0x3 i_links: 5, real links: 3
[FIX] (fsck_chk_inode_blk: 900)  --> Dir: 0x3 i_links= 0x5 -> 0x3

NID[0x6] is unreachable
NID[0x7] is unreachable
NID[0x8] is unreachable
NID[0x9] is unreachable
NID[0xa] is unreachable
NID[0xb] is unreachable
NID[0xc] is unreachable
NID[0xe] is unreachable
NID[0xf] is unreachable
NID[0x10] is unreachable

[FSCK] Reconnect 4 files to lost+found
[FSCK] Unreachable nat entries[Fail] [0xa]
[FSCK] SIT valid block bitmap checking[Fail]
[FSCK] Hard link checking for regular file[Ok..] [0x0]
[FSCK] valid_block_count matching with CP [Fail] [0xc56]
[FSCK] valid_node_count matcing with CP (de lookup)   [Fail] [0xa]
[FSCK] valid_node_count matcing with CP (nat lookup)  [Fail] [0xc]
[FSCK] valid_inode_count matched with CP  [Fail] [0x6]
[FSCK] free segment_count matched with CP [Ok..] [0x1e]
[FSCK] next block offset is free  [Ok..]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs   [Fail]
[FIX] (nullify_nat_entry:2064)  --> Remove nid [0xb] in NAT
[FIX] (nullify_nat_entry:2064)  --> Remove nid [0xf] in NAT
Info: Write valid nat_bits in checkpoint

Done.

$ tree /data
/data/
└── lost+found
├── 12
├── 14
    ├── 16
└── 6

Any comments and tests are appreciated.

Thanks,
Sheng

Sheng Yong (5):
  mkfs.f2fs: introduce mkfs parameters in f2fs_configuration
  f2fs-tools: init f2fs_configuration wit as 0
  fsck.f2fs: integrate sanity_check_inode to __

[f2fs-dev] [RFC PATCH 1/5] mkfs.f2fs: introduce mkfs parameters in f2fs_configuration

2018-02-05 Thread Sheng Yong
Introduce new parameters in f2fs_configuration for mkfs:
  * next_free_nid: save the next free nid
  * quota_inum: save how many blocks are used for quota inodes
  * quota_dnum: save how many blocks are used for quota data

Use these parameters to avoid duplicated calculation of these values.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 include/f2fs_fs.h  |  5 +
 mkfs/f2fs_format.c | 46 +-
 2 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 548a3e8..ca4522d 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -365,6 +365,11 @@ struct f2fs_configuration {
int large_nat_bitmap;
__le32 feature; /* defined features */
 
+   /* mkfs parameters */
+   u_int32_t next_free_nid;
+   u_int32_t quota_inum;
+   u_int32_t quota_dnum;
+
/* defragmentation parameters */
int defrag_shrink;
u_int64_t defrag_start;
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 4fb429e..bda3c9d 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -159,7 +159,6 @@ static int f2fs_prepare_super_block(void)
u_int32_t sit_bitmap_size, max_sit_bitmap_size;
u_int32_t max_nat_bitmap_size, max_nat_segments;
u_int32_t total_zones;
-   u_int32_t next_ino;
enum quota_type qtype;
int i;
 
@@ -411,7 +410,7 @@ static int f2fs_prepare_super_block(void)
set_sb(node_ino, 1);
set_sb(meta_ino, 2);
set_sb(root_ino, 3);
-   next_ino = 4;
+   c.next_free_nid = 4;
 
if (c.feature & cpu_to_le32(F2FS_FEATURE_QUOTA_INO)) {
quotatype_bits = QUOTA_USR_BIT | QUOTA_GRP_BIT;
@@ -422,9 +421,9 @@ static int f2fs_prepare_super_block(void)
for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++) {
if (!((1 << qtype) & quotatype_bits))
continue;
-   sb->qf_ino[qtype] = cpu_to_le32(next_ino++);
+   sb->qf_ino[qtype] = cpu_to_le32(c.next_free_nid++);
MSG(0, "Info: add quota type = %u => %u\n",
-   qtype, next_ino - 1);
+   qtype, c.next_free_nid - 1);
}
 
if (total_zones <= 6) {
@@ -558,7 +557,6 @@ static int f2fs_write_check_point_pack(void)
char *sum_compact, *sum_compact_p;
struct f2fs_summary *sum_entry;
enum quota_type qtype;
-   u_int32_t quota_inum, quota_dnum;
int off;
int ret = -1;
 
@@ -610,16 +608,9 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_segno[i], 0x);
}
 
-   quota_inum = quota_dnum = 0;
-   for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++)
-   if (sb->qf_ino[qtype]) {
-   quota_inum++;
-   quota_dnum += QUOTA_DATA(qtype);
-   }
-
-   set_cp(cur_node_blkoff[0], 1 + quota_inum);
-   set_cp(cur_data_blkoff[0], 1 + quota_dnum);
-   set_cp(valid_block_count, 2 + quota_inum + quota_dnum);
+   set_cp(cur_node_blkoff[0], 1 + c.quota_inum);
+   set_cp(cur_data_blkoff[0], 1 + c.quota_dnum);
+   set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum);
set_cp(rsvd_segment_count, c.reserved_segments);
set_cp(overprov_segment_count, (get_sb(segment_count_main) -
get_cp(rsvd_segment_count)) *
@@ -651,9 +642,9 @@ static int f2fs_write_check_point_pack(void)
 
set_cp(ckpt_flags, flags);
set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload));
-   set_cp(valid_node_count, 1 + quota_inum);
-   set_cp(valid_inode_count, 1 + quota_inum);
-   set_cp(next_free_nid, get_sb(root_ino) + 1 + quota_inum);
+   set_cp(valid_node_count, 1 + c.quota_inum);
+   set_cp(valid_inode_count, 1 + c.quota_inum);
+   set_cp(next_free_nid, c.next_free_nid);
set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) <<
get_sb(log_blocks_per_seg)) / 8);
 
@@ -711,7 +702,7 @@ static int f2fs_write_check_point_pack(void)
SET_SUM_TYPE((>footer), SUM_TYPE_DATA);
 
journal = >journal;
-   journal->n_nats = cpu_to_le16(1 + quota_inum);
+   journal->n_nats = cpu_to_le16(1 + c.quota_inum);
journal->nat_j.entries[0].nid = sb->root_ino;
journal->nat_j.entries[0].ne.version = 0;
journal->nat_j.entries[0].ne.ino = sb->root_ino;
@@ -741,9 +732,9 @@ static int f2fs_write_check_point_pack(void)
journal->sit_j.entries[0].segno = cp->cur_node_segno[0];
journal->sit_j.entries[0].se.vblocks =
cpu_to_le16((CURSEG_HOT_NODE << 10) |
-   (1 + quota_inum));
+   (1 + c.quota_

[f2fs-dev] [RFC PATCH 3/5] fsck.f2fs: integrate sanity_check_inode to __check_inode_mode

2018-02-05 Thread Sheng Yong
In sanity_check_nid, __check_inode_mode will check i_mode value of an
inode. So integrate sanity_check_inode to __check_inode_mode to clean
up the code.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/fsck.c | 26 +-
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 29823a1..fcaab14 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -334,6 +334,11 @@ static int __check_inode_mode(u32 nid, enum FILE_TYPE 
ftype, u32 mode)
 {
if (ftype >= F2FS_FT_MAX)
return 0;
+   /* f2fs_iget will return -EIO if mode is not valid file type */
+   if (!S_ISLNK(mode) && !S_ISREG(mode) && !S_ISDIR(mode) &&
+   !S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode) &&
+   !S_ISSOCK(mode))
+   goto err;
if (S_ISLNK(mode) && ftype != F2FS_FT_SYMLINK)
goto err;
if (S_ISREG(mode) && ftype != F2FS_FT_REG_FILE)
@@ -465,25 +470,6 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 
nid,
return 0;
 }
 
-static int sanity_check_inode(struct f2fs_sb_info *sbi, struct f2fs_node *node)
-{
-   struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
-   struct f2fs_inode *fi = >i;
-
-   if (!(le16_to_cpu(fi->i_mode) & S_IFMT)) {
-   ASSERT_MSG("i_mode is not valid. [0x%x]", 
le16_to_cpu(fi->i_mode));
-   goto remove_node;
-   }
-
-   return 0;
-
-remove_node:
-   f2fs_set_bit(le32_to_cpu(node->footer.ino), fsck->nat_area_bitmap);
-   fsck->chk.valid_blk_cnt--;
-   fsck->chk.valid_node_cnt--;
-   return -EINVAL;
-}
-
 static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
u32 x_nid, u32 *blk_cnt)
 {
@@ -528,8 +514,6 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
if (ntype == TYPE_INODE) {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 
-   if (sanity_check_inode(sbi, node_blk))
-   goto err;
fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, , 
child);
quota_add_inode_usage(fsck->qctx, nid, _blk->i);
} else {
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] f2fs: fix potential corruption in area before F2FS_SUPER_OFFSET

2018-01-29 Thread Sheng Yong



On 2018/1/29 16:58, Chao Yu wrote:

Hi Sheng Yong,

On 2018/1/29 16:39, Sheng Yong wrote:

Hi, Chao

On 2018/1/29 16:27, Chao Yu wrote:

On 2018/1/29 16:04, Sheng Yong wrote:

sb_getblk does not guarantee the buffer head is uptodate. If bh is not
uptodate, the data (may be used as boot code) in area before


Why boot code can be stored into the position f2fs superblock locates?

According to Ext4_Disk_Layout [1], the first 1024 bytes is used to install
boot sectors (may be used by some legacy bootloader, I'm not quite sure :(


OK, I can understand your concern now, anyway, no matter the area is used
by someone else or not, let's keep data in that area as it is as possible
as we can.


I checked the change again, I think we should also remove the extra
set_buffer_uptodate(bh); in __f2fs_commit_super like the following,

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8173ae688814..07d72d651c45 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1894,7 +1894,6 @@ static int __f2fs_commit_super(struct buffer_head *bh,
lock_buffer(bh);
if (super)
memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super));
-   set_buffer_uptodate(bh);
set_buffer_dirty(bh);
unlock_buffer(bh);

I will resend it, thanks.



Reviewed-by: Chao Yu <yuch...@huawei.com>

Thanks,



And even we have updated the buffer, we will still commit superblock's
datas into that buffer, boot code can be messed up anyway, right?

The first 1024 bytes are all set to 0 by mkfs, while __f2fs_commit_super only
updates bh->b_data from F2FS_SUPER_OFFSET, but not the whole 4KB area. If the
buffer head is not read from super block (4KB), there is a chance it may get
messed up.

Thanks,
Sheng




[1] https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout

Thanks,


F2FS_SUPER_OFFSET may get corrupted when super block is committed.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
   fs/f2fs/super.c | 4 ++--
   1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8173ae688814..7def48cb2b22 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2334,7 +2334,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
}
   
   	/* write back-up superblock first */

-   bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
@@ -2345,7 +2345,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
return err;
   
   	/* write current valid superblock */

-   bh = sb_getblk(sbi->sb, sbi->valid_super_block);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));




.




.




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] f2fs: fix potential corruption in area before F2FS_SUPER_OFFSET

2018-01-29 Thread Sheng Yong

Hi, Chao

On 2018/1/29 16:27, Chao Yu wrote:

On 2018/1/29 16:04, Sheng Yong wrote:

sb_getblk does not guarantee the buffer head is uptodate. If bh is not
uptodate, the data (may be used as boot code) in area before


Why boot code can be stored into the position f2fs superblock locates?

According to Ext4_Disk_Layout [1], the first 1024 bytes is used to install
boot sectors (may be used by some legacy bootloader, I'm not quite sure :(


And even we have updated the buffer, we will still commit superblock's
datas into that buffer, boot code can be messed up anyway, right?

The first 1024 bytes are all set to 0 by mkfs, while __f2fs_commit_super only
updates bh->b_data from F2FS_SUPER_OFFSET, but not the whole 4KB area. If the
buffer head is not read from super block (4KB), there is a chance it may get
messed up.

Thanks,
Sheng




[1] https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout

Thanks,


F2FS_SUPER_OFFSET may get corrupted when super block is committed.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
  fs/f2fs/super.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8173ae688814..7def48cb2b22 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2334,7 +2334,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
}
  
  	/* write back-up superblock first */

-   bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
@@ -2345,7 +2345,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
return err;
  
  	/* write current valid superblock */

-   bh = sb_getblk(sbi->sb, sbi->valid_super_block);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));




.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: fix potential corruption in area before F2FS_SUPER_OFFSET

2018-01-29 Thread Sheng Yong
sb_getblk does not guarantee the buffer head is uptodate. If bh is not
uptodate, the data (may be used as boot code) in area before
F2FS_SUPER_OFFSET may get corrupted when super block is committed.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/super.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8173ae688814..7def48cb2b22 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2334,7 +2334,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
}
 
/* write back-up superblock first */
-   bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
@@ -2345,7 +2345,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool 
recover)
return err;
 
/* write current valid superblock */
-   bh = sb_getblk(sbi->sb, sbi->valid_super_block);
+   bh = sb_bread(sbi->sb, sbi->valid_super_block);
if (!bh)
return -EIO;
err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v2] f2fs: avoid hungtask when GC encrypted block if io_bits is set

2018-01-16 Thread Sheng Yong
When io_bits is set, GCing encrypted block may hit the following hungtask.
Since io_bits requires aligned block address, f2fs_submit_page_write may
return -EAGAIN if new_blkaddr does not satisify io_bits alignment. As a
result, the encrypted page will never be writtenback.

This patch makes move_data_block aware the EAGAIN error and cancel the
writeback.

[  246.751371] INFO: task kworker/u4:4:797 blocked for more than 90 seconds.
[  246.752423]   Not tainted 4.15.0-rc4+ #11
[  246.754176] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
[  246.755336] kworker/u4:4D25448   797  2 0x8000
[  246.755597] Workqueue: writeback wb_workfn (flush-7:0)
[  246.755616] Call Trace:
[  246.755695]  ? __schedule+0x322/0xa90
[  246.755761]  ? blk_init_request_from_bio+0x120/0x120
[  246.755773]  ? pci_mmcfg_check_reserved+0xb0/0xb0
[  246.755801]  ? __radix_tree_create+0x19e/0x200
[  246.755813]  ? delete_node+0x136/0x370
[  246.755838]  schedule+0x43/0xc0
[  246.755904]  io_schedule+0x17/0x40
[  246.755939]  wait_on_page_bit_common+0x17b/0x240
[  246.755950]  ? wake_page_function+0xa0/0xa0
[  246.755961]  ? add_to_page_cache_lru+0x160/0x160
[  246.755972]  ? page_cache_tree_insert+0x170/0x170
[  246.755983]  ? __lru_cache_add+0x96/0xb0
[  246.756086]  __filemap_fdatawait_range+0x14f/0x1c0
[  246.756097]  ? wait_on_page_bit_common+0x240/0x240
[  246.756120]  ? __wake_up_locked_key_bookmark+0x20/0x20
[  246.756167]  ? wait_on_all_pages_writeback+0xc9/0x100
[  246.756179]  ? __remove_ino_entry+0x120/0x120
[  246.756192]  ? wait_woken+0x100/0x100
[  246.756204]  filemap_fdatawait_range+0x9/0x20
[  246.756216]  write_checkpoint+0x18a1/0x1f00
[  246.756254]  ? blk_get_request+0x10/0x10
[  246.756265]  ? cpumask_next_and+0x43/0x60
[  246.756279]  ? f2fs_sync_inode_meta+0x160/0x160
[  246.756289]  ? remove_element.isra.4+0xa0/0xa0
[  246.756300]  ? __put_compound_page+0x40/0x40
[  246.756310]  ? f2fs_sync_fs+0xec/0x1c0
[  246.756320]  ? f2fs_sync_fs+0x120/0x1c0
[  246.756329]  f2fs_sync_fs+0x120/0x1c0
[  246.756357]  ? trace_event_raw_event_f2fs__page+0x260/0x260
[  246.756393]  ? ata_build_rw_tf+0x173/0x410
[  246.756397]  f2fs_balance_fs_bg+0x198/0x390
[  246.756405]  ? drop_inmem_page+0x230/0x230
[  246.756415]  ? ahci_qc_prep+0x1bb/0x2e0
[  246.756418]  ? ahci_qc_issue+0x1df/0x290
[  246.756422]  ? __accumulate_pelt_segments+0x42/0xd0
[  246.756426]  ? f2fs_write_node_pages+0xd1/0x380
[  246.756429]  f2fs_write_node_pages+0xd1/0x380
[  246.756437]  ? sync_node_pages+0x8f0/0x8f0
[  246.756440]  ? update_curr+0x53/0x220
[  246.756444]  ? __accumulate_pelt_segments+0xa2/0xd0
[  246.756448]  ? __update_load_avg_se.isra.39+0x349/0x360
[  246.756452]  ? do_writepages+0x2a/0xa0
[  246.756456]  do_writepages+0x2a/0xa0
[  246.756460]  __writeback_single_inode+0x70/0x490
[  246.756463]  ? check_preempt_wakeup+0x199/0x310
[  246.756467]  writeback_sb_inodes+0x2a2/0x660
[  246.756471]  ? is_empty_dir_inode+0x40/0x40
[  246.756474]  ? __writeback_single_inode+0x490/0x490
[  246.756477]  ? string+0xbf/0xf0
[  246.756480]  ? down_read_trylock+0x35/0x60
[  246.756484]  __writeback_inodes_wb+0x9f/0xf0
[  246.756488]  wb_writeback+0x41d/0x4b0
[  246.756492]  ? writeback_inodes_wb.constprop.55+0x150/0x150
[  246.756498]  ? set_worker_desc+0xf7/0x130
[  246.756502]  ? current_is_workqueue_rescuer+0x60/0x60
[  246.756511]  ? _find_next_bit+0x2c/0xa0
[  246.756514]  ? wb_workfn+0x400/0x5d0
[  246.756518]  wb_workfn+0x400/0x5d0
[  246.756521]  ? finish_task_switch+0xdf/0x2a0
[  246.756525]  ? inode_wait_for_writeback+0x30/0x30
[  246.756529]  process_one_work+0x3a7/0x6f0
[  246.756533]  worker_thread+0x82/0x750
[  246.756537]  kthread+0x16f/0x1c0
[  246.756541]  ? trace_event_raw_event_workqueue_work+0x110/0x110
[  246.756544]  ? kthread_create_worker_on_cpu+0xb0/0xb0
[  246.756548]  ret_from_fork+0x1f/0x30

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v2->v1: do not change the index in meta inode
make move_data_block aware EAGAIN error
---
 fs/f2fs/gc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 33e79697e41c..aa720cc44509 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -691,7 +691,12 @@ static void move_data_block(struct inode *inode, block_t 
bidx,
fio.op = REQ_OP_WRITE;
fio.op_flags = REQ_SYNC;
fio.new_blkaddr = newaddr;
-   f2fs_submit_page_write();
+   err = f2fs_submit_page_write();
+   if (err) {
+   if (PageWriteback(fio.encrypted_page))
+   end_page_writeback(fio.encrypted_page);
+   goto put_page_out;
+   }
 
f2fs_update_iostat(fio.sbi, FS_GC_DATA_IO, F2FS_BLKSIZE);
 
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! ht

[f2fs-dev] [PATCH] f2fs: avoid hungtask when gc encrypted block if io_bits is set

2018-01-10 Thread Sheng Yong
When io_bits is set, gc encrypted block may trigger the following hungtask.
Since io_bits requires aligned block address, f2fs_submit_page_write may
return -EAGAIN if new_blkaddr does not satisify io_bits alignment.

So let's try to alloc new block address to make sure encrypted page could
be writeback.

[  246.751371] INFO: task kworker/u4:4:797 blocked for more than 90 seconds.
[  246.752423]   Not tainted 4.15.0-rc4+ #11
[  246.754176] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
[  246.755336] kworker/u4:4D25448   797  2 0x8000
[  246.755597] Workqueue: writeback wb_workfn (flush-7:0)
[  246.755616] Call Trace:
[  246.755695]  ? __schedule+0x322/0xa90
[  246.755761]  ? blk_init_request_from_bio+0x120/0x120
[  246.755773]  ? pci_mmcfg_check_reserved+0xb0/0xb0
[  246.755801]  ? __radix_tree_create+0x19e/0x200
[  246.755813]  ? delete_node+0x136/0x370
[  246.755838]  schedule+0x43/0xc0
[  246.755904]  io_schedule+0x17/0x40
[  246.755939]  wait_on_page_bit_common+0x17b/0x240
[  246.755950]  ? wake_page_function+0xa0/0xa0
[  246.755961]  ? add_to_page_cache_lru+0x160/0x160
[  246.755972]  ? page_cache_tree_insert+0x170/0x170
[  246.755983]  ? __lru_cache_add+0x96/0xb0
[  246.756086]  __filemap_fdatawait_range+0x14f/0x1c0
[  246.756097]  ? wait_on_page_bit_common+0x240/0x240
[  246.756120]  ? __wake_up_locked_key_bookmark+0x20/0x20
[  246.756167]  ? wait_on_all_pages_writeback+0xc9/0x100
[  246.756179]  ? __remove_ino_entry+0x120/0x120
[  246.756192]  ? wait_woken+0x100/0x100
[  246.756204]  filemap_fdatawait_range+0x9/0x20
[  246.756216]  write_checkpoint+0x18a1/0x1f00
[  246.756254]  ? blk_get_request+0x10/0x10
[  246.756265]  ? cpumask_next_and+0x43/0x60
[  246.756279]  ? f2fs_sync_inode_meta+0x160/0x160
[  246.756289]  ? remove_element.isra.4+0xa0/0xa0
[  246.756300]  ? __put_compound_page+0x40/0x40
[  246.756310]  ? f2fs_sync_fs+0xec/0x1c0
[  246.756320]  ? f2fs_sync_fs+0x120/0x1c0
[  246.756329]  f2fs_sync_fs+0x120/0x1c0
[  246.756357]  ? trace_event_raw_event_f2fs__page+0x260/0x260
[  246.756393]  ? ata_build_rw_tf+0x173/0x410
[  246.756397]  f2fs_balance_fs_bg+0x198/0x390
[  246.756405]  ? drop_inmem_page+0x230/0x230
[  246.756415]  ? ahci_qc_prep+0x1bb/0x2e0
[  246.756418]  ? ahci_qc_issue+0x1df/0x290
[  246.756422]  ? __accumulate_pelt_segments+0x42/0xd0
[  246.756426]  ? f2fs_write_node_pages+0xd1/0x380
[  246.756429]  f2fs_write_node_pages+0xd1/0x380
[  246.756437]  ? sync_node_pages+0x8f0/0x8f0
[  246.756440]  ? update_curr+0x53/0x220
[  246.756444]  ? __accumulate_pelt_segments+0xa2/0xd0
[  246.756448]  ? __update_load_avg_se.isra.39+0x349/0x360
[  246.756452]  ? do_writepages+0x2a/0xa0
[  246.756456]  do_writepages+0x2a/0xa0
[  246.756460]  __writeback_single_inode+0x70/0x490
[  246.756463]  ? check_preempt_wakeup+0x199/0x310
[  246.756467]  writeback_sb_inodes+0x2a2/0x660
[  246.756471]  ? is_empty_dir_inode+0x40/0x40
[  246.756474]  ? __writeback_single_inode+0x490/0x490
[  246.756477]  ? string+0xbf/0xf0
[  246.756480]  ? down_read_trylock+0x35/0x60
[  246.756484]  __writeback_inodes_wb+0x9f/0xf0
[  246.756488]  wb_writeback+0x41d/0x4b0
[  246.756492]  ? writeback_inodes_wb.constprop.55+0x150/0x150
[  246.756498]  ? set_worker_desc+0xf7/0x130
[  246.756502]  ? current_is_workqueue_rescuer+0x60/0x60
[  246.756511]  ? _find_next_bit+0x2c/0xa0
[  246.756514]  ? wb_workfn+0x400/0x5d0
[  246.756518]  wb_workfn+0x400/0x5d0
[  246.756521]  ? finish_task_switch+0xdf/0x2a0
[  246.756525]  ? inode_wait_for_writeback+0x30/0x30
[  246.756529]  process_one_work+0x3a7/0x6f0
[  246.756533]  worker_thread+0x82/0x750
[  246.756537]  kthread+0x16f/0x1c0
[  246.756541]  ? trace_event_raw_event_workqueue_work+0x110/0x110
[  246.756544]  ? kthread_create_worker_on_cpu+0xb0/0xb0
[  246.756548]  ret_from_fork+0x1f/0x30

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/gc.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 33e79697e41c..8a7d6e74ecd5 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -690,8 +690,15 @@ static void move_data_block(struct inode *inode, block_t 
bidx,
 
fio.op = REQ_OP_WRITE;
fio.op_flags = REQ_SYNC;
-   fio.new_blkaddr = newaddr;
-   f2fs_submit_page_write();
+   do {
+   fio.new_blkaddr = newaddr;
+   err = f2fs_submit_page_write();
+   if (err == -EAGAIN) {
+   fio.old_blkaddr = newaddr;
+   allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, 
,
+   , CURSEG_COLD_DATA, NULL, false);
+   }
+   } while (err == -EAGAIN);
 
f2fs_update_iostat(fio.sbi, FS_GC_DATA_IO, F2FS_BLKSIZE);
 
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http:

Re: [f2fs-dev] [RFC PATCH 1/3] f2fs: introduce sysfs readdir_ra to readahead inode block in readdir

2018-01-01 Thread Sheng Yong

Hi, Ju Hyung

On 2017/12/31 4:37, Ju Hyung Park wrote:

May I ask why is this disabled by default?

Since the readahead only improves "readdir + stat" scenario, and it will cause
overhead if we only call a readdir, we don't know how user lookup files. So I
think it's better to provide an option for user to decide if the readahead is
needed.

thanks,
Sheng


On Thu, Nov 23, 2017 at 10:11 PM, Chao Yu <c...@kernel.org> wrote:

On 2017/11/22 18:23, Sheng Yong wrote:

This patch introduces a sysfs interface readdir_ra to enable/disable
readaheading inode block in f2fs_readdir. When readdir_ra is enabled,
it improves the performance of "readdir + stat".

For 300,000 files:
   time find /data/test > /dev/null
disable readdir_ra: 1m25.69s real  0m01.94s user  0m50.80s system
enable  readdir_ra: 0m18.55s real  0m00.44s user  0m15.39s system

Signed-off-by: Sheng Yong <shengyo...@huawei.com>


Reviewed-by: Chao Yu <yuch...@huawei.com>

Thanks,


---
  Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++
  fs/f2fs/dir.c   | 4 
  fs/f2fs/f2fs.h  | 1 +
  fs/f2fs/sysfs.c | 2 ++
  4 files changed, 13 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index a7799c2fca28..d870b5514d15 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -186,3 +186,9 @@ Date: August 2017
  Contact: "Jaegeuk Kim" <jaeg...@kernel.org>
  Description:
Controls sleep time of GC urgent mode
+
+What:/sys/fs/f2fs//readdir_ra
+Date:November 2017
+Contact: "Sheng Yong" <shengyo...@huawei.com>
+Description:
+  Controls readahead inode block in readdir.
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 2d98d877c09d..724304dc6143 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -798,6 +798,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct 
f2fs_dentry_ptr *d,
   unsigned int bit_pos;
   struct f2fs_dir_entry *de = NULL;
   struct fscrypt_str de_name = FSTR_INIT(NULL, 0);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode);

   bit_pos = ((unsigned long)ctx->pos % d->max);

@@ -836,6 +837,9 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct 
f2fs_dentry_ptr *d,
   le32_to_cpu(de->ino), d_type))
   return 1;

+ if (sbi->readdir_ra == 1)
+ ra_node_page(sbi, le32_to_cpu(de->ino));
+
   bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
   ctx->pos = start_pos + bit_pos;
   }
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ca6b0c9bc621..a269d795ba7c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1095,6 +1095,7 @@ struct f2fs_sb_info {
   int dir_level;  /* directory level */
   int inline_xattr_size;  /* inline xattr size */
   unsigned int trigger_ssr_threshold; /* threshold to trigger ssr */
+ int readdir_ra; /* readahead inode in readdir */

   block_t user_block_count;   /* # of user blocks */
   block_t total_valid_block_count;/* # of valid blocks */
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 9835348b6e5d..93c3364250dd 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -299,6 +299,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
  #ifdef CONFIG_F2FS_FAULT_INJECTION
  F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
  F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
@@ -346,6 +347,7 @@ static struct attribute *f2fs_attrs[] = {
   ATTR_LIST(cp_interval),
   ATTR_LIST(idle_interval),
   ATTR_LIST(iostat_enable),
+ ATTR_LIST(readdir_ra),
  #ifdef CONFIG_F2FS_FAULT_INJECTION
   ATTR_LIST(inject_rate),
   ATTR_LIST(inject_type),



--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


.




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_

Re: [f2fs-dev] [PATCH] fsck.f2fs: check nid range before use to avoid segmentation fault

2017-12-15 Thread Sheng Yong



On 2017/12/15 14:26, Yunlong Song wrote:

Signed-off-by: Yunlong Song 
---
  fsck/fsck.c | 11 ++-
  1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 11b8b0b..2212aa3 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -14,6 +14,15 @@
  char *tree_mark;
  uint32_t tree_mark_size = 256;
  
+static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)

+{
+if (nid < F2FS_ROOT_INO(sbi))
+return -EINVAL;
+if (nid >= NM_I(sbi)->max_nid)
+return -EINVAL;
+return 0;
+}
+

Hi Yunlong,
I think you could use IS_VALID_NID() instead of check_nid_range. Maybe we could
add the check 'if (nid < F2FS_ROOT_INO(sbi))' to IS_VALID_NID().

thanks,
Sheng

  int f2fs_set_main_bitmap(struct f2fs_sb_info *sbi, u32 blk, int type)
  {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -740,7 +749,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
for (idx = 0; idx < 5; idx++) {
u32 nid = le32_to_cpu(node_blk->i.i_nid[idx]);
  
-		if (nid != 0) {

+   if (nid != 0 && !check_nid_range(sbi, nid)) {
struct node_info ni;
  
  			get_node_info(sbi, nid, );





--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] fsck.f2fs: check and fix i_namelen to avoid double free

2017-12-15 Thread Sheng Yong



On 2017/12/15 14:25, Yunlong Song wrote:

Signed-off-by: Yunlong Song 
---
  fsck/fsck.c | 19 ---
  1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 2212aa3..8ff4e4b 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -643,7 +643,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
int ofs = get_extra_isize(node_blk);
unsigned char *en;
-   int namelen;
+   int namelen, i_namelen;
unsigned int idx = 0;
int need_fix = 0;
int ret;
@@ -850,8 +850,21 @@ skip_blkcnt_fix:
en = malloc(F2FS_NAME_LEN + 1);
ASSERT(en);
  
-	namelen = convert_encrypted_name(node_blk->i.i_name,

-   le32_to_cpu(node_blk->i.i_namelen),
+   i_namelen = le32_to_cpu(node_blk->i.i_namelen);
+   namelen = strlen((const char *)node_blk->i.i_name);

Hi, Yunlong
The strlen doesn't work for encrypted i_name. strlen may get a wrong namelen.

thanks,
Sheng

+   if (i_namelen > F2FS_NAME_LEN) {
+   ASSERT_MSG("ino: 0x%x has i_namelen: 0x%x, "
+   "but has %d characters for name",
+   nid, i_namelen, namelen);
+   if (c.fix_on) {
+   FIX_MSG("[0x%x] i_namelen=0x%x -> 0x%x", nid, i_namelen,
+   namelen);
+   node_blk->i.i_namelen = cpu_to_le32(namelen);
+   need_fix = 1;
+   }
+   i_namelen = namelen;
+   }
+   namelen = convert_encrypted_name(node_blk->i.i_name, i_namelen,
en, file_enc_name(_blk->i));
en[namelen] = '\0';
if (ftype == F2FS_FT_ORPHAN)




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/3] f2fs: remove unused parameter

2017-11-22 Thread Sheng Yong
Commit d260081ccf37 ("f2fs: change recovery policy of xattr node block")
removes the use of blkaddr, which is no longer used. So remove the
parameter.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/f2fs.h | 3 +--
 fs/f2fs/node.c | 2 +-
 fs/f2fs/recovery.c | 6 +++---
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index a269d795ba7c..bab4c2287090 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2607,8 +2607,7 @@ void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
 void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
 int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
 void recover_inline_xattr(struct inode *inode, struct page *page);
-int recover_xattr_data(struct inode *inode, struct page *page,
-   block_t blkaddr);
+int recover_xattr_data(struct inode *inode, struct page *page);
 int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
 int restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index fe1fc662af2a..ebb0d1797431 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2238,7 +2238,7 @@ void recover_inline_xattr(struct inode *inode, struct 
page *page)
f2fs_put_page(ipage, 1);
 }
 
-int recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
+int recover_xattr_data(struct inode *inode, struct page *page)
 {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid;
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 92c57ace1939..7d63faf51e52 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -404,7 +404,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info 
*sbi,
 }
 
 static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
-   struct page *page, block_t blkaddr)
+   struct page *page)
 {
struct dnode_of_data dn;
struct node_info ni;
@@ -415,7 +415,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct 
inode *inode,
if (IS_INODE(page)) {
recover_inline_xattr(inode, page);
} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
-   err = recover_xattr_data(inode, page, blkaddr);
+   err = recover_xattr_data(inode, page);
if (!err)
recovered++;
goto out;
@@ -568,7 +568,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct 
list_head *inode_list,
break;
}
}
-   err = do_recover_data(sbi, entry->inode, page, blkaddr);
+   err = do_recover_data(sbi, entry->inode, page);
if (err) {
f2fs_put_page(page, 1);
break;
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/3] f2fs: still write data if preallocate only partial blocks

2017-11-22 Thread Sheng Yong
If there is not enough space left, f2fs_preallocate_blocks may only
preallocte partial blocks. As a result, the write operation fails
but i_blocks is not 0.  To avoid this, f2fs should write data in
non-preallocation way and write as many data as the size of i_blocks.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fs/f2fs/data.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index b0781edc9ada..e593df628158 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -862,8 +862,14 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct 
iov_iter *from)
if (err)
return err;
}
-   if (!f2fs_has_inline_data(inode))
-   return f2fs_map_blocks(inode, , 1, F2FS_GET_BLOCK_PRE_AIO);
+   if (!f2fs_has_inline_data(inode)) {
+   err = f2fs_map_blocks(inode, , 1, F2FS_GET_BLOCK_PRE_AIO);
+   if (map.m_len > 0 && err == -ENOSPC) {
+   set_inode_flag(inode, FI_NO_PREALLOC);
+   err = 0;
+   }
+   return err;
+   }
return err;
 }
 
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH 1/3] f2fs: introduce sysfs readdir_ra to readahead inode block in readdir

2017-11-22 Thread Sheng Yong
This patch introduces a sysfs interface readdir_ra to enable/disable
readaheading inode block in f2fs_readdir. When readdir_ra is enabled,
it improves the performance of "readdir + stat".

For 300,000 files:
time find /data/test > /dev/null
disable readdir_ra: 1m25.69s real  0m01.94s user  0m50.80s system
enable  readdir_ra: 0m18.55s real  0m00.44s user  0m15.39s system

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++
 fs/f2fs/dir.c   | 4 
 fs/f2fs/f2fs.h  | 1 +
 fs/f2fs/sysfs.c | 2 ++
 4 files changed, 13 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index a7799c2fca28..d870b5514d15 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -186,3 +186,9 @@ Date:   August 2017
 Contact:   "Jaegeuk Kim" <jaeg...@kernel.org>
 Description:
 Controls sleep time of GC urgent mode
+
+What:  /sys/fs/f2fs//readdir_ra
+Date:  November 2017
+Contact:   "Sheng Yong" <shengyo...@huawei.com>
+Description:
+Controls readahead inode block in readdir.
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 2d98d877c09d..724304dc6143 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -798,6 +798,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct 
f2fs_dentry_ptr *d,
unsigned int bit_pos;
struct f2fs_dir_entry *de = NULL;
struct fscrypt_str de_name = FSTR_INIT(NULL, 0);
+   struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode);
 
bit_pos = ((unsigned long)ctx->pos % d->max);
 
@@ -836,6 +837,9 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct 
f2fs_dentry_ptr *d,
le32_to_cpu(de->ino), d_type))
return 1;
 
+   if (sbi->readdir_ra == 1)
+   ra_node_page(sbi, le32_to_cpu(de->ino));
+
bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
ctx->pos = start_pos + bit_pos;
}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ca6b0c9bc621..a269d795ba7c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1095,6 +1095,7 @@ struct f2fs_sb_info {
int dir_level;  /* directory level */
int inline_xattr_size;  /* inline xattr size */
unsigned int trigger_ssr_threshold; /* threshold to trigger ssr */
+   int readdir_ra; /* readahead inode in readdir */
 
block_t user_block_count;   /* # of user blocks */
block_t total_valid_block_count;/* # of valid blocks */
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 9835348b6e5d..93c3364250dd 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -299,6 +299,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
@@ -346,6 +347,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(cp_interval),
ATTR_LIST(idle_interval),
ATTR_LIST(iostat_enable),
+   ATTR_LIST(readdir_ra),
 #ifdef CONFIG_F2FS_FAULT_INJECTION
ATTR_LIST(inject_rate),
ATTR_LIST(inject_type),
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v5] dump/fsck: introduce print_xattr_entry

2017-11-02 Thread Sheng Yong
This patch exports read_all_xattrs to allow dump/fsck to get all xattrs,
and introduces print_xattr_entry which tries to parse an xattr entry
accroding to its xattr index.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v3->v5:
Please ignore the previous [PATCH v3/v4] because of the bad indent (some
configure of my email client may be not correct). Sorry for the noise :(

v2->v3:
check if  is supported. If it is not, print ACL value
in hex format.

thanks,
Sheng
 configure.ac |   3 +-
 fsck/dump.c  |  18 
 fsck/fsck.h  |   7 +++-
 fsck/mount.c | 132 +--
 fsck/xattr.c |   2 +-
 fsck/xattr.h |  54 +++-
 6 files changed, 199 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2fc9260..91bbc9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,7 +92,8 @@ AS_IF([test "x$have_blkid" = "xyes"],
 
 # Checks for header files.
 AC_CHECK_HEADERS([linux/fs.h linux/blkzoned.h fcntl.h mntent.h stdlib.h 
string.h \
-   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h])
+   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h \
+   linux/posix_acl.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_INLINE
diff --git a/fsck/dump.c b/fsck/dump.c
index 128dc53..90fd073 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -419,17 +419,17 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int 
force)
if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
le32_to_cpu(node_blk->footer.nid) == ni.nid &&
ni.ino == ni.nid) {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
dump_file(sbi, , node_blk, force);
} else {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
MSG(force, "Invalid (i)node block\n\n");
}
 
free(node_blk);
 }
 
-static void dump_node_from_blkaddr(u32 blk_addr)
+static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
 {
struct f2fs_node *node_blk;
int ret;
@@ -441,9 +441,9 @@ static void dump_node_from_blkaddr(u32 blk_addr)
ASSERT(ret >= 0);
 
if (c.dbg_lv > 0)
-   print_node_info(node_blk, 0);
+   print_node_info(sbi, node_blk, 0);
else
-   print_inode_info(_blk->i, 1);
+   print_inode_info(sbi, node_blk, 1);
 
free(node_blk);
 }
@@ -567,7 +567,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
 
/* print inode */
if (c.dbg_lv > 0)
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
 
if (type == SEG_TYPE_CUR_DATA || type == SEG_TYPE_DATA) {
MSG(0, "FS Userdata Area: Data block from 0x%x\n", blk_addr);
@@ -575,7 +575,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_data_offset(ni.blk_addr,
le16_to_cpu(sum_entry.ofs_in_node));
} else {
@@ -583,13 +583,13 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
if (ni.ino == ni.nid) {
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
} else {
MSG(0, " - Node block: id = 0x%x from 0x%x\n",
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_node_offset(ni.blk_addr);
}
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 1e8ed0b..f8caa46 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -141,8 +141,8 @@ int convert_encrypted_name(unsigned char *, int, unsigned 
char *, int);
 
 extern void update_free_segments(struct f2fs_sb_info *);
 void print_cp_state(u32);
-extern void print_node_info(struct f2fs_node *, int);
-extern void print_inode_info(struct f2fs_inode *, int);
+extern voi

[f2fs-dev] [PATCH v4] dump/fsck: introduce print_xattr_entry

2017-11-02 Thread Sheng Yong

This patch exports read_all_xattrs to allow dump/fsck to get all xattrs,
and introduces print_xattr_entry which tries to parse an xattr entry
accroding to its xattr index.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v3->v4:
Please ignore the previous [PATCH v3] because of the bad indent. Sorry
for the noise :(

v2->v3:
check if  is supported. If it is not, print ACL value
in hex format.

thanks,
Sheng

 configure.ac |   3 +-
 fsck/dump.c  |  18 
 fsck/fsck.h  |   7 +++-
 fsck/mount.c | 132 +--
 fsck/xattr.c |   2 +-
 fsck/xattr.h |  54 +++-
 6 files changed, 199 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2fc9260..91bbc9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,7 +92,8 @@ AS_IF([test "x$have_blkid" = "xyes"],

 # Checks for header files.
 AC_CHECK_HEADERS([linux/fs.h linux/blkzoned.h fcntl.h mntent.h stdlib.h 
string.h \
-   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h])
+   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h \
+   linux/posix_acl.h])

 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_INLINE
diff --git a/fsck/dump.c b/fsck/dump.c
index 128dc53..90fd073 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -419,17 +419,17 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int 
force)
if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
le32_to_cpu(node_blk->footer.nid) == ni.nid &&
ni.ino == ni.nid) {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
dump_file(sbi, , node_blk, force);
} else {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
MSG(force, "Invalid (i)node block\n\n");
}

free(node_blk);
 }

-static void dump_node_from_blkaddr(u32 blk_addr)
+static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
 {
struct f2fs_node *node_blk;
int ret;
@@ -441,9 +441,9 @@ static void dump_node_from_blkaddr(u32 blk_addr)
ASSERT(ret >= 0);

if (c.dbg_lv > 0)
-   print_node_info(node_blk, 0);
+   print_node_info(sbi, node_blk, 0);
else
-   print_inode_info(_blk->i, 1);
+   print_inode_info(sbi, node_blk, 1);

free(node_blk);
 }
@@ -567,7 +567,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)

/* print inode */
if (c.dbg_lv > 0)
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);

if (type == SEG_TYPE_CUR_DATA || type == SEG_TYPE_DATA) {
MSG(0, "FS Userdata Area: Data block from 0x%x\n", blk_addr);
@@ -575,7 +575,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_data_offset(ni.blk_addr,
le16_to_cpu(sum_entry.ofs_in_node));
} else {
@@ -583,13 +583,13 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
if (ni.ino == ni.nid) {
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
} else {
MSG(0, " - Node block: id = 0x%x from 0x%x\n",
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_node_offset(ni.blk_addr);
}
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 1e8ed0b..f8caa46 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -141,8 +141,8 @@ int convert_encrypted_name(unsigned char *, int, unsigned 
char *, int);

 extern void update_free_segments(struct f2fs_sb_info *);
 void print_cp_state(u32);
-extern void print_node_info(struct f2fs_node *, int);
-extern void print_inode_info(struct f2fs_inode *, int);
+extern void print_node_info(struct f2fs_sb_info *, struct f2fs_node *, int);

[f2fs-dev] [PATCH v3] dump/fsck: introduce print_xattr_entry

2017-11-02 Thread Sheng Yong

This patch exports read_all_xattrs to allow dump/fsck to get all xattrs,
and introduces print_xattr_entry which tries to parse an xattr entry
accroding to its xattr index.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
v2->v3:
check if  is supported. If it is not, print ACL value
in hex format.

 configure.ac |   3 +-
 fsck/dump.c  |  18 
 fsck/fsck.h  |   7 +++-
 fsck/mount.c | 132 +--
 fsck/xattr.c |   2 +-
 fsck/xattr.h |  54 +++-
 6 files changed, 199 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2fc9260..91bbc9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,7 +92,8 @@ AS_IF([test "x$have_blkid" = "xyes"],

 # Checks for header files.
 AC_CHECK_HEADERS([linux/fs.h linux/blkzoned.h fcntl.h mntent.h stdlib.h 
string.h \
-   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h])
+   sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h \
+   linux/posix_acl.h])

 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_INLINE
diff --git a/fsck/dump.c b/fsck/dump.c
index 128dc53..90fd073 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -419,17 +419,17 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int 
force)
if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
le32_to_cpu(node_blk->footer.nid) == ni.nid &&
ni.ino == ni.nid) {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
dump_file(sbi, , node_blk, force);
} else {
-   print_node_info(node_blk, force);
+   print_node_info(sbi, node_blk, force);
MSG(force, "Invalid (i)node block\n\n");
}

free(node_blk);
 }

-static void dump_node_from_blkaddr(u32 blk_addr)
+static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
 {
struct f2fs_node *node_blk;
int ret;
@@ -441,9 +441,9 @@ static void dump_node_from_blkaddr(u32 blk_addr)
ASSERT(ret >= 0);

if (c.dbg_lv > 0)
-   print_node_info(node_blk, 0);
+   print_node_info(sbi, node_blk, 0);
else
-   print_inode_info(_blk->i, 1);
+   print_inode_info(sbi, node_blk, 1);

free(node_blk);
 }
@@ -567,7 +567,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)

/* print inode */
if (c.dbg_lv > 0)
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);

if (type == SEG_TYPE_CUR_DATA || type == SEG_TYPE_DATA) {
MSG(0, "FS Userdata Area: Data block from 0x%x\n", blk_addr);
@@ -575,7 +575,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_data_offset(ni.blk_addr,
le16_to_cpu(sum_entry.ofs_in_node));
} else {
@@ -583,13 +583,13 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 
blk_addr)
if (ni.ino == ni.nid) {
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
} else {
MSG(0, " - Node block: id = 0x%x from 0x%x\n",
nid, ni.blk_addr);
MSG(0, " - Inode block   : id = 0x%x from 0x%x\n",
ni.ino, ino_ni.blk_addr);
-   dump_node_from_blkaddr(ino_ni.blk_addr);
+   dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
dump_node_offset(ni.blk_addr);
}
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 1e8ed0b..f8caa46 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -141,8 +141,8 @@ int convert_encrypted_name(unsigned char *, int, unsigned 
char *, int);

 extern void update_free_segments(struct f2fs_sb_info *);
 void print_cp_state(u32);
-extern void print_node_info(struct f2fs_node *, int);
-extern void print_inode_info(struct f2fs_inode *, int);
+extern void print_node_info(struct f2fs_sb_info *, struct f2fs_node *, int);
+extern void print_inode_info(struct f2fs_sb_info *, struct f2fs_node *, int);
 extern struct seg_entr

[f2fs-dev] [RFC PATCH v2 9/9] fsck.f2fs: format output message of FIX_MSG

2017-11-01 Thread Sheng Yong
This patch removes an extra '\n' at the end of the string in FIX_MSG.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
---
 fsck/fsck.c  | 4 ++--
 fsck/mount.c | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 77490d8..1905319 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -966,7 +966,7 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
else {
node_blk->in.nid[i] = 0;
need_fix = 1;
-   FIX_MSG("Set indirect node 0x%x -> 0\n", i);
+   FIX_MSG("Set indirect node 0x%x -> 0", i);
}
 skip:
child->pgofs += ADDRS_PER_BLOCK;
@@ -1006,7 +1006,7 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
else {
node_blk->in.nid[i] = 0;
need_fix = 1;
-   FIX_MSG("Set double indirect node 0x%x -> 0\n", 
i);
+   FIX_MSG("Set double indirect node 0x%x -> 0", 
i);
}
 skip:
child->pgofs += ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
diff --git a/fsck/mount.c b/fsck/mount.c
index d631547..cf2ef8e 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1981,7 +1981,7 @@ void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
if (le32_to_cpu(nid_in_journal(journal, i)) == nid) {
memset(_in_journal(journal, i), 0,
sizeof(struct f2fs_nat_entry));
-   FIX_MSG("Remove nid [0x%x] in nat journal\n", nid);
+   FIX_MSG("Remove nid [0x%x] in nat journal", nid);
return;
}
}
@@ -2001,6 +2001,7 @@ void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
} else {
memset(_block->entries[entry_off], 0,
sizeof(struct f2fs_nat_entry));
+   FIX_MSG("Remove nid [0x%x] in NAT", nid);
}
 
ret = dev_write_block(nat_block, block_addr);
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC PATCH v2 6/9] fsck.f2fs: introduce new option --dry-run

2017-11-01 Thread Sheng Yong
With --dry-run enabled, fsck.f2fs will do all checks and "fixes" except
that all fixes will not be written to storage at last.

Signed-off-by: Sheng Yong <shengyo...@huawei.com>
Reviewed-by: Chao Yu <yuch...@huawei.com>
---
 fsck/main.c   | 14 +-
 include/f2fs_fs.h |  1 +
 lib/libf2fs.c |  1 +
 lib/libf2fs_io.c  |  3 +++
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/fsck/main.c b/fsck/main.c
index 93037e1..baa8efc 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -18,6 +18,7 @@
 #include "fsck.h"
 #include 
 #include 
+#include 
 
 struct f2fs_fsck gfsck;
 
@@ -30,6 +31,7 @@ void fsck_usage()
MSG(0, "  -f check/fix entire partition\n");
MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
MSG(0, "  -t show directory tree\n");
+   MSG(0, "  --dry-run do not really fix corruptions\n");
exit(1);
 }
 
@@ -117,10 +119,20 @@ void f2fs_parse_options(int argc, char *argv[])
 
if (!strcmp("fsck.f2fs", prog)) {
const char *option_string = ":ad:fp:t";
+   int opt = 0;
+   struct option long_opt[] = {
+   {"dry-run", no_argument, 0, 1},
+   {0, 0, 0, 0}
+   };
 
c.func = FSCK;
-   while ((option = getopt(argc, argv, option_string)) != EOF) {
+   while ((option = getopt_long(argc, argv, option_string,
+   long_opt, )) != EOF) {
switch (option) {
+   case 1:
+   c.dry_run = 1;
+   MSG(0, "Info: Dry run\n");
+   break;
case 'a':
c.auto_fix = 1;
MSG(0, "Info: Fix the reported corruption.\n");
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index e1e299d..64a796d 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -300,6 +300,7 @@ struct f2fs_configuration {
int trimmed;
int func;
void *private;
+   int dry_run;
int fix_on;
int bug_on;
int auto_fix;
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 69f5ccc..259bd17 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -598,6 +598,7 @@ void f2fs_init_configuration(void)
c.trimmed = 0;
c.ro = 0;
c.kd = -1;
+   c.dry_run = 0;
 }
 
 static int is_mounted(const char *mpt, const char *device)
diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c
index 50ff171..8a79672 100644
--- a/lib/libf2fs_io.c
+++ b/lib/libf2fs_io.c
@@ -129,6 +129,9 @@ int dev_write(void *buf, __u64 offset, size_t len)
 {
int fd;
 
+   if (c.dry_run)
+   return 0;
+
if (c.sparse_mode)
return dev_write_sparse(buf, offset, len);
 
-- 
2.11.0


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


<    1   2   3   >