aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/recovery.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-03-08 07:29:23 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-03-20 05:30:06 -0400
commit393ff91f57c87d48ffed30878be6e3e486d3a00a (patch)
treec80fe33bcf8546ebce9ab6fc043b99889e67536f /fs/f2fs/recovery.c
parent25c0a6e529b56ca010e1f46239edd07c1b484b63 (diff)
f2fs: reduce unncessary locking pages during read
This patch reduces redundant locking and unlocking pages during read operations. In f2fs_readpage, let's use wait_on_page_locked() instead of lock_page. And then, when we need to modify any data finally, let's lock the page so that we can avoid lock contention. [readpage rule] - The f2fs_readpage returns unlocked page, or released page too in error cases. - Its caller should handle read error, -EIO, after locking the page, which indicates read completion. - Its caller should check PageUptodate after grab_cache_page. Signed-off-by: Changman Lee <cm224.lee@samsung.com> Reviewed-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/recovery.c')
-rw-r--r--fs/f2fs/recovery.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 6b82e2034cfd..2d86eb26c493 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -112,11 +112,16 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
112 while (1) { 112 while (1) {
113 struct fsync_inode_entry *entry; 113 struct fsync_inode_entry *entry;
114 114
115 if (f2fs_readpage(sbi, page, blkaddr, READ_SYNC)) 115 err = f2fs_readpage(sbi, page, blkaddr, READ_SYNC);
116 if (err)
116 goto out; 117 goto out;
117 118
118 if (cp_ver != cpver_of_node(page)) 119 lock_page(page);
119 goto out; 120
121 if (cp_ver != cpver_of_node(page)) {
122 err = -EINVAL;
123 goto unlock_out;
124 }
120 125
121 if (!is_fsync_dnode(page)) 126 if (!is_fsync_dnode(page))
122 goto next; 127 goto next;
@@ -131,7 +136,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
131 if (IS_INODE(page) && is_dent_dnode(page)) { 136 if (IS_INODE(page) && is_dent_dnode(page)) {
132 if (recover_inode_page(sbi, page)) { 137 if (recover_inode_page(sbi, page)) {
133 err = -ENOMEM; 138 err = -ENOMEM;
134 goto out; 139 goto unlock_out;
135 } 140 }
136 } 141 }
137 142
@@ -139,14 +144,14 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
139 entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS); 144 entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS);
140 if (!entry) { 145 if (!entry) {
141 err = -ENOMEM; 146 err = -ENOMEM;
142 goto out; 147 goto unlock_out;
143 } 148 }
144 149
145 entry->inode = f2fs_iget(sbi->sb, ino_of_node(page)); 150 entry->inode = f2fs_iget(sbi->sb, ino_of_node(page));
146 if (IS_ERR(entry->inode)) { 151 if (IS_ERR(entry->inode)) {
147 err = PTR_ERR(entry->inode); 152 err = PTR_ERR(entry->inode);
148 kmem_cache_free(fsync_entry_slab, entry); 153 kmem_cache_free(fsync_entry_slab, entry);
149 goto out; 154 goto unlock_out;
150 } 155 }
151 156
152 list_add_tail(&entry->list, head); 157 list_add_tail(&entry->list, head);
@@ -155,15 +160,15 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
155 if (IS_INODE(page)) { 160 if (IS_INODE(page)) {
156 err = recover_inode(entry->inode, page); 161 err = recover_inode(entry->inode, page);
157 if (err) 162 if (err)
158 goto out; 163 goto unlock_out;
159 } 164 }
160next: 165next:
161 /* check next segment */ 166 /* check next segment */
162 blkaddr = next_blkaddr_of_node(page); 167 blkaddr = next_blkaddr_of_node(page);
163 ClearPageUptodate(page);
164 } 168 }
165out: 169unlock_out:
166 unlock_page(page); 170 unlock_page(page);
171out:
167 __free_pages(page, 0); 172 __free_pages(page, 0);
168 return err; 173 return err;
169} 174}
@@ -319,8 +324,10 @@ static void recover_data(struct f2fs_sb_info *sbi,
319 if (f2fs_readpage(sbi, page, blkaddr, READ_SYNC)) 324 if (f2fs_readpage(sbi, page, blkaddr, READ_SYNC))
320 goto out; 325 goto out;
321 326
327 lock_page(page);
328
322 if (cp_ver != cpver_of_node(page)) 329 if (cp_ver != cpver_of_node(page))
323 goto out; 330 goto unlock_out;
324 331
325 entry = get_fsync_inode(head, ino_of_node(page)); 332 entry = get_fsync_inode(head, ino_of_node(page));
326 if (!entry) 333 if (!entry)
@@ -336,10 +343,10 @@ static void recover_data(struct f2fs_sb_info *sbi,
336next: 343next:
337 /* check next segment */ 344 /* check next segment */
338 blkaddr = next_blkaddr_of_node(page); 345 blkaddr = next_blkaddr_of_node(page);
339 ClearPageUptodate(page);
340 } 346 }
341out: 347unlock_out:
342 unlock_page(page); 348 unlock_page(page);
349out:
343 __free_pages(page, 0); 350 __free_pages(page, 0);
344 351
345 allocate_new_segments(sbi); 352 allocate_new_segments(sbi);