Re: [f2fs-dev] [PATCH 1/2] f2fs: reorganize __f2fs_add_link

2015-07-24 Thread Jaegeuk Kim
Hi Chao,

On Fri, Jul 24, 2015 at 06:31:16PM +0800, Chao Yu wrote:
 Hi Jaegeuk,
 
  -Original Message-
  From: Jaegeuk Kim [mailto:jaeg...@kernel.org]
  Sent: Friday, July 24, 2015 2:15 AM
  To: Chao Yu
  Cc: linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org
  Subject: Re: [PATCH 1/2] f2fs: reorganize __f2fs_add_link
  
  Hi Chao,
  
  On Wed, Jul 22, 2015 at 06:21:52PM +0800, Chao Yu wrote:
   Firstly, spliting init_inode_metadata into two parts as below since they
   are relatively independent.
   1) init_inode_metadata: init datas belong to newly created inode;
   2) update_inode_metadata: update inode info for linking inode to new
   dentry.
  
   Secondly, move init_inode_metadata to the front of __f2fs_add_link,
   So the flow of __f2fs_add_link will be reorganized as:
   1) init inode meta data for new creatation;
   2) lookup dentry page and insert new directory entry in the page;
   3) update meta data of inode and parent.
  
   Signed-off-by: Chao Yu chao2...@samsung.com
   ---
fs/f2fs/dir.c| 129 
   ---
fs/f2fs/f2fs.h   |   4 +-
fs/f2fs/inline.c |   2 +-
3 files changed, 78 insertions(+), 57 deletions(-)
  
   diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
   index a34ebd8..0ad9a1c 100644
   --- a/fs/f2fs/dir.c
   +++ b/fs/f2fs/dir.c
   @@ -381,43 +381,68 @@ static int make_empty_dir(struct inode *inode,
 return 0;
}
  
   -struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
   +int init_inode_metadata(struct inode *inode, struct inode *dir,
 const struct qstr *name, struct page *dpage)
{
 struct page *page;
 int err;
  
   - if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
   - page = new_inode_page(inode);
   - if (IS_ERR(page))
   - return page;
   + if (!is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE))
   + return 0;
  
   - if (S_ISDIR(inode-i_mode)) {
   - err = make_empty_dir(inode, dir, page);
   - if (err)
   - goto error;
   - }
   + page = new_inode_page(inode);
   + if (IS_ERR(page))
   + return PTR_ERR(page);
  
   - err = f2fs_init_acl(inode, dir, page, dpage);
   + if (S_ISDIR(inode-i_mode)) {
   + err = make_empty_dir(inode, dir, page);
 if (err)
   - goto put_error;
   + goto error;
   + }
  
   - err = f2fs_init_security(inode, dir, name, page);
   + err = f2fs_init_acl(inode, dir, page, dpage);
   + if (err)
   + goto put_error;
   +
   + err = f2fs_init_security(inode, dir, name, page);
   + if (err)
   + goto put_error;
   +
   + if (f2fs_encrypted_inode(dir)  f2fs_may_encrypt(inode)) {
   + err = f2fs_inherit_context(dir, inode, page);
 if (err)
 goto put_error;
   + }
  
   - if (f2fs_encrypted_inode(dir)  f2fs_may_encrypt(inode)) {
   - err = f2fs_inherit_context(dir, inode, page);
   - if (err)
   - goto put_error;
   - }
   - } else {
   - page = get_node_page(F2FS_I_SB(dir), inode-i_ino);
   - if (IS_ERR(page))
   - return page;
   + if (f2fs_encrypted_inode(dir))
   + file_set_enc_name(inode);
   +
   + update_inode(inode, page);
   + f2fs_put_page(page, 1);
  
  We should not put the inode page here.
  Since checkpoint can be called and flush all the node pages with valid
  NAT entres. Once power-off happens after then, we can see unreachable NAT
  entries.
 
 IMO, all callers of init_inode_metadata such as 
 __f2fs_add_link/f2fs_do_tmpfile,
 they are all protected well by cp_rwsem, so checkpoint  SPO will not easily
 bother us.
 
 1) Lately in __f2fs_add_link, ino of ipage will be inserted into directory 
 entry
 of parent's inode, this makes our nat entry of ipage reachable.
 2) And also in __f2fs_tmpfile, ino will be added in orphan list, so all data
 resource of the inode will be evicted after CP-SPO-RFR procedure.
 
 Is there anything I missed?

Let me think about this for a while.
I think two patches are clean-ups with a little bit big changes.
Currently, we've touched many parts including extent_cache, so I need to focus
on stabilizing them first.
After then, I'd like to dig two clean-up patches. Ok?

Thanks,

 
 Thanks,
 
  
  Thanks,

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


Re: [f2fs-dev] [PATCH 1/2] f2fs: reorganize __f2fs_add_link

2015-07-24 Thread Jaegeuk Kim
Hi Chao,

BTW, isn't there any problem on update_inode/mark_inode_dirty stuffs?
And, is there a hole to write uncompleted node pages unnecessarily?

On Fri, Jul 24, 2015 at 08:52:00AM -0700, Jaegeuk Kim wrote:
 Hi Chao,
 
 On Fri, Jul 24, 2015 at 06:31:16PM +0800, Chao Yu wrote:
  Hi Jaegeuk,
  
   -Original Message-
   From: Jaegeuk Kim [mailto:jaeg...@kernel.org]
   Sent: Friday, July 24, 2015 2:15 AM
   To: Chao Yu
   Cc: linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org
   Subject: Re: [PATCH 1/2] f2fs: reorganize __f2fs_add_link
   
   Hi Chao,
   
   On Wed, Jul 22, 2015 at 06:21:52PM +0800, Chao Yu wrote:
Firstly, spliting init_inode_metadata into two parts as below since they
are relatively independent.
1) init_inode_metadata: init datas belong to newly created inode;
2) update_inode_metadata: update inode info for linking inode to new
dentry.
   
Secondly, move init_inode_metadata to the front of __f2fs_add_link,
So the flow of __f2fs_add_link will be reorganized as:
1) init inode meta data for new creatation;
2) lookup dentry page and insert new directory entry in the page;
3) update meta data of inode and parent.
   
Signed-off-by: Chao Yu chao2...@samsung.com
---
 fs/f2fs/dir.c| 129 
---
 fs/f2fs/f2fs.h   |   4 +-
 fs/f2fs/inline.c |   2 +-
 3 files changed, 78 insertions(+), 57 deletions(-)
   
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index a34ebd8..0ad9a1c 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -381,43 +381,68 @@ static int make_empty_dir(struct inode *inode,
return 0;
 }
   
-struct page *init_inode_metadata(struct inode *inode, struct inode 
*dir,
+int init_inode_metadata(struct inode *inode, struct inode *dir,
const struct qstr *name, struct page *dpage)
 {
struct page *page;
int err;
   
-   if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
-   page = new_inode_page(inode);
-   if (IS_ERR(page))
-   return page;
+   if (!is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE))
+   return 0;
   
-   if (S_ISDIR(inode-i_mode)) {
-   err = make_empty_dir(inode, dir, page);
-   if (err)
-   goto error;
-   }
+   page = new_inode_page(inode);
+   if (IS_ERR(page))
+   return PTR_ERR(page);
   
-   err = f2fs_init_acl(inode, dir, page, dpage);
+   if (S_ISDIR(inode-i_mode)) {
+   err = make_empty_dir(inode, dir, page);
if (err)
-   goto put_error;
+   goto error;
+   }
   
-   err = f2fs_init_security(inode, dir, name, page);
+   err = f2fs_init_acl(inode, dir, page, dpage);
+   if (err)
+   goto put_error;
+
+   err = f2fs_init_security(inode, dir, name, page);
+   if (err)
+   goto put_error;
+
+   if (f2fs_encrypted_inode(dir)  f2fs_may_encrypt(inode)) {
+   err = f2fs_inherit_context(dir, inode, page);
if (err)
goto put_error;
+   }
   
-   if (f2fs_encrypted_inode(dir)  
f2fs_may_encrypt(inode)) {
-   err = f2fs_inherit_context(dir, inode, page);
-   if (err)
-   goto put_error;
-   }
-   } else {
-   page = get_node_page(F2FS_I_SB(dir), inode-i_ino);
-   if (IS_ERR(page))
-   return page;
+   if (f2fs_encrypted_inode(dir))
+   file_set_enc_name(inode);
+
+   update_inode(inode, page);
+   f2fs_put_page(page, 1);
   
   We should not put the inode page here.
   Since checkpoint can be called and flush all the node pages with valid
   NAT entres. Once power-off happens after then, we can see unreachable NAT
   entries.
  
  IMO, all callers of init_inode_metadata such as 
  __f2fs_add_link/f2fs_do_tmpfile,
  they are all protected well by cp_rwsem, so checkpoint  SPO will not easily
  bother us.
  
  1) Lately in __f2fs_add_link, ino of ipage will be inserted into directory 
  entry
  of parent's inode, this makes our nat entry of ipage reachable.
  2) And also in __f2fs_tmpfile, ino will be added in orphan list, so all data
  resource of the inode will be evicted after CP-SPO-RFR procedure.
  
  Is there anything I missed?
 
 Let me think about this for a while.
 I think two patches are clean-ups with a little bit big changes.
 Currently, we've touched many parts including extent_cache, so I need to focus

[f2fs-dev] [PATCH 1/2] f2fs: reorganize __f2fs_add_link

2015-07-22 Thread Chao Yu
Firstly, spliting init_inode_metadata into two parts as below since they
are relatively independent.
1) init_inode_metadata: init datas belong to newly created inode;
2) update_inode_metadata: update inode info for linking inode to new
dentry.

Secondly, move init_inode_metadata to the front of __f2fs_add_link,
So the flow of __f2fs_add_link will be reorganized as:
1) init inode meta data for new creatation;
2) lookup dentry page and insert new directory entry in the page;
3) update meta data of inode and parent.

Signed-off-by: Chao Yu chao2...@samsung.com
---
 fs/f2fs/dir.c| 129 ---
 fs/f2fs/f2fs.h   |   4 +-
 fs/f2fs/inline.c |   2 +-
 3 files changed, 78 insertions(+), 57 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index a34ebd8..0ad9a1c 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -381,43 +381,68 @@ static int make_empty_dir(struct inode *inode,
return 0;
 }
 
-struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
+int init_inode_metadata(struct inode *inode, struct inode *dir,
const struct qstr *name, struct page *dpage)
 {
struct page *page;
int err;
 
-   if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
-   page = new_inode_page(inode);
-   if (IS_ERR(page))
-   return page;
+   if (!is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE))
+   return 0;
 
-   if (S_ISDIR(inode-i_mode)) {
-   err = make_empty_dir(inode, dir, page);
-   if (err)
-   goto error;
-   }
+   page = new_inode_page(inode);
+   if (IS_ERR(page))
+   return PTR_ERR(page);
 
-   err = f2fs_init_acl(inode, dir, page, dpage);
+   if (S_ISDIR(inode-i_mode)) {
+   err = make_empty_dir(inode, dir, page);
if (err)
-   goto put_error;
+   goto error;
+   }
 
-   err = f2fs_init_security(inode, dir, name, page);
+   err = f2fs_init_acl(inode, dir, page, dpage);
+   if (err)
+   goto put_error;
+
+   err = f2fs_init_security(inode, dir, name, page);
+   if (err)
+   goto put_error;
+
+   if (f2fs_encrypted_inode(dir)  f2fs_may_encrypt(inode)) {
+   err = f2fs_inherit_context(dir, inode, page);
if (err)
goto put_error;
+   }
 
-   if (f2fs_encrypted_inode(dir)  f2fs_may_encrypt(inode)) {
-   err = f2fs_inherit_context(dir, inode, page);
-   if (err)
-   goto put_error;
-   }
-   } else {
-   page = get_node_page(F2FS_I_SB(dir), inode-i_ino);
-   if (IS_ERR(page))
-   return page;
+   if (f2fs_encrypted_inode(dir))
+   file_set_enc_name(inode);
+
+   update_inode(inode, page);
+   f2fs_put_page(page, 1);
+   return 0;
+
+put_error:
+   f2fs_put_page(page, 1);
+error:
+   /* once the failed inode becomes a bad inode, i_mode is S_IFREG */
+   truncate_inode_pages(inode-i_data, 0);
+   truncate_blocks(inode, 0, false);
+   remove_dirty_dir_inode(inode);
+   remove_inode_page(inode);
+   return err;
+}
+
+struct page *update_inode_metadata(struct inode *dir, struct inode *inode,
+   const struct qstr *name)
+{
+   struct page *page;
+
+   page = get_node_page(F2FS_I_SB(inode), inode-i_ino);
+   if (IS_ERR(page))
+   return page;
 
+   if (!is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE))
set_cold_node(inode, page);
-   }
 
if (name)
init_dent_inode(name, page);
@@ -433,20 +458,10 @@ struct page *init_inode_metadata(struct inode *inode, 
struct inode *dir,
 * we should remove this inode from orphan list.
 */
if (inode-i_nlink == 0)
-   remove_orphan_inode(F2FS_I_SB(dir), inode-i_ino);
+   remove_orphan_inode(F2FS_I_SB(inode), inode-i_ino);
inc_nlink(inode);
}
return page;
-
-put_error:
-   f2fs_put_page(page, 1);
-error:
-   /* once the failed inode becomes a bad inode, i_mode is S_IFREG */
-   truncate_inode_pages(inode-i_data, 0);
-   truncate_blocks(inode, 0, false);
-   remove_dirty_dir_inode(inode);
-   remove_inode_page(inode);
-   return ERR_PTR(err);
 }
 
 void update_parent_metadata(struct inode *dir, struct inode *inode,
@@ -537,10 +552,18 @@ int __f2fs_add_link(struct inode *dir, const struct qstr 
*name,
new_name.name = fname_name(fname);
new_name.len = fname_len(fname);
 
+   if (inode) {
+   down_write(F2FS_I(inode)-i_sem);
+   err =