diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-11 17:29:06 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-23 14:10:17 -0400 |
commit | c52e1b10b175bef84f1681946b4a438cc4c84147 (patch) | |
tree | 8c316e124453a3b2b03eefa3d0cf36094f386bc8 | |
parent | 19c9c466e5c79402cbf8929f922011b02fbb59bd (diff) |
f2fs: remove redundant operation during roll-forward recovery
If same data is updated multiple times, we don't need to redo whole the
operations.
Let's just update the lastest one.
Reviewed-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/f2fs.h | 4 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 43 |
2 files changed, 22 insertions, 25 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index dbe5f939b7e7..3b70b0137191 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -137,7 +137,9 @@ struct discard_entry { | |||
137 | struct fsync_inode_entry { | 137 | struct fsync_inode_entry { |
138 | struct list_head list; /* list head */ | 138 | struct list_head list; /* list head */ |
139 | struct inode *inode; /* vfs inode pointer */ | 139 | struct inode *inode; /* vfs inode pointer */ |
140 | block_t blkaddr; /* block address locating the last inode */ | 140 | block_t blkaddr; /* block address locating the last fsync */ |
141 | block_t last_dentry; /* block address locating the last dentry */ | ||
142 | block_t last_inode; /* block address locating the last inode */ | ||
141 | }; | 143 | }; |
142 | 144 | ||
143 | #define nats_in_cursum(sum) (le16_to_cpu(sum->n_nats)) | 145 | #define nats_in_cursum(sum) (le16_to_cpu(sum->n_nats)) |
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 39832833c02f..39c4ff69990e 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -67,7 +67,7 @@ static struct fsync_inode_entry *get_fsync_inode(struct list_head *head, | |||
67 | return NULL; | 67 | return NULL; |
68 | } | 68 | } |
69 | 69 | ||
70 | static int recover_dentry(struct page *ipage, struct inode *inode) | 70 | static int recover_dentry(struct inode *inode, struct page *ipage) |
71 | { | 71 | { |
72 | struct f2fs_inode *raw_inode = F2FS_INODE(ipage); | 72 | struct f2fs_inode *raw_inode = F2FS_INODE(ipage); |
73 | nid_t pino = le32_to_cpu(raw_inode->i_pino); | 73 | nid_t pino = le32_to_cpu(raw_inode->i_pino); |
@@ -141,7 +141,7 @@ out: | |||
141 | return err; | 141 | return err; |
142 | } | 142 | } |
143 | 143 | ||
144 | static void __recover_inode(struct inode *inode, struct page *page) | 144 | static void recover_inode(struct inode *inode, struct page *page) |
145 | { | 145 | { |
146 | struct f2fs_inode *raw = F2FS_INODE(page); | 146 | struct f2fs_inode *raw = F2FS_INODE(page); |
147 | 147 | ||
@@ -153,21 +153,9 @@ static void __recover_inode(struct inode *inode, struct page *page) | |||
153 | inode->i_atime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); | 153 | inode->i_atime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); |
154 | inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec); | 154 | inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec); |
155 | inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); | 155 | inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); |
156 | } | ||
157 | |||
158 | static int recover_inode(struct inode *inode, struct page *node_page) | ||
159 | { | ||
160 | if (!IS_INODE(node_page)) | ||
161 | return 0; | ||
162 | |||
163 | __recover_inode(inode, node_page); | ||
164 | |||
165 | if (is_dent_dnode(node_page)) | ||
166 | return recover_dentry(node_page, inode); | ||
167 | 156 | ||
168 | f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode: ino = %x, name = %s", | 157 | f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode: ino = %x, name = %s", |
169 | ino_of_node(node_page), F2FS_INODE(node_page)->i_name); | 158 | ino_of_node(page), F2FS_INODE(page)->i_name); |
170 | return 0; | ||
171 | } | 159 | } |
172 | 160 | ||
173 | static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | 161 | static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) |
@@ -210,12 +198,11 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
210 | } | 198 | } |
211 | 199 | ||
212 | /* add this fsync inode to the list */ | 200 | /* add this fsync inode to the list */ |
213 | entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS); | 201 | entry = kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO); |
214 | if (!entry) { | 202 | if (!entry) { |
215 | err = -ENOMEM; | 203 | err = -ENOMEM; |
216 | break; | 204 | break; |
217 | } | 205 | } |
218 | |||
219 | /* | 206 | /* |
220 | * CP | dnode(F) | inode(DF) | 207 | * CP | dnode(F) | inode(DF) |
221 | * For this case, we should not give up now. | 208 | * For this case, we should not give up now. |
@@ -232,9 +219,11 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
232 | } | 219 | } |
233 | entry->blkaddr = blkaddr; | 220 | entry->blkaddr = blkaddr; |
234 | 221 | ||
235 | err = recover_inode(entry->inode, page); | 222 | if (IS_INODE(page)) { |
236 | if (err && err != -ENOENT) | 223 | entry->last_inode = blkaddr; |
237 | break; | 224 | if (is_dent_dnode(page)) |
225 | entry->last_dentry = blkaddr; | ||
226 | } | ||
238 | next: | 227 | next: |
239 | /* check next segment */ | 228 | /* check next segment */ |
240 | blkaddr = next_blkaddr_of_node(page); | 229 | blkaddr = next_blkaddr_of_node(page); |
@@ -462,11 +451,17 @@ static int recover_data(struct f2fs_sb_info *sbi, | |||
462 | /* | 451 | /* |
463 | * inode(x) | CP | inode(x) | dnode(F) | 452 | * inode(x) | CP | inode(x) | dnode(F) |
464 | * In this case, we can lose the latest inode(x). | 453 | * In this case, we can lose the latest inode(x). |
465 | * So, call __recover_inode for the inode update. | 454 | * So, call recover_inode for the inode update. |
466 | */ | 455 | */ |
467 | if (IS_INODE(page)) | 456 | if (entry->last_inode == blkaddr) |
468 | __recover_inode(entry->inode, page); | 457 | recover_inode(entry->inode, page); |
469 | 458 | if (entry->last_dentry == blkaddr) { | |
459 | err = recover_dentry(entry->inode, page); | ||
460 | if (err) { | ||
461 | f2fs_put_page(page, 1); | ||
462 | break; | ||
463 | } | ||
464 | } | ||
470 | err = do_recover_data(sbi, entry->inode, page, blkaddr); | 465 | err = do_recover_data(sbi, entry->inode, page, blkaddr); |
471 | if (err) { | 466 | if (err) { |
472 | f2fs_put_page(page, 1); | 467 | f2fs_put_page(page, 1); |