diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-05-20 10:10:29 +0900 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-05-28 15:03:02 +0900 |
commit | 44a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1 (patch) | |
tree | 8b7c8b192d237ee774c0f1ab59f3a0007e463655 /fs/f2fs/node.c | |
parent | 64aa7ed98db489d1c41ef140876ada38498678ab (diff) |
f2fs: update inode page after creation
I found a bug when testing power-off-recovery as follows.
[Bug Scenario]
1. create a file
2. fsync the file
3. reboot w/o any sync
4. try to recover the file
- found its fsync mark
- found its dentry mark
: try to recover its dentry
- get its file name
- get its parent inode number
: here we got zero value
The reason why we get the wrong parent inode number is that we didn't
synchronize the inode page with its newly created inode information perfectly.
Especially, previous f2fs stores fi->i_pino and writes it to the cached
node page in a wrong order, which incurs the zero-valued i_pino during the
recovery.
So, this patch modifies the creation flow to fix the synchronization order of
inode page with its inode.
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r-- | fs/f2fs/node.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index f63f0a4046c..b41482de492 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -806,19 +806,15 @@ int remove_inode_page(struct inode *inode) return 0; } -int new_inode_page(struct inode *inode, const struct qstr *name) +struct page *new_inode_page(struct inode *inode, const struct qstr *name) { - struct page *page; struct dnode_of_data dn; /* allocate inode page for new inode */ set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); - page = new_node_page(&dn, 0); - init_dent_inode(name, page); - if (IS_ERR(page)) - return PTR_ERR(page); - f2fs_put_page(page, 1); - return 0; + + /* caller should f2fs_put_page(page, 1); */ + return new_node_page(&dn, 0); } struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) |