diff options
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r-- | fs/f2fs/node.c | 223 |
1 files changed, 156 insertions, 67 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 342597a5897f..118321bd1a7f 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -257,15 +257,20 @@ static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid) | |||
257 | return new; | 257 | return new; |
258 | } | 258 | } |
259 | 259 | ||
260 | static void cache_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid, | 260 | static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, |
261 | struct f2fs_nat_entry *ne) | 261 | struct f2fs_nat_entry *ne) |
262 | { | 262 | { |
263 | struct f2fs_nm_info *nm_i = NM_I(sbi); | ||
263 | struct nat_entry *e; | 264 | struct nat_entry *e; |
264 | 265 | ||
265 | e = __lookup_nat_cache(nm_i, nid); | 266 | e = __lookup_nat_cache(nm_i, nid); |
266 | if (!e) { | 267 | if (!e) { |
267 | e = grab_nat_entry(nm_i, nid); | 268 | e = grab_nat_entry(nm_i, nid); |
268 | node_info_from_raw_nat(&e->ni, ne); | 269 | node_info_from_raw_nat(&e->ni, ne); |
270 | } else { | ||
271 | f2fs_bug_on(sbi, nat_get_ino(e) != ne->ino || | ||
272 | nat_get_blkaddr(e) != ne->block_addr || | ||
273 | nat_get_version(e) != ne->version); | ||
269 | } | 274 | } |
270 | } | 275 | } |
271 | 276 | ||
@@ -354,7 +359,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) | |||
354 | { | 359 | { |
355 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 360 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
356 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 361 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
357 | struct f2fs_summary_block *sum = curseg->sum_blk; | 362 | struct f2fs_journal *journal = curseg->journal; |
358 | nid_t start_nid = START_NID(nid); | 363 | nid_t start_nid = START_NID(nid); |
359 | struct f2fs_nat_block *nat_blk; | 364 | struct f2fs_nat_block *nat_blk; |
360 | struct page *page = NULL; | 365 | struct page *page = NULL; |
@@ -371,23 +376,20 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) | |||
371 | ni->ino = nat_get_ino(e); | 376 | ni->ino = nat_get_ino(e); |
372 | ni->blk_addr = nat_get_blkaddr(e); | 377 | ni->blk_addr = nat_get_blkaddr(e); |
373 | ni->version = nat_get_version(e); | 378 | ni->version = nat_get_version(e); |
374 | } | 379 | up_read(&nm_i->nat_tree_lock); |
375 | up_read(&nm_i->nat_tree_lock); | ||
376 | if (e) | ||
377 | return; | 380 | return; |
381 | } | ||
378 | 382 | ||
379 | memset(&ne, 0, sizeof(struct f2fs_nat_entry)); | 383 | memset(&ne, 0, sizeof(struct f2fs_nat_entry)); |
380 | 384 | ||
381 | down_write(&nm_i->nat_tree_lock); | ||
382 | |||
383 | /* Check current segment summary */ | 385 | /* Check current segment summary */ |
384 | mutex_lock(&curseg->curseg_mutex); | 386 | down_read(&curseg->journal_rwsem); |
385 | i = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 0); | 387 | i = lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0); |
386 | if (i >= 0) { | 388 | if (i >= 0) { |
387 | ne = nat_in_journal(sum, i); | 389 | ne = nat_in_journal(journal, i); |
388 | node_info_from_raw_nat(ni, &ne); | 390 | node_info_from_raw_nat(ni, &ne); |
389 | } | 391 | } |
390 | mutex_unlock(&curseg->curseg_mutex); | 392 | up_read(&curseg->journal_rwsem); |
391 | if (i >= 0) | 393 | if (i >= 0) |
392 | goto cache; | 394 | goto cache; |
393 | 395 | ||
@@ -398,19 +400,52 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) | |||
398 | node_info_from_raw_nat(ni, &ne); | 400 | node_info_from_raw_nat(ni, &ne); |
399 | f2fs_put_page(page, 1); | 401 | f2fs_put_page(page, 1); |
400 | cache: | 402 | cache: |
403 | up_read(&nm_i->nat_tree_lock); | ||
401 | /* cache nat entry */ | 404 | /* cache nat entry */ |
402 | cache_nat_entry(NM_I(sbi), nid, &ne); | 405 | down_write(&nm_i->nat_tree_lock); |
406 | cache_nat_entry(sbi, nid, &ne); | ||
403 | up_write(&nm_i->nat_tree_lock); | 407 | up_write(&nm_i->nat_tree_lock); |
404 | } | 408 | } |
405 | 409 | ||
410 | pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) | ||
411 | { | ||
412 | const long direct_index = ADDRS_PER_INODE(dn->inode); | ||
413 | const long direct_blks = ADDRS_PER_BLOCK; | ||
414 | const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; | ||
415 | unsigned int skipped_unit = ADDRS_PER_BLOCK; | ||
416 | int cur_level = dn->cur_level; | ||
417 | int max_level = dn->max_level; | ||
418 | pgoff_t base = 0; | ||
419 | |||
420 | if (!dn->max_level) | ||
421 | return pgofs + 1; | ||
422 | |||
423 | while (max_level-- > cur_level) | ||
424 | skipped_unit *= NIDS_PER_BLOCK; | ||
425 | |||
426 | switch (dn->max_level) { | ||
427 | case 3: | ||
428 | base += 2 * indirect_blks; | ||
429 | case 2: | ||
430 | base += 2 * direct_blks; | ||
431 | case 1: | ||
432 | base += direct_index; | ||
433 | break; | ||
434 | default: | ||
435 | f2fs_bug_on(F2FS_I_SB(dn->inode), 1); | ||
436 | } | ||
437 | |||
438 | return ((pgofs - base) / skipped_unit + 1) * skipped_unit + base; | ||
439 | } | ||
440 | |||
406 | /* | 441 | /* |
407 | * The maximum depth is four. | 442 | * The maximum depth is four. |
408 | * Offset[0] will have raw inode offset. | 443 | * Offset[0] will have raw inode offset. |
409 | */ | 444 | */ |
410 | static int get_node_path(struct f2fs_inode_info *fi, long block, | 445 | static int get_node_path(struct inode *inode, long block, |
411 | int offset[4], unsigned int noffset[4]) | 446 | int offset[4], unsigned int noffset[4]) |
412 | { | 447 | { |
413 | const long direct_index = ADDRS_PER_INODE(fi); | 448 | const long direct_index = ADDRS_PER_INODE(inode); |
414 | const long direct_blks = ADDRS_PER_BLOCK; | 449 | const long direct_blks = ADDRS_PER_BLOCK; |
415 | const long dptrs_per_blk = NIDS_PER_BLOCK; | 450 | const long dptrs_per_blk = NIDS_PER_BLOCK; |
416 | const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; | 451 | const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; |
@@ -495,10 +530,10 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) | |||
495 | int offset[4]; | 530 | int offset[4]; |
496 | unsigned int noffset[4]; | 531 | unsigned int noffset[4]; |
497 | nid_t nids[4]; | 532 | nid_t nids[4]; |
498 | int level, i; | 533 | int level, i = 0; |
499 | int err = 0; | 534 | int err = 0; |
500 | 535 | ||
501 | level = get_node_path(F2FS_I(dn->inode), index, offset, noffset); | 536 | level = get_node_path(dn->inode, index, offset, noffset); |
502 | 537 | ||
503 | nids[0] = dn->inode->i_ino; | 538 | nids[0] = dn->inode->i_ino; |
504 | npage[0] = dn->inode_page; | 539 | npage[0] = dn->inode_page; |
@@ -585,6 +620,10 @@ release_pages: | |||
585 | release_out: | 620 | release_out: |
586 | dn->inode_page = NULL; | 621 | dn->inode_page = NULL; |
587 | dn->node_page = NULL; | 622 | dn->node_page = NULL; |
623 | if (err == -ENOENT) { | ||
624 | dn->cur_level = i; | ||
625 | dn->max_level = level; | ||
626 | } | ||
588 | return err; | 627 | return err; |
589 | } | 628 | } |
590 | 629 | ||
@@ -792,7 +831,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) | |||
792 | 831 | ||
793 | trace_f2fs_truncate_inode_blocks_enter(inode, from); | 832 | trace_f2fs_truncate_inode_blocks_enter(inode, from); |
794 | 833 | ||
795 | level = get_node_path(F2FS_I(inode), from, offset, noffset); | 834 | level = get_node_path(inode, from, offset, noffset); |
796 | restart: | 835 | restart: |
797 | page = get_node_page(sbi, inode->i_ino); | 836 | page = get_node_page(sbi, inode->i_ino); |
798 | if (IS_ERR(page)) { | 837 | if (IS_ERR(page)) { |
@@ -861,7 +900,7 @@ skip_partial: | |||
861 | f2fs_put_page(page, 1); | 900 | f2fs_put_page(page, 1); |
862 | goto restart; | 901 | goto restart; |
863 | } | 902 | } |
864 | f2fs_wait_on_page_writeback(page, NODE); | 903 | f2fs_wait_on_page_writeback(page, NODE, true); |
865 | ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0; | 904 | ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0; |
866 | set_page_dirty(page); | 905 | set_page_dirty(page); |
867 | unlock_page(page); | 906 | unlock_page(page); |
@@ -976,7 +1015,7 @@ struct page *new_node_page(struct dnode_of_data *dn, | |||
976 | new_ni.ino = dn->inode->i_ino; | 1015 | new_ni.ino = dn->inode->i_ino; |
977 | set_node_addr(sbi, &new_ni, NEW_ADDR, false); | 1016 | set_node_addr(sbi, &new_ni, NEW_ADDR, false); |
978 | 1017 | ||
979 | f2fs_wait_on_page_writeback(page, NODE); | 1018 | f2fs_wait_on_page_writeback(page, NODE, true); |
980 | fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); | 1019 | fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); |
981 | set_cold_node(dn->inode, page); | 1020 | set_cold_node(dn->inode, page); |
982 | SetPageUptodate(page); | 1021 | SetPageUptodate(page); |
@@ -1029,7 +1068,7 @@ static int read_node_page(struct page *page, int rw) | |||
1029 | if (PageUptodate(page)) | 1068 | if (PageUptodate(page)) |
1030 | return LOCKED_PAGE; | 1069 | return LOCKED_PAGE; |
1031 | 1070 | ||
1032 | fio.blk_addr = ni.blk_addr; | 1071 | fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr; |
1033 | return f2fs_submit_page_bio(&fio); | 1072 | return f2fs_submit_page_bio(&fio); |
1034 | } | 1073 | } |
1035 | 1074 | ||
@@ -1045,12 +1084,11 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) | |||
1045 | return; | 1084 | return; |
1046 | f2fs_bug_on(sbi, check_nid_range(sbi, nid)); | 1085 | f2fs_bug_on(sbi, check_nid_range(sbi, nid)); |
1047 | 1086 | ||
1048 | apage = find_get_page(NODE_MAPPING(sbi), nid); | 1087 | rcu_read_lock(); |
1049 | if (apage && PageUptodate(apage)) { | 1088 | apage = radix_tree_lookup(&NODE_MAPPING(sbi)->page_tree, nid); |
1050 | f2fs_put_page(apage, 0); | 1089 | rcu_read_unlock(); |
1090 | if (apage) | ||
1051 | return; | 1091 | return; |
1052 | } | ||
1053 | f2fs_put_page(apage, 0); | ||
1054 | 1092 | ||
1055 | apage = grab_cache_page(NODE_MAPPING(sbi), nid); | 1093 | apage = grab_cache_page(NODE_MAPPING(sbi), nid); |
1056 | if (!apage) | 1094 | if (!apage) |
@@ -1063,7 +1101,7 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) | |||
1063 | /* | 1101 | /* |
1064 | * readahead MAX_RA_NODE number of node pages. | 1102 | * readahead MAX_RA_NODE number of node pages. |
1065 | */ | 1103 | */ |
1066 | void ra_node_pages(struct page *parent, int start) | 1104 | static void ra_node_pages(struct page *parent, int start) |
1067 | { | 1105 | { |
1068 | struct f2fs_sb_info *sbi = F2FS_P_SB(parent); | 1106 | struct f2fs_sb_info *sbi = F2FS_P_SB(parent); |
1069 | struct blk_plug plug; | 1107 | struct blk_plug plug; |
@@ -1083,7 +1121,7 @@ void ra_node_pages(struct page *parent, int start) | |||
1083 | blk_finish_plug(&plug); | 1121 | blk_finish_plug(&plug); |
1084 | } | 1122 | } |
1085 | 1123 | ||
1086 | struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, | 1124 | static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, |
1087 | struct page *parent, int start) | 1125 | struct page *parent, int start) |
1088 | { | 1126 | { |
1089 | struct page *page; | 1127 | struct page *page; |
@@ -1154,19 +1192,57 @@ void sync_inode_page(struct dnode_of_data *dn) | |||
1154 | dn->node_changed = ret ? true: false; | 1192 | dn->node_changed = ret ? true: false; |
1155 | } | 1193 | } |
1156 | 1194 | ||
1195 | static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino) | ||
1196 | { | ||
1197 | struct inode *inode; | ||
1198 | struct page *page; | ||
1199 | |||
1200 | /* should flush inline_data before evict_inode */ | ||
1201 | inode = ilookup(sbi->sb, ino); | ||
1202 | if (!inode) | ||
1203 | return; | ||
1204 | |||
1205 | page = pagecache_get_page(inode->i_mapping, 0, FGP_NOWAIT, 0); | ||
1206 | if (!page) | ||
1207 | goto iput_out; | ||
1208 | |||
1209 | if (!trylock_page(page)) | ||
1210 | goto release_out; | ||
1211 | |||
1212 | if (!PageUptodate(page)) | ||
1213 | goto page_out; | ||
1214 | |||
1215 | if (!PageDirty(page)) | ||
1216 | goto page_out; | ||
1217 | |||
1218 | if (!clear_page_dirty_for_io(page)) | ||
1219 | goto page_out; | ||
1220 | |||
1221 | if (!f2fs_write_inline_data(inode, page)) | ||
1222 | inode_dec_dirty_pages(inode); | ||
1223 | else | ||
1224 | set_page_dirty(page); | ||
1225 | page_out: | ||
1226 | unlock_page(page); | ||
1227 | release_out: | ||
1228 | f2fs_put_page(page, 0); | ||
1229 | iput_out: | ||
1230 | iput(inode); | ||
1231 | } | ||
1232 | |||
1157 | int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, | 1233 | int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, |
1158 | struct writeback_control *wbc) | 1234 | struct writeback_control *wbc) |
1159 | { | 1235 | { |
1160 | pgoff_t index, end; | 1236 | pgoff_t index, end; |
1161 | struct pagevec pvec; | 1237 | struct pagevec pvec; |
1162 | int step = ino ? 2 : 0; | 1238 | int step = ino ? 2 : 0; |
1163 | int nwritten = 0, wrote = 0; | 1239 | int nwritten = 0; |
1164 | 1240 | ||
1165 | pagevec_init(&pvec, 0); | 1241 | pagevec_init(&pvec, 0); |
1166 | 1242 | ||
1167 | next_step: | 1243 | next_step: |
1168 | index = 0; | 1244 | index = 0; |
1169 | end = LONG_MAX; | 1245 | end = ULONG_MAX; |
1170 | 1246 | ||
1171 | while (index <= end) { | 1247 | while (index <= end) { |
1172 | int i, nr_pages; | 1248 | int i, nr_pages; |
@@ -1203,6 +1279,7 @@ next_step: | |||
1203 | * If an fsync mode, | 1279 | * If an fsync mode, |
1204 | * we should not skip writing node pages. | 1280 | * we should not skip writing node pages. |
1205 | */ | 1281 | */ |
1282 | lock_node: | ||
1206 | if (ino && ino_of_node(page) == ino) | 1283 | if (ino && ino_of_node(page) == ino) |
1207 | lock_page(page); | 1284 | lock_page(page); |
1208 | else if (!trylock_page(page)) | 1285 | else if (!trylock_page(page)) |
@@ -1221,6 +1298,17 @@ continue_unlock: | |||
1221 | goto continue_unlock; | 1298 | goto continue_unlock; |
1222 | } | 1299 | } |
1223 | 1300 | ||
1301 | /* flush inline_data */ | ||
1302 | if (!ino && is_inline_node(page)) { | ||
1303 | clear_inline_node(page); | ||
1304 | unlock_page(page); | ||
1305 | flush_inline_data(sbi, ino_of_node(page)); | ||
1306 | goto lock_node; | ||
1307 | } | ||
1308 | |||
1309 | f2fs_wait_on_page_writeback(page, NODE, true); | ||
1310 | |||
1311 | BUG_ON(PageWriteback(page)); | ||
1224 | if (!clear_page_dirty_for_io(page)) | 1312 | if (!clear_page_dirty_for_io(page)) |
1225 | goto continue_unlock; | 1313 | goto continue_unlock; |
1226 | 1314 | ||
@@ -1238,8 +1326,6 @@ continue_unlock: | |||
1238 | 1326 | ||
1239 | if (NODE_MAPPING(sbi)->a_ops->writepage(page, wbc)) | 1327 | if (NODE_MAPPING(sbi)->a_ops->writepage(page, wbc)) |
1240 | unlock_page(page); | 1328 | unlock_page(page); |
1241 | else | ||
1242 | wrote++; | ||
1243 | 1329 | ||
1244 | if (--wbc->nr_to_write == 0) | 1330 | if (--wbc->nr_to_write == 0) |
1245 | break; | 1331 | break; |
@@ -1257,15 +1343,12 @@ continue_unlock: | |||
1257 | step++; | 1343 | step++; |
1258 | goto next_step; | 1344 | goto next_step; |
1259 | } | 1345 | } |
1260 | |||
1261 | if (wrote) | ||
1262 | f2fs_submit_merged_bio(sbi, NODE, WRITE); | ||
1263 | return nwritten; | 1346 | return nwritten; |
1264 | } | 1347 | } |
1265 | 1348 | ||
1266 | int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino) | 1349 | int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino) |
1267 | { | 1350 | { |
1268 | pgoff_t index = 0, end = LONG_MAX; | 1351 | pgoff_t index = 0, end = ULONG_MAX; |
1269 | struct pagevec pvec; | 1352 | struct pagevec pvec; |
1270 | int ret2 = 0, ret = 0; | 1353 | int ret2 = 0, ret = 0; |
1271 | 1354 | ||
@@ -1287,7 +1370,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino) | |||
1287 | continue; | 1370 | continue; |
1288 | 1371 | ||
1289 | if (ino && ino_of_node(page) == ino) { | 1372 | if (ino && ino_of_node(page) == ino) { |
1290 | f2fs_wait_on_page_writeback(page, NODE); | 1373 | f2fs_wait_on_page_writeback(page, NODE, true); |
1291 | if (TestClearPageError(page)) | 1374 | if (TestClearPageError(page)) |
1292 | ret = -EIO; | 1375 | ret = -EIO; |
1293 | } | 1376 | } |
@@ -1326,8 +1409,6 @@ static int f2fs_write_node_page(struct page *page, | |||
1326 | if (unlikely(f2fs_cp_error(sbi))) | 1409 | if (unlikely(f2fs_cp_error(sbi))) |
1327 | goto redirty_out; | 1410 | goto redirty_out; |
1328 | 1411 | ||
1329 | f2fs_wait_on_page_writeback(page, NODE); | ||
1330 | |||
1331 | /* get old block addr of this node page */ | 1412 | /* get old block addr of this node page */ |
1332 | nid = nid_of_node(page); | 1413 | nid = nid_of_node(page); |
1333 | f2fs_bug_on(sbi, page->index != nid); | 1414 | f2fs_bug_on(sbi, page->index != nid); |
@@ -1351,14 +1432,18 @@ static int f2fs_write_node_page(struct page *page, | |||
1351 | } | 1432 | } |
1352 | 1433 | ||
1353 | set_page_writeback(page); | 1434 | set_page_writeback(page); |
1354 | fio.blk_addr = ni.blk_addr; | 1435 | fio.old_blkaddr = ni.blk_addr; |
1355 | write_node_page(nid, &fio); | 1436 | write_node_page(nid, &fio); |
1356 | set_node_addr(sbi, &ni, fio.blk_addr, is_fsync_dnode(page)); | 1437 | set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page)); |
1357 | dec_page_count(sbi, F2FS_DIRTY_NODES); | 1438 | dec_page_count(sbi, F2FS_DIRTY_NODES); |
1358 | up_read(&sbi->node_write); | 1439 | up_read(&sbi->node_write); |
1440 | |||
1441 | if (wbc->for_reclaim) | ||
1442 | f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, NODE, WRITE); | ||
1443 | |||
1359 | unlock_page(page); | 1444 | unlock_page(page); |
1360 | 1445 | ||
1361 | if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi))) | 1446 | if (unlikely(f2fs_cp_error(sbi))) |
1362 | f2fs_submit_merged_bio(sbi, NODE, WRITE); | 1447 | f2fs_submit_merged_bio(sbi, NODE, WRITE); |
1363 | 1448 | ||
1364 | return 0; | 1449 | return 0; |
@@ -1374,8 +1459,6 @@ static int f2fs_write_node_pages(struct address_space *mapping, | |||
1374 | struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); | 1459 | struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); |
1375 | long diff; | 1460 | long diff; |
1376 | 1461 | ||
1377 | trace_f2fs_writepages(mapping->host, wbc, NODE); | ||
1378 | |||
1379 | /* balancing f2fs's metadata in background */ | 1462 | /* balancing f2fs's metadata in background */ |
1380 | f2fs_balance_fs_bg(sbi); | 1463 | f2fs_balance_fs_bg(sbi); |
1381 | 1464 | ||
@@ -1383,6 +1466,8 @@ static int f2fs_write_node_pages(struct address_space *mapping, | |||
1383 | if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE)) | 1466 | if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE)) |
1384 | goto skip_write; | 1467 | goto skip_write; |
1385 | 1468 | ||
1469 | trace_f2fs_writepages(mapping->host, wbc, NODE); | ||
1470 | |||
1386 | diff = nr_pages_to_write(sbi, NODE, wbc); | 1471 | diff = nr_pages_to_write(sbi, NODE, wbc); |
1387 | wbc->sync_mode = WB_SYNC_NONE; | 1472 | wbc->sync_mode = WB_SYNC_NONE; |
1388 | sync_node_pages(sbi, 0, wbc); | 1473 | sync_node_pages(sbi, 0, wbc); |
@@ -1391,6 +1476,7 @@ static int f2fs_write_node_pages(struct address_space *mapping, | |||
1391 | 1476 | ||
1392 | skip_write: | 1477 | skip_write: |
1393 | wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_NODES); | 1478 | wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_NODES); |
1479 | trace_f2fs_writepages(mapping->host, wbc, NODE); | ||
1394 | return 0; | 1480 | return 0; |
1395 | } | 1481 | } |
1396 | 1482 | ||
@@ -1526,7 +1612,7 @@ static void build_free_nids(struct f2fs_sb_info *sbi) | |||
1526 | { | 1612 | { |
1527 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1613 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1528 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 1614 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
1529 | struct f2fs_summary_block *sum = curseg->sum_blk; | 1615 | struct f2fs_journal *journal = curseg->journal; |
1530 | int i = 0; | 1616 | int i = 0; |
1531 | nid_t nid = nm_i->next_scan_nid; | 1617 | nid_t nid = nm_i->next_scan_nid; |
1532 | 1618 | ||
@@ -1558,16 +1644,18 @@ static void build_free_nids(struct f2fs_sb_info *sbi) | |||
1558 | nm_i->next_scan_nid = nid; | 1644 | nm_i->next_scan_nid = nid; |
1559 | 1645 | ||
1560 | /* find free nids from current sum_pages */ | 1646 | /* find free nids from current sum_pages */ |
1561 | mutex_lock(&curseg->curseg_mutex); | 1647 | down_read(&curseg->journal_rwsem); |
1562 | for (i = 0; i < nats_in_cursum(sum); i++) { | 1648 | for (i = 0; i < nats_in_cursum(journal); i++) { |
1563 | block_t addr = le32_to_cpu(nat_in_journal(sum, i).block_addr); | 1649 | block_t addr; |
1564 | nid = le32_to_cpu(nid_in_journal(sum, i)); | 1650 | |
1651 | addr = le32_to_cpu(nat_in_journal(journal, i).block_addr); | ||
1652 | nid = le32_to_cpu(nid_in_journal(journal, i)); | ||
1565 | if (addr == NULL_ADDR) | 1653 | if (addr == NULL_ADDR) |
1566 | add_free_nid(sbi, nid, true); | 1654 | add_free_nid(sbi, nid, true); |
1567 | else | 1655 | else |
1568 | remove_free_nid(nm_i, nid); | 1656 | remove_free_nid(nm_i, nid); |
1569 | } | 1657 | } |
1570 | mutex_unlock(&curseg->curseg_mutex); | 1658 | up_read(&curseg->journal_rwsem); |
1571 | up_read(&nm_i->nat_tree_lock); | 1659 | up_read(&nm_i->nat_tree_lock); |
1572 | 1660 | ||
1573 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), | 1661 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), |
@@ -1703,7 +1791,7 @@ void recover_inline_xattr(struct inode *inode, struct page *page) | |||
1703 | src_addr = inline_xattr_addr(page); | 1791 | src_addr = inline_xattr_addr(page); |
1704 | inline_size = inline_xattr_size(inode); | 1792 | inline_size = inline_xattr_size(inode); |
1705 | 1793 | ||
1706 | f2fs_wait_on_page_writeback(ipage, NODE); | 1794 | f2fs_wait_on_page_writeback(ipage, NODE, true); |
1707 | memcpy(dst_addr, src_addr, inline_size); | 1795 | memcpy(dst_addr, src_addr, inline_size); |
1708 | update_inode: | 1796 | update_inode: |
1709 | update_inode(inode, ipage); | 1797 | update_inode(inode, ipage); |
@@ -1831,16 +1919,16 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi) | |||
1831 | { | 1919 | { |
1832 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1920 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1833 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 1921 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
1834 | struct f2fs_summary_block *sum = curseg->sum_blk; | 1922 | struct f2fs_journal *journal = curseg->journal; |
1835 | int i; | 1923 | int i; |
1836 | 1924 | ||
1837 | mutex_lock(&curseg->curseg_mutex); | 1925 | down_write(&curseg->journal_rwsem); |
1838 | for (i = 0; i < nats_in_cursum(sum); i++) { | 1926 | for (i = 0; i < nats_in_cursum(journal); i++) { |
1839 | struct nat_entry *ne; | 1927 | struct nat_entry *ne; |
1840 | struct f2fs_nat_entry raw_ne; | 1928 | struct f2fs_nat_entry raw_ne; |
1841 | nid_t nid = le32_to_cpu(nid_in_journal(sum, i)); | 1929 | nid_t nid = le32_to_cpu(nid_in_journal(journal, i)); |
1842 | 1930 | ||
1843 | raw_ne = nat_in_journal(sum, i); | 1931 | raw_ne = nat_in_journal(journal, i); |
1844 | 1932 | ||
1845 | ne = __lookup_nat_cache(nm_i, nid); | 1933 | ne = __lookup_nat_cache(nm_i, nid); |
1846 | if (!ne) { | 1934 | if (!ne) { |
@@ -1849,8 +1937,8 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi) | |||
1849 | } | 1937 | } |
1850 | __set_nat_cache_dirty(nm_i, ne); | 1938 | __set_nat_cache_dirty(nm_i, ne); |
1851 | } | 1939 | } |
1852 | update_nats_in_cursum(sum, -i); | 1940 | update_nats_in_cursum(journal, -i); |
1853 | mutex_unlock(&curseg->curseg_mutex); | 1941 | up_write(&curseg->journal_rwsem); |
1854 | } | 1942 | } |
1855 | 1943 | ||
1856 | static void __adjust_nat_entry_set(struct nat_entry_set *nes, | 1944 | static void __adjust_nat_entry_set(struct nat_entry_set *nes, |
@@ -1875,7 +1963,7 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1875 | struct nat_entry_set *set) | 1963 | struct nat_entry_set *set) |
1876 | { | 1964 | { |
1877 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 1965 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
1878 | struct f2fs_summary_block *sum = curseg->sum_blk; | 1966 | struct f2fs_journal *journal = curseg->journal; |
1879 | nid_t start_nid = set->set * NAT_ENTRY_PER_BLOCK; | 1967 | nid_t start_nid = set->set * NAT_ENTRY_PER_BLOCK; |
1880 | bool to_journal = true; | 1968 | bool to_journal = true; |
1881 | struct f2fs_nat_block *nat_blk; | 1969 | struct f2fs_nat_block *nat_blk; |
@@ -1887,11 +1975,11 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1887 | * #1, flush nat entries to journal in current hot data summary block. | 1975 | * #1, flush nat entries to journal in current hot data summary block. |
1888 | * #2, flush nat entries to nat page. | 1976 | * #2, flush nat entries to nat page. |
1889 | */ | 1977 | */ |
1890 | if (!__has_cursum_space(sum, set->entry_cnt, NAT_JOURNAL)) | 1978 | if (!__has_cursum_space(journal, set->entry_cnt, NAT_JOURNAL)) |
1891 | to_journal = false; | 1979 | to_journal = false; |
1892 | 1980 | ||
1893 | if (to_journal) { | 1981 | if (to_journal) { |
1894 | mutex_lock(&curseg->curseg_mutex); | 1982 | down_write(&curseg->journal_rwsem); |
1895 | } else { | 1983 | } else { |
1896 | page = get_next_nat_page(sbi, start_nid); | 1984 | page = get_next_nat_page(sbi, start_nid); |
1897 | nat_blk = page_address(page); | 1985 | nat_blk = page_address(page); |
@@ -1908,11 +1996,11 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1908 | continue; | 1996 | continue; |
1909 | 1997 | ||
1910 | if (to_journal) { | 1998 | if (to_journal) { |
1911 | offset = lookup_journal_in_cursum(sum, | 1999 | offset = lookup_journal_in_cursum(journal, |
1912 | NAT_JOURNAL, nid, 1); | 2000 | NAT_JOURNAL, nid, 1); |
1913 | f2fs_bug_on(sbi, offset < 0); | 2001 | f2fs_bug_on(sbi, offset < 0); |
1914 | raw_ne = &nat_in_journal(sum, offset); | 2002 | raw_ne = &nat_in_journal(journal, offset); |
1915 | nid_in_journal(sum, offset) = cpu_to_le32(nid); | 2003 | nid_in_journal(journal, offset) = cpu_to_le32(nid); |
1916 | } else { | 2004 | } else { |
1917 | raw_ne = &nat_blk->entries[nid - start_nid]; | 2005 | raw_ne = &nat_blk->entries[nid - start_nid]; |
1918 | } | 2006 | } |
@@ -1924,7 +2012,7 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1924 | } | 2012 | } |
1925 | 2013 | ||
1926 | if (to_journal) | 2014 | if (to_journal) |
1927 | mutex_unlock(&curseg->curseg_mutex); | 2015 | up_write(&curseg->journal_rwsem); |
1928 | else | 2016 | else |
1929 | f2fs_put_page(page, 1); | 2017 | f2fs_put_page(page, 1); |
1930 | 2018 | ||
@@ -1941,7 +2029,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1941 | { | 2029 | { |
1942 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 2030 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1943 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 2031 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
1944 | struct f2fs_summary_block *sum = curseg->sum_blk; | 2032 | struct f2fs_journal *journal = curseg->journal; |
1945 | struct nat_entry_set *setvec[SETVEC_SIZE]; | 2033 | struct nat_entry_set *setvec[SETVEC_SIZE]; |
1946 | struct nat_entry_set *set, *tmp; | 2034 | struct nat_entry_set *set, *tmp; |
1947 | unsigned int found; | 2035 | unsigned int found; |
@@ -1958,7 +2046,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1958 | * entries, remove all entries from journal and merge them | 2046 | * entries, remove all entries from journal and merge them |
1959 | * into nat entry set. | 2047 | * into nat entry set. |
1960 | */ | 2048 | */ |
1961 | if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) | 2049 | if (!__has_cursum_space(journal, nm_i->dirty_nat_cnt, NAT_JOURNAL)) |
1962 | remove_nats_in_journal(sbi); | 2050 | remove_nats_in_journal(sbi); |
1963 | 2051 | ||
1964 | while ((found = __gang_lookup_nat_set(nm_i, | 2052 | while ((found = __gang_lookup_nat_set(nm_i, |
@@ -1967,7 +2055,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1967 | set_idx = setvec[found - 1]->set + 1; | 2055 | set_idx = setvec[found - 1]->set + 1; |
1968 | for (idx = 0; idx < found; idx++) | 2056 | for (idx = 0; idx < found; idx++) |
1969 | __adjust_nat_entry_set(setvec[idx], &sets, | 2057 | __adjust_nat_entry_set(setvec[idx], &sets, |
1970 | MAX_NAT_JENTRIES(sum)); | 2058 | MAX_NAT_JENTRIES(journal)); |
1971 | } | 2059 | } |
1972 | 2060 | ||
1973 | /* flush dirty nats in nat entry set */ | 2061 | /* flush dirty nats in nat entry set */ |
@@ -2000,6 +2088,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) | |||
2000 | nm_i->nat_cnt = 0; | 2088 | nm_i->nat_cnt = 0; |
2001 | nm_i->ram_thresh = DEF_RAM_THRESHOLD; | 2089 | nm_i->ram_thresh = DEF_RAM_THRESHOLD; |
2002 | nm_i->ra_nid_pages = DEF_RA_NID_PAGES; | 2090 | nm_i->ra_nid_pages = DEF_RA_NID_PAGES; |
2091 | nm_i->dirty_nats_ratio = DEF_DIRTY_NAT_RATIO_THRESHOLD; | ||
2003 | 2092 | ||
2004 | INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); | 2093 | INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); |
2005 | INIT_LIST_HEAD(&nm_i->free_nid_list); | 2094 | INIT_LIST_HEAD(&nm_i->free_nid_list); |