[f2fs-dev] [PATCH] fsck.f2fs: refactor extent info verification flow

2016-03-15 Thread Chao Yu
There are some issues in original approach:
- memory allocated in i_extent.map will leak
- do not convert fields in i_ext from on-disk format to cpu format
- do not support checking file offset with extent info

This patch refactors the flow for fixing above issues and supporting
file offset check.

Signed-off-by: Chao Yu 
---
 fsck/fsck.c | 120 ++--
 fsck/fsck.h |  28 +++---
 fsck/main.c |   2 +-
 3 files changed, 93 insertions(+), 57 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index acdd5d4..95b 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -494,8 +494,7 @@ out:
 
 int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
u32 nid, u8 *name, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
-   u32 *blk_cnt, struct child_info *child,
-   struct extent_info *i_ext)
+   u32 *blk_cnt, struct child_info *child)
 {
struct node_info ni;
struct f2fs_node *node_blk = NULL;
@@ -514,19 +513,19 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_WARM_NODE);
fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
-   blk_cnt, child, , i_ext);
+   blk_cnt, child, );
break;
case TYPE_INDIRECT_NODE:
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_COLD_NODE);
fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
-   blk_cnt, child, i_ext);
+   blk_cnt, child);
break;
case TYPE_DOUBLE_INDIRECT_NODE:
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_COLD_NODE);
fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
-   blk_cnt, child, i_ext);
+   blk_cnt, child);
break;
default:
ASSERT(0);
@@ -539,24 +538,62 @@ err:
return -EINVAL;
 }
 
-static void update_i_extent(struct extent_info *i_ext, block_t blkaddr)
+static inline void get_extent_info(struct extent_info *ext,
+   struct f2fs_extent *i_ext)
 {
-   block_t end_addr;
+   ext->fofs = le32_to_cpu(i_ext->fofs);
+   ext->blk = le32_to_cpu(i_ext->blk_addr);
+   ext->len = le32_to_cpu(i_ext->len);
+}
+
+static void check_extent_info(struct child_info *child,
+   block_t blkaddr, int last)
+{
+   struct extent_info *ei = >ei;
+   u32 pgofs = child->pgofs;
+   int is_hole = 0;
+
+   if (!ei->len)
+   return;
 
-   if (!i_ext)
+   if (child->state & FSCK_UNMATCHED_EXTENT)
return;
 
-   end_addr = i_ext->ext.blk_addr + i_ext->ext.len;
+   if (last) {
+   /* hole exist in the back of extent */
+   if (child->last_blk != ei->blk + ei->len - 1)
+   child->state |= FSCK_UNMATCHED_EXTENT;
+   return;
+   }
 
-   /* TODO: check its file offset later */
-   if (blkaddr >= i_ext->ext.blk_addr && blkaddr < end_addr) {
-   unsigned int offset = blkaddr - i_ext->ext.blk_addr;
+   if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR)
+   is_hole = 1;
 
-   if (f2fs_set_bit(offset, i_ext->map))
-   i_ext->fail = 1;
-   else
-   i_ext->len--;
+   if (pgofs >= ei->fofs && pgofs < ei->fofs + ei->len) {
+   /* unmatched blkaddr */
+   if (is_hole || (blkaddr != pgofs - ei->fofs + ei->blk))
+   goto unmatched;
+
+   if (!child->last_blk) {
+   /* hole exists in the front of extent */
+   if (pgofs != ei->fofs)
+   goto unmatched;
+   } else if (child->last_blk + 1 != blkaddr) {
+   /* hole exists in the middle of extent */
+   goto unmatched;
+   }
+   child->last_blk = blkaddr;
+   return;
}
+
+   if (is_hole)
+   return;
+
+   if (blkaddr < ei->blk || blkaddr >= ei->blk + ei->len)
+   return;
+   /* unmatched file offset */
+unmatched:
+   child->state |= FSCK_UNMATCHED_EXTENT;
 }
 
 /* start with valid nid and blkaddr */
@@ -565,14 +602,13 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u32 *blk_cnt, 

[f2fs-dev] [PATCH v3 1/2] fsck.f2fs: check dirent position

2016-03-15 Thread Chao Yu
This patch enables fsck.f2fs to detect incorrect position where dirent
locates in an hierarchical hash structure directory.

Signed-off-by: Chao Yu 
---
v3:
- fix to correct current pgofs when skipping holes.
 fsck/fsck.c   | 117 +++---
 fsck/fsck.h   |   2 +
 include/f2fs_fs.h |   3 ++
 3 files changed, 108 insertions(+), 14 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index a4922fb..acdd5d4 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -565,12 +565,13 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u32 *blk_cnt, struct node_info *ni)
 {
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
-   struct child_info child = {2, 0, 0};
+   struct child_info child = {2, 0, 0, 0};
enum NODE_TYPE ntype;
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
child.p_ino = nid;
child.pp_ino = le32_to_cpu(node_blk->i.i_pino);
+   child.dir_level = node_blk->i.i_dir_level;
struct extent_info i_extent;
unsigned int idx = 0;
int need_fix = 0;
@@ -679,7 +680,8 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
}
 
/* check data blocks in inode */
-   for (idx = 0; idx < ADDRS_PER_INODE(_blk->i); idx++) {
+   for (idx = 0; idx < ADDRS_PER_INODE(_blk->i);
+   idx++, child.pgofs++) {
block_t blkaddr = le32_to_cpu(node_blk->i.i_addr[idx]);
 
if (blkaddr != 0) {
@@ -712,19 +714,31 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
else
ASSERT(0);
 
-   if (blkaddr != 0) {
-   ret = fsck_chk_node_blk(sbi, _blk->i,
-   blkaddr,
-   NULL, ftype, ntype, blk_cnt, ,
-   _extent);
-   if (!ret) {
-   *blk_cnt = *blk_cnt + 1;
-   } else if (config.fix_on) {
+   if (blkaddr == 0x0)
+   goto skip;
+
+   ret = fsck_chk_node_blk(sbi, _blk->i,
+   blkaddr,
+   NULL, ftype, ntype, blk_cnt, ,
+   _extent);
+   if (!ret) {
+   *blk_cnt = *blk_cnt + 1;
+   } else if (ret == -EINVAL) {
+   if (config.fix_on) {
node_blk->i.i_nid[idx] = 0;
need_fix = 1;
FIX_MSG("[0x%x] i_nid[%d] = 0", nid, idx);
}
+skip:
+   if (ntype == TYPE_DIRECT_NODE)
+   child.pgofs += ADDRS_PER_BLOCK;
+   else if (ntype == TYPE_INDIRECT_NODE)
+   child.pgofs += ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
+   else
+   child.pgofs += ADDRS_PER_BLOCK *
+   NIDS_PER_BLOCK * NIDS_PER_BLOCK;
}
+
}
if (i_extent.len || i_extent.fail) {
ASSERT_MSG("ino: 0x%x has wrong ext: untouched=%d, overlap=%d",
@@ -808,7 +822,7 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
child->p_ino = nid;
child->pp_ino = le32_to_cpu(inode->i_pino);
 
-   for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) {
+   for (idx = 0; idx < ADDRS_PER_BLOCK; idx++, child->pgofs++) {
block_t blkaddr = le32_to_cpu(node_blk->dn.addr[idx]);
 
if (blkaddr == 0x0)
@@ -841,9 +855,9 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
int need_fix = 0, ret;
int i = 0;
 
-   for (i = 0 ; i < NIDS_PER_BLOCK; i++) {
+   for (i = 0; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
-   continue;
+   goto skip;
ret = fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]), NULL,
ftype, TYPE_DIRECT_NODE, blk_cnt, child,
@@ -858,6 +872,8 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
need_fix = 1;
FIX_MSG("Set indirect node 0x%x -> 0\n", i);
}
+skip:
+   child->pgofs += ADDRS_PER_BLOCK;
}
}
 
@@ -882,7 +898,7 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct 
f2fs_inode *inode,
 
for (i = 0; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
-   continue;
+   goto 

[f2fs-dev] [PATCH v3] mkfs.f2fs: set segment_count in super block correctly

2016-03-15 Thread Junling Zheng
From: Fan Li 

Now f2fs will check statistics recorded in super block in
sanity_check_area_boundary() during mount. If the number of segments
per zone is greater than 1, and the disk space isn't aligned with zone,
mount will fail due to following condition:

main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
segment0_blkaddr + (segment_count << log_blocks_per_seg)

This is because when the length of main area isn't aligned with zone,
mkfs doesn't add those excess segments to segment_count_main, but adds
them to segment_count.

Here align segment_count with zone size as well as segment_count_main
to prevent such problem.

Signed-off-by: Fan Li 
Signed-off-by: Junling Zheng 
---
 mkfs/f2fs_format.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 4f38f03..960031e 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -175,7 +175,8 @@ static int f2fs_prepare_super_block(void)
}
 
set_sb(segment_count, (config.total_sectors * config.sector_size -
-   zone_align_start_offset) / segment_size_bytes);
+   zone_align_start_offset) / segment_size_bytes /
+   config.segs_per_zone * config.segs_per_zone);
 
set_sb(segment0_blkaddr, zone_align_start_offset / blk_size_bytes);
sb->cp_blkaddr = sb->segment0_blkaddr;
-- 
1.9.1


--
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785231=/4140
___
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: support access control via key management

2016-03-15 Thread Jaegeuk Kim
Hello,

On Tue, Mar 15, 2016 at 12:24:22AM -0700, Christoph Hellwig wrote:
> On Wed, Mar 09, 2016 at 04:52:48PM -0800, Jaegeuk Kim wrote:
> > Through this patch, user can assign its key into a specific normal files.
> > Then, other users who do not have that key cannot open the files.
> > Later, owner can drop its key from the files for other users to access
> > the files again.
> 
> No magic file system specific access control, please:

I agree that I must follow FS convention here.
But, in order to make this clear out, could you please elaborate why this is not
allowed?

I wrote this patch totally based on per-file encryption in which users cannot
access their files if they have no right key.
The only difference is that this controls user access with a key only, neither
encrypting file data nor dentries.

This was initiated by UX in android letting nobody be able to access the files
that owner wants to protect by passcode or fingerprint.

Does it make no sense to support this by filesystems?

Thanks,

> 
> Nacked-by: Christoph Hellwig 

--
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785231=/4140
___
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: support access control via key management

2016-03-15 Thread Christoph Hellwig
On Wed, Mar 09, 2016 at 04:52:48PM -0800, Jaegeuk Kim wrote:
> Through this patch, user can assign its key into a specific normal files.
> Then, other users who do not have that key cannot open the files.
> Later, owner can drop its key from the files for other users to access
> the files again.

No magic file system specific access control, please:

Nacked-by: Christoph Hellwig 

--
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785231=/4140
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel