linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
To: Huajun Li <huajun.li.lee@gmail.com>
Cc: Huajun Li <huajun.li@intel.com>,
	Weihong Xu <weihong.xu@intel.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: Re: [f2fs-dev 4/5] f2fs: Key functions to handle inline data
Date: Tue, 29 Oct 2013 10:06:27 +0900	[thread overview]
Message-ID: <1383008787.14041.8.camel@kjgkr> (raw)
In-Reply-To: <CA+v9cxZfy37vzC+s8rDtpM34JLh38BBMocoU74TYRc1gvFSZPw@mail.gmail.com>

Hi,

2013-10-29 (화), 01:20 +0800, Huajun Li:
> On Mon, Oct 28, 2013 at 8:43 PM, Jaegeuk Kim <jaegeuk.kim@samsung.com> wrote:
> > Hi,
> >
> > 2013-10-26 (토), 00:01 +0800, Huajun Li:
> >> From: Huajun Li <huajun.li@intel.com>
> >>
> >> Functions to implement inline data read/write, and move inline data to
> >> normal data block when file size exceeds inline data limitation.
> >>
> >> Signed-off-by: Huajun Li <huajun.li@intel.com>
> >> Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
> >> Signed-off-by: Weihong Xu <weihong.xu@intel.com>
> >> ---
> >>  fs/f2fs/Makefile |    2 +-
> >>  fs/f2fs/f2fs.h   |    7 +++
> >>  fs/f2fs/inline.c |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 152 insertions(+), 1 deletion(-)
> >>  create mode 100644 fs/f2fs/inline.c
> >>
> >
> > [snip]
> >
> >> +static int __f2fs_convert_inline_data(struct inode *inode, struct page *page)
> >> +{
> >> +     int err;
> >> +     struct page *ipage;
> >> +     struct dnode_of_data dn;
> >> +     void *src_addr, *dst_addr;
> >> +     struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
> >> +
> >
> > Here..  f2fs_lock_op(sbi);
> >
> >> +     ipage = get_node_page(sbi, inode->i_ino);
> >> +     if (IS_ERR(ipage))
> >> +             return PTR_ERR(ipage);
> >> +
> >
> > Need to move f2fs_lock_op prior to get_node_page.
> >
> >> +     /* i_addr[0] is not used for inline data,
> >
> > Coding style.
> >          /*
> >           * ...
> >           */
> >
> >> +      * so reserving new block will not destroy inline data */
> >> +     err = f2fs_reserve_block(inode, &dn, 0);
> >> +     if (err) {
> >> +             f2fs_put_page(ipage, 1);
> >> +             f2fs_unlock_op(sbi);
> >> +             return err;
> >> +     }
> >
> > Need to move this too.
> >
> >> +
> >> +     src_addr = inline_data_addr(ipage);
> >> +     dst_addr = page_address(page);
> >> +     zero_user_segment(page, 0, PAGE_CACHE_SIZE);
> >
> > + space for readability.
> >
> >> +     /* Copy the whole inline data block */
> >> +     memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
> >> +     zero_user_segment(ipage, INLINE_DATA_OFFSET,
> >> +                              INLINE_DATA_OFFSET + MAX_INLINE_DATA);
> >> +     clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
> >> +     set_raw_inline(F2FS_I(inode),
> >> +                     (struct f2fs_inode *)page_address(ipage));
> 
> Thanks for your comments, I will update them according to above comments.
> 
> >
> >    --> sync_inode_page()?
> >
> IMO, we just handle file data, so do we still need call sync_inode_page() ?

I think sync_inode_page() is more suitable, since we need to sync
between i_size, i_blocks and its i_flag, inline_data, at this moment.

> 
> >> +
> >> +     set_page_dirty(ipage);

Need to consider skipping set_page_dirty(ipage).

> >> +     f2fs_put_page(ipage, 1);
> >> +     set_page_dirty(page);
> >
> > Here... f2fs_unlock_op(sbi);
> >
> > Here, we need to consider data consistency.
> > Let's think about the below scenario.
> > 1. inline_data was written.
> > 2. sync_fs is done.
> > 3. additional data were written.
> >   : this triggers f2fs_convert_inline_data(), produces a page, and then
> > unsets the inline flag.
> > 4. checkpoint was done with updated inode page. Note that, checkpoint
> > doesn't guarantee any user data.
> > 5. sudden power-off is occurred.
> >   -> Once power-off-recovery is done, we loose the inline_data which was
> > written successfully at step #2.
> >
> > So, I think we need to do f2fs_sync_file() procedure at this moment.
> > Any idea?
> >
> 
> Yes, need consider this case carefully, thanks for your reminder.
> 
> Considering sudden power-off may happen before f2fs_sync_file() is
> called, so how about following solutions:
>      ...
>      /* Copy the whole inline data block */
>      memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
> 
>     do f2fs_sync_file() procedure ( Or  do write_data_page() procedure ? )

Ya, but it may still have some conditions to do this or not.
One of them is checking whether previous inline data should be recovered
or not, for example.

> 
>      zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET +
> MAX_INLINE_DATA);
>      clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
>      set_raw_inline(F2FS_I(inode), (struct f2fs_inode *)page_address(ipage));
>      ...
> 
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +int f2fs_convert_inline_data(struct inode *inode,
> >> +                          struct page *p, unsigned flags)
> >> +{
> >> +     int err;
> >> +     struct page *page;
> >> +
> >> +     if (p && !p->index) {
> >> +             page = p;
> >> +     } else {
> >> +             page = grab_cache_page_write_begin(inode->i_mapping, 0, flags);
> >> +             if (IS_ERR(page))
> >> +                     return PTR_ERR(page);
> >> +     }
> >> +
> >> +     err = __f2fs_convert_inline_data(inode, page);
> >> +
> >> +     if (p && !p->index)
> >> +             f2fs_put_page(page, 1);
> >> +
> >> +     return err;
> >> +}
> >> +
> >> +int f2fs_write_inline_data(struct inode *inode,
> >> +                        struct page *page, unsigned size)
> >> +{
> >> +     void *src_addr, *dst_addr;
> >> +     struct page *ipage;
> >> +     struct dnode_of_data dn;
> >> +     int err;
> >> +
> >> +     set_new_dnode(&dn, inode, NULL, NULL, 0);
> >> +     err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
> >> +     if (err)
> >> +             return err;
> >> +     ipage = dn.inode_page;
> >> +
> >> +     src_addr = page_address(page);
> >> +     dst_addr = inline_data_addr(ipage);
> >> +
> >> +     zero_user_segment(ipage, INLINE_DATA_OFFSET,
> >> +                              INLINE_DATA_OFFSET + MAX_INLINE_DATA);
> >> +     memcpy(dst_addr, src_addr, size);
> >> +     if (!f2fs_has_inline_data(inode))
> >> +             set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
> >> +     set_raw_inline(F2FS_I(inode),
> >> +                     (struct f2fs_inode *)page_address(ipage));
> >> +     set_page_dirty(ipage);
> >> +
> >> +     if ((F2FS_I(inode)->i_xattr_nid && inode->i_blocks == 2) ||
> >> +             (!F2FS_I(inode)->i_xattr_nid && inode->i_blocks == 1)) {
> >> +             f2fs_put_dnode(&dn);
> >> +             return 0;
> >> +     }
> >> +
> >> +     /* Release the first data block if it is allocated */
> >> +     truncate_data_blocks_range(&dn, 1);
> >> +     f2fs_put_dnode(&dn);
> >> +
> >> +     return 0;
> >> +}
> >
> > --
> > Jaegeuk Kim
> > Samsung
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Jaegeuk Kim
Samsung



------------------------------------------------------------------------------
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951&iu=/4140/ostg.clktrk
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2013-10-29  1:07 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-25 16:01 [f2fs-dev 0/5] f2fs: Enable f2fs support inline data Huajun Li
2013-10-25 16:01 ` [f2fs-dev 1/5] f2fs: Add flags and helpers to " Huajun Li
2013-10-25 16:01 ` [f2fs-dev 2/5] f2fs: Add a new mount option: inline_data Huajun Li
2013-10-25 16:01 ` [f2fs-dev 3/5] f2fs: Add a new function: f2fs_reserve_block() Huajun Li
     [not found]   ` <1382962607.992.104.camel@kjgkr>
2013-10-28 12:28     ` Jaegeuk Kim
2013-10-28 16:53       ` Huajun Li
2013-10-29  0:56         ` Jaegeuk Kim
2013-10-29 15:27           ` Huajun Li
2013-10-25 16:01 ` [f2fs-dev 4/5] f2fs: Key functions to handle inline data Huajun Li
2013-10-28 12:43   ` Jaegeuk Kim
2013-10-28 17:20     ` Huajun Li
2013-10-29  1:06       ` Jaegeuk Kim [this message]
2013-10-29 15:33         ` Huajun Li
2013-10-25 16:01 ` [f2fs-dev 5/5] f2fs: Handle inline data operations Huajun Li
2013-10-28 12:44   ` Jaegeuk Kim
2013-10-28 16:56     ` Huajun Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1383008787.14041.8.camel@kjgkr \
    --to=jaegeuk.kim@samsung.com \
    --cc=huajun.li.lee@gmail.com \
    --cc=huajun.li@intel.com \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=weihong.xu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).