On 12/15, heyunlei wrote:
>
>
> >-----Original Message-----
> >From: Jaegeuk Kim [mailto:[email protected]]
> >Sent: Friday, December 15, 2017 3:46 AM
> >To: heyunlei
> >Cc: Yuchao (T); [email protected]; Wangbintian; Jianing
> >(Euler)
> >Subject: Re: [f2fs-dev][PATCH RFC] f2fs: fix an error case of missing update
> >inode page
> >
> >On 12/05, Yunlei He wrote:
> >> -Thread A Thread B
> >>
> >> -write_checkpoint
> >> -block_operations
> >> -f2fs_unlock_all -f2fs_sync_file
> >> -f2fs_write_inode
> >>
> >> -f2fs_inode_synced
> >>
> >> -f2fs_sync_inode_meta
> >> -sync_node_pages
> >>
> >> -set_page_drity
> >>
> >> In this case, if sudden power off without next new checkpoint,
> >> the last inode page update will lost. wb_writeback is same with
> >> fsync.
> >
> >Does this patch fix the problem?
> >
> I modify code as below:
> @@ -366,7 +366,7 @@ int update_inode(struct inode *inode, struct page
> *node_page)
> struct extent_tree *et = F2FS_I(inode)->extent_tree;
>
> f2fs_inode_synced(inode);
> -
> + msleep(10000);
> f2fs_wait_on_page_writeback(node_page, NODE, true);
>
> shell 1: shell2:
> dd if=/dev/zero of=./test bs=1M count=10
> sync
> echo "hello" >> ./test
> fsync test // sleep 10s
> sync //return quickly
>
> echo c > /proc/sysrq-trigger //before fsync return
> fsck will find iblocks mismatch, and with this patch it 's ok.
So, do you mean it was fixed by adding msleep() on top of this patch as well?
Like:
- f2fs_write_inode()
- set_page_drity
- f2fs_inode_synced
- msleep(10000);
>
> Besides,I came across another error like this:
>
> f2fs_inode-> i_xattr_nid is non-zero, but node blkaddr in raw nat entry is
> NULL.
>
> This case makes sense to this problem also.
>
> > -write_checkpoint
> > -block_operations
> > -f2fs_unlock_all -f2fs_sync_file
> > -f2fs_write_inode
> > -set_page_drity
> >
> > -f2fs_inode_synced
> > -f2fs_sync_inode_meta
> > -sync_node_pages
> >
> >I think, we need to cover f2fs_lock_op() for f2fs_write_inode() again.
>
> It can also work well with f2fs_lock_op(), I am afraid other cases will
> update inode
> like f2fs_write_inode without f2fs_lock_op
>
> Thanks
> >
> >Thanks,
> >
> >>
> >> Signed-off-by: Yunlei He <[email protected]>
> >> ---
> >> fs/f2fs/f2fs.h | 4 ++--
> >> fs/f2fs/inode.c | 15 +++++++--------
> >> 2 files changed, 9 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >> index 82f1dc3..38f9324 100644
> >> --- a/fs/f2fs/f2fs.h
> >> +++ b/fs/f2fs/f2fs.h
> >> @@ -2513,8 +2513,8 @@ int f2fs_getattr(const struct path *path, struct
> >> kstat *stat,
> >> struct inode *f2fs_iget(struct super_block *sb, unsigned long ino);
> >> struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino);
> >> int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink);
> >> -int update_inode(struct inode *inode, struct page *node_page);
> >> -int update_inode_page(struct inode *inode);
> >> +void update_inode(struct inode *inode, struct page *node_page);
> >> +void update_inode_page(struct inode *inode);
> >> int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc);
> >> void f2fs_evict_inode(struct inode *inode);
> >> void handle_failed_inode(struct inode *inode);
> >> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> >> index b4c4f2b..10d3c7c 100644
> >> --- a/fs/f2fs/inode.c
> >> +++ b/fs/f2fs/inode.c
> >> @@ -360,14 +360,15 @@ struct inode *f2fs_iget_retry(struct super_block
> >> *sb, unsigned long ino)
> >> return inode;
> >> }
> >>
> >> -int update_inode(struct inode *inode, struct page *node_page)
> >> +void update_inode(struct inode *inode, struct page *node_page)
> >> {
> >> struct f2fs_inode *ri;
> >> struct extent_tree *et = F2FS_I(inode)->extent_tree;
> >>
> >> - f2fs_inode_synced(inode);
> >> -
> >> f2fs_wait_on_page_writeback(node_page, NODE, true);
> >> + set_page_dirty(node_page);
> >> +
> >> + f2fs_inode_synced(inode);
> >>
> >> ri = F2FS_INODE(node_page);
> >>
> >> @@ -426,10 +427,9 @@ int update_inode(struct inode *inode, struct page
> >> *node_page)
> >> if (inode->i_nlink == 0)
> >> clear_inline_node(node_page);
> >>
> >> - return set_page_dirty(node_page);
> >> }
> >>
> >> -int update_inode_page(struct inode *inode)
> >> +void update_inode_page(struct inode *inode)
> >> {
> >> struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> >> struct page *node_page;
> >> @@ -444,11 +444,10 @@ int update_inode_page(struct inode *inode)
> >> } else if (err != -ENOENT) {
> >> f2fs_stop_checkpoint(sbi, false);
> >> }
> >> - return 0;
> >> + return;
> >> }
> >> - ret = update_inode(inode, node_page);
> >> + update_inode(inode, node_page);
> >> f2fs_put_page(node_page, 1);
> >> - return ret;
> >> }
> >>
> >> int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
> >> --
> >> 1.9.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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel