aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c386
1 files changed, 234 insertions, 152 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 5904a411c86f..6f16b39f0b52 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -191,70 +191,145 @@ void register_inmem_page(struct inode *inode, struct page *page)
191 trace_f2fs_register_inmem_page(page, INMEM); 191 trace_f2fs_register_inmem_page(page, INMEM);
192} 192}
193 193
194int commit_inmem_pages(struct inode *inode, bool abort) 194static int __revoke_inmem_pages(struct inode *inode,
195 struct list_head *head, bool drop, bool recover)
196{
197 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
198 struct inmem_pages *cur, *tmp;
199 int err = 0;
200
201 list_for_each_entry_safe(cur, tmp, head, list) {
202 struct page *page = cur->page;
203
204 if (drop)
205 trace_f2fs_commit_inmem_page(page, INMEM_DROP);
206
207 lock_page(page);
208
209 if (recover) {
210 struct dnode_of_data dn;
211 struct node_info ni;
212
213 trace_f2fs_commit_inmem_page(page, INMEM_REVOKE);
214
215 set_new_dnode(&dn, inode, NULL, NULL, 0);
216 if (get_dnode_of_data(&dn, page->index, LOOKUP_NODE)) {
217 err = -EAGAIN;
218 goto next;
219 }
220 get_node_info(sbi, dn.nid, &ni);
221 f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
222 cur->old_addr, ni.version, true, true);
223 f2fs_put_dnode(&dn);
224 }
225next:
226 ClearPageUptodate(page);
227 set_page_private(page, 0);
228 ClearPageUptodate(page);
229 f2fs_put_page(page, 1);
230
231 list_del(&cur->list);
232 kmem_cache_free(inmem_entry_slab, cur);
233 dec_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES);
234 }
235 return err;
236}
237
238void drop_inmem_pages(struct inode *inode)
239{
240 struct f2fs_inode_info *fi = F2FS_I(inode);
241
242 mutex_lock(&fi->inmem_lock);
243 __revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
244 mutex_unlock(&fi->inmem_lock);
245}
246
247static int __commit_inmem_pages(struct inode *inode,
248 struct list_head *revoke_list)
195{ 249{
196 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 250 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
197 struct f2fs_inode_info *fi = F2FS_I(inode); 251 struct f2fs_inode_info *fi = F2FS_I(inode);
198 struct inmem_pages *cur, *tmp; 252 struct inmem_pages *cur, *tmp;
199 bool submit_bio = false;
200 struct f2fs_io_info fio = { 253 struct f2fs_io_info fio = {
201 .sbi = sbi, 254 .sbi = sbi,
202 .type = DATA, 255 .type = DATA,
203 .rw = WRITE_SYNC | REQ_PRIO, 256 .rw = WRITE_SYNC | REQ_PRIO,
204 .encrypted_page = NULL, 257 .encrypted_page = NULL,
205 }; 258 };
259 bool submit_bio = false;
206 int err = 0; 260 int err = 0;
207 261
208 /*
209 * The abort is true only when f2fs_evict_inode is called.
210 * Basically, the f2fs_evict_inode doesn't produce any data writes, so
211 * that we don't need to call f2fs_balance_fs.
212 * Otherwise, f2fs_gc in f2fs_balance_fs can wait forever until this
213 * inode becomes free by iget_locked in f2fs_iget.
214 */
215 if (!abort) {
216 f2fs_balance_fs(sbi, true);
217 f2fs_lock_op(sbi);
218 }
219
220 mutex_lock(&fi->inmem_lock);
221 list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) { 262 list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
222 lock_page(cur->page); 263 struct page *page = cur->page;
223 if (!abort) { 264
224 if (cur->page->mapping == inode->i_mapping) { 265 lock_page(page);
225 set_page_dirty(cur->page); 266 if (page->mapping == inode->i_mapping) {
226 f2fs_wait_on_page_writeback(cur->page, DATA); 267 trace_f2fs_commit_inmem_page(page, INMEM);
227 if (clear_page_dirty_for_io(cur->page)) 268
228 inode_dec_dirty_pages(inode); 269 set_page_dirty(page);
229 trace_f2fs_commit_inmem_page(cur->page, INMEM); 270 f2fs_wait_on_page_writeback(page, DATA, true);
230 fio.page = cur->page; 271 if (clear_page_dirty_for_io(page))
231 err = do_write_data_page(&fio); 272 inode_dec_dirty_pages(inode);
232 if (err) { 273
233 unlock_page(cur->page); 274 fio.page = page;
234 break; 275 err = do_write_data_page(&fio);
235 } 276 if (err) {
236 clear_cold_data(cur->page); 277 unlock_page(page);
237 submit_bio = true; 278 break;
238 } 279 }
239 } else { 280
240 ClearPageUptodate(cur->page); 281 /* record old blkaddr for revoking */
241 trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); 282 cur->old_addr = fio.old_blkaddr;
283
284 clear_cold_data(page);
285 submit_bio = true;
242 } 286 }
243 set_page_private(cur->page, 0); 287 unlock_page(page);
244 ClearPagePrivate(cur->page); 288 list_move_tail(&cur->list, revoke_list);
245 f2fs_put_page(cur->page, 1); 289 }
246 290
247 list_del(&cur->list); 291 if (submit_bio)
248 kmem_cache_free(inmem_entry_slab, cur); 292 f2fs_submit_merged_bio_cond(sbi, inode, NULL, 0, DATA, WRITE);
249 dec_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES); 293
294 if (!err)
295 __revoke_inmem_pages(inode, revoke_list, false, false);
296
297 return err;
298}
299
300int commit_inmem_pages(struct inode *inode)
301{
302 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
303 struct f2fs_inode_info *fi = F2FS_I(inode);
304 struct list_head revoke_list;
305 int err;
306
307 INIT_LIST_HEAD(&revoke_list);
308 f2fs_balance_fs(sbi, true);
309 f2fs_lock_op(sbi);
310
311 mutex_lock(&fi->inmem_lock);
312 err = __commit_inmem_pages(inode, &revoke_list);
313 if (err) {
314 int ret;
315 /*
316 * try to revoke all committed pages, but still we could fail
317 * due to no memory or other reason, if that happened, EAGAIN
318 * will be returned, which means in such case, transaction is
319 * already not integrity, caller should use journal to do the
320 * recovery or rewrite & commit last transaction. For other
321 * error number, revoking was done by filesystem itself.
322 */
323 ret = __revoke_inmem_pages(inode, &revoke_list, false, true);
324 if (ret)
325 err = ret;
326
327 /* drop all uncommitted pages */
328 __revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
250 } 329 }
251 mutex_unlock(&fi->inmem_lock); 330 mutex_unlock(&fi->inmem_lock);
252 331
253 if (!abort) { 332 f2fs_unlock_op(sbi);
254 f2fs_unlock_op(sbi);
255 if (submit_bio)
256 f2fs_submit_merged_bio(sbi, DATA, WRITE);
257 }
258 return err; 333 return err;
259} 334}
260 335
@@ -291,11 +366,17 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
291 366
292 /* checkpoint is the only way to shrink partial cached entries */ 367 /* checkpoint is the only way to shrink partial cached entries */
293 if (!available_free_memory(sbi, NAT_ENTRIES) || 368 if (!available_free_memory(sbi, NAT_ENTRIES) ||
294 excess_prefree_segs(sbi) ||
295 !available_free_memory(sbi, INO_ENTRIES) || 369 !available_free_memory(sbi, INO_ENTRIES) ||
370 excess_prefree_segs(sbi) ||
371 excess_dirty_nats(sbi) ||
296 (is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) { 372 (is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) {
297 if (test_opt(sbi, DATA_FLUSH)) 373 if (test_opt(sbi, DATA_FLUSH)) {
374 struct blk_plug plug;
375
376 blk_start_plug(&plug);
298 sync_dirty_inodes(sbi, FILE_INODE); 377 sync_dirty_inodes(sbi, FILE_INODE);
378 blk_finish_plug(&plug);
379 }
299 f2fs_sync_fs(sbi->sb, true); 380 f2fs_sync_fs(sbi->sb, true);
300 stat_inc_bg_cp_count(sbi->stat_info); 381 stat_inc_bg_cp_count(sbi->stat_info);
301 } 382 }
@@ -502,7 +583,7 @@ static int f2fs_issue_discard(struct f2fs_sb_info *sbi,
502 583
503bool discard_next_dnode(struct f2fs_sb_info *sbi, block_t blkaddr) 584bool discard_next_dnode(struct f2fs_sb_info *sbi, block_t blkaddr)
504{ 585{
505 int err = -ENOTSUPP; 586 int err = -EOPNOTSUPP;
506 587
507 if (test_opt(sbi, DISCARD)) { 588 if (test_opt(sbi, DISCARD)) {
508 struct seg_entry *se = get_seg_entry(sbi, 589 struct seg_entry *se = get_seg_entry(sbi,
@@ -841,6 +922,31 @@ static void write_sum_page(struct f2fs_sb_info *sbi,
841 update_meta_page(sbi, (void *)sum_blk, blk_addr); 922 update_meta_page(sbi, (void *)sum_blk, blk_addr);
842} 923}
843 924
925static void write_current_sum_page(struct f2fs_sb_info *sbi,
926 int type, block_t blk_addr)
927{
928 struct curseg_info *curseg = CURSEG_I(sbi, type);
929 struct page *page = grab_meta_page(sbi, blk_addr);
930 struct f2fs_summary_block *src = curseg->sum_blk;
931 struct f2fs_summary_block *dst;
932
933 dst = (struct f2fs_summary_block *)page_address(page);
934
935 mutex_lock(&curseg->curseg_mutex);
936
937 down_read(&curseg->journal_rwsem);
938 memcpy(&dst->journal, curseg->journal, SUM_JOURNAL_SIZE);
939 up_read(&curseg->journal_rwsem);
940
941 memcpy(dst->entries, src->entries, SUM_ENTRY_SIZE);
942 memcpy(&dst->footer, &src->footer, SUM_FOOTER_SIZE);
943
944 mutex_unlock(&curseg->curseg_mutex);
945
946 set_page_dirty(page);
947 f2fs_put_page(page, 1);
948}
949
844static int is_next_segment_free(struct f2fs_sb_info *sbi, int type) 950static int is_next_segment_free(struct f2fs_sb_info *sbi, int type)
845{ 951{
846 struct curseg_info *curseg = CURSEG_I(sbi, type); 952 struct curseg_info *curseg = CURSEG_I(sbi, type);
@@ -873,9 +979,8 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
873 979
874 if (!new_sec && ((*newseg + 1) % sbi->segs_per_sec)) { 980 if (!new_sec && ((*newseg + 1) % sbi->segs_per_sec)) {
875 segno = find_next_zero_bit(free_i->free_segmap, 981 segno = find_next_zero_bit(free_i->free_segmap,
876 MAIN_SEGS(sbi), *newseg + 1); 982 (hint + 1) * sbi->segs_per_sec, *newseg + 1);
877 if (segno - *newseg < sbi->segs_per_sec - 983 if (segno < (hint + 1) * sbi->segs_per_sec)
878 (*newseg % sbi->segs_per_sec))
879 goto got_it; 984 goto got_it;
880 } 985 }
881find_other_zone: 986find_other_zone:
@@ -1280,8 +1385,8 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
1280{ 1385{
1281 int type = __get_segment_type(fio->page, fio->type); 1386 int type = __get_segment_type(fio->page, fio->type);
1282 1387
1283 allocate_data_block(fio->sbi, fio->page, fio->blk_addr, 1388 allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
1284 &fio->blk_addr, sum, type); 1389 &fio->new_blkaddr, sum, type);
1285 1390
1286 /* writeout dirty page into bdev */ 1391 /* writeout dirty page into bdev */
1287 f2fs_submit_page_mbio(fio); 1392 f2fs_submit_page_mbio(fio);
@@ -1293,7 +1398,8 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
1293 .sbi = sbi, 1398 .sbi = sbi,
1294 .type = META, 1399 .type = META,
1295 .rw = WRITE_SYNC | REQ_META | REQ_PRIO, 1400 .rw = WRITE_SYNC | REQ_META | REQ_PRIO,
1296 .blk_addr = page->index, 1401 .old_blkaddr = page->index,
1402 .new_blkaddr = page->index,
1297 .page = page, 1403 .page = page,
1298 .encrypted_page = NULL, 1404 .encrypted_page = NULL,
1299 }; 1405 };
@@ -1323,19 +1429,19 @@ void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio)
1323 get_node_info(sbi, dn->nid, &ni); 1429 get_node_info(sbi, dn->nid, &ni);
1324 set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); 1430 set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
1325 do_write_page(&sum, fio); 1431 do_write_page(&sum, fio);
1326 dn->data_blkaddr = fio->blk_addr; 1432 f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
1327} 1433}
1328 1434
1329void rewrite_data_page(struct f2fs_io_info *fio) 1435void rewrite_data_page(struct f2fs_io_info *fio)
1330{ 1436{
1437 fio->new_blkaddr = fio->old_blkaddr;
1331 stat_inc_inplace_blocks(fio->sbi); 1438 stat_inc_inplace_blocks(fio->sbi);
1332 f2fs_submit_page_mbio(fio); 1439 f2fs_submit_page_mbio(fio);
1333} 1440}
1334 1441
1335static void __f2fs_replace_block(struct f2fs_sb_info *sbi, 1442void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
1336 struct f2fs_summary *sum,
1337 block_t old_blkaddr, block_t new_blkaddr, 1443 block_t old_blkaddr, block_t new_blkaddr,
1338 bool recover_curseg) 1444 bool recover_curseg, bool recover_newaddr)
1339{ 1445{
1340 struct sit_info *sit_i = SIT_I(sbi); 1446 struct sit_info *sit_i = SIT_I(sbi);
1341 struct curseg_info *curseg; 1447 struct curseg_info *curseg;
@@ -1378,7 +1484,7 @@ static void __f2fs_replace_block(struct f2fs_sb_info *sbi,
1378 curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); 1484 curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr);
1379 __add_sum_entry(sbi, type, sum); 1485 __add_sum_entry(sbi, type, sum);
1380 1486
1381 if (!recover_curseg) 1487 if (!recover_curseg || recover_newaddr)
1382 update_sit_entry(sbi, new_blkaddr, 1); 1488 update_sit_entry(sbi, new_blkaddr, 1);
1383 if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) 1489 if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
1384 update_sit_entry(sbi, old_blkaddr, -1); 1490 update_sit_entry(sbi, old_blkaddr, -1);
@@ -1402,66 +1508,30 @@ static void __f2fs_replace_block(struct f2fs_sb_info *sbi,
1402 1508
1403void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn, 1509void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
1404 block_t old_addr, block_t new_addr, 1510 block_t old_addr, block_t new_addr,
1405 unsigned char version, bool recover_curseg) 1511 unsigned char version, bool recover_curseg,
1512 bool recover_newaddr)
1406{ 1513{
1407 struct f2fs_summary sum; 1514 struct f2fs_summary sum;
1408 1515
1409 set_summary(&sum, dn->nid, dn->ofs_in_node, version); 1516 set_summary(&sum, dn->nid, dn->ofs_in_node, version);
1410 1517
1411 __f2fs_replace_block(sbi, &sum, old_addr, new_addr, recover_curseg); 1518 __f2fs_replace_block(sbi, &sum, old_addr, new_addr,
1519 recover_curseg, recover_newaddr);
1412 1520
1413 dn->data_blkaddr = new_addr; 1521 f2fs_update_data_blkaddr(dn, new_addr);
1414 set_data_blkaddr(dn);
1415 f2fs_update_extent_cache(dn);
1416}
1417
1418static inline bool is_merged_page(struct f2fs_sb_info *sbi,
1419 struct page *page, enum page_type type)
1420{
1421 enum page_type btype = PAGE_TYPE_OF_BIO(type);
1422 struct f2fs_bio_info *io = &sbi->write_io[btype];
1423 struct bio_vec *bvec;
1424 struct page *target;
1425 int i;
1426
1427 down_read(&io->io_rwsem);
1428 if (!io->bio) {
1429 up_read(&io->io_rwsem);
1430 return false;
1431 }
1432
1433 bio_for_each_segment_all(bvec, io->bio, i) {
1434
1435 if (bvec->bv_page->mapping) {
1436 target = bvec->bv_page;
1437 } else {
1438 struct f2fs_crypto_ctx *ctx;
1439
1440 /* encrypted page */
1441 ctx = (struct f2fs_crypto_ctx *)page_private(
1442 bvec->bv_page);
1443 target = ctx->w.control_page;
1444 }
1445
1446 if (page == target) {
1447 up_read(&io->io_rwsem);
1448 return true;
1449 }
1450 }
1451
1452 up_read(&io->io_rwsem);
1453 return false;
1454} 1522}
1455 1523
1456void f2fs_wait_on_page_writeback(struct page *page, 1524void f2fs_wait_on_page_writeback(struct page *page,
1457 enum page_type type) 1525 enum page_type type, bool ordered)
1458{ 1526{
1459 if (PageWriteback(page)) { 1527 if (PageWriteback(page)) {
1460 struct f2fs_sb_info *sbi = F2FS_P_SB(page); 1528 struct f2fs_sb_info *sbi = F2FS_P_SB(page);
1461 1529
1462 if (is_merged_page(sbi, page, type)) 1530 f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, type, WRITE);
1463 f2fs_submit_merged_bio(sbi, type, WRITE); 1531 if (ordered)
1464 wait_on_page_writeback(page); 1532 wait_on_page_writeback(page);
1533 else
1534 wait_for_stable_page(page);
1465 } 1535 }
1466} 1536}
1467 1537
@@ -1477,7 +1547,7 @@ void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi,
1477 1547
1478 cpage = find_lock_page(META_MAPPING(sbi), blkaddr); 1548 cpage = find_lock_page(META_MAPPING(sbi), blkaddr);
1479 if (cpage) { 1549 if (cpage) {
1480 f2fs_wait_on_page_writeback(cpage, DATA); 1550 f2fs_wait_on_page_writeback(cpage, DATA, true);
1481 f2fs_put_page(cpage, 1); 1551 f2fs_put_page(cpage, 1);
1482 } 1552 }
1483} 1553}
@@ -1498,12 +1568,11 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi)
1498 1568
1499 /* Step 1: restore nat cache */ 1569 /* Step 1: restore nat cache */
1500 seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); 1570 seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA);
1501 memcpy(&seg_i->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE); 1571 memcpy(seg_i->journal, kaddr, SUM_JOURNAL_SIZE);
1502 1572
1503 /* Step 2: restore sit cache */ 1573 /* Step 2: restore sit cache */
1504 seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA); 1574 seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA);
1505 memcpy(&seg_i->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE, 1575 memcpy(seg_i->journal, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE);
1506 SUM_JOURNAL_SIZE);
1507 offset = 2 * SUM_JOURNAL_SIZE; 1576 offset = 2 * SUM_JOURNAL_SIZE;
1508 1577
1509 /* Step 3: restore summary entries */ 1578 /* Step 3: restore summary entries */
@@ -1599,7 +1668,14 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
1599 /* set uncompleted segment to curseg */ 1668 /* set uncompleted segment to curseg */
1600 curseg = CURSEG_I(sbi, type); 1669 curseg = CURSEG_I(sbi, type);
1601 mutex_lock(&curseg->curseg_mutex); 1670 mutex_lock(&curseg->curseg_mutex);
1602 memcpy(curseg->sum_blk, sum, PAGE_CACHE_SIZE); 1671
1672 /* update journal info */
1673 down_write(&curseg->journal_rwsem);
1674 memcpy(curseg->journal, &sum->journal, SUM_JOURNAL_SIZE);
1675 up_write(&curseg->journal_rwsem);
1676
1677 memcpy(curseg->sum_blk->entries, sum->entries, SUM_ENTRY_SIZE);
1678 memcpy(&curseg->sum_blk->footer, &sum->footer, SUM_FOOTER_SIZE);
1603 curseg->next_segno = segno; 1679 curseg->next_segno = segno;
1604 reset_curseg(sbi, type, 0); 1680 reset_curseg(sbi, type, 0);
1605 curseg->alloc_type = ckpt->alloc_type[type]; 1681 curseg->alloc_type = ckpt->alloc_type[type];
@@ -1654,13 +1730,12 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr)
1654 1730
1655 /* Step 1: write nat cache */ 1731 /* Step 1: write nat cache */
1656 seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); 1732 seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA);
1657 memcpy(kaddr, &seg_i->sum_blk->n_nats, SUM_JOURNAL_SIZE); 1733 memcpy(kaddr, seg_i->journal, SUM_JOURNAL_SIZE);
1658 written_size += SUM_JOURNAL_SIZE; 1734 written_size += SUM_JOURNAL_SIZE;
1659 1735
1660 /* Step 2: write sit cache */ 1736 /* Step 2: write sit cache */
1661 seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA); 1737 seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA);
1662 memcpy(kaddr + written_size, &seg_i->sum_blk->n_sits, 1738 memcpy(kaddr + written_size, seg_i->journal, SUM_JOURNAL_SIZE);
1663 SUM_JOURNAL_SIZE);
1664 written_size += SUM_JOURNAL_SIZE; 1739 written_size += SUM_JOURNAL_SIZE;
1665 1740
1666 /* Step 3: write summary entries */ 1741 /* Step 3: write summary entries */
@@ -1706,12 +1781,8 @@ static void write_normal_summaries(struct f2fs_sb_info *sbi,
1706 else 1781 else
1707 end = type + NR_CURSEG_NODE_TYPE; 1782 end = type + NR_CURSEG_NODE_TYPE;
1708 1783
1709 for (i = type; i < end; i++) { 1784 for (i = type; i < end; i++)
1710 struct curseg_info *sum = CURSEG_I(sbi, i); 1785 write_current_sum_page(sbi, i, blkaddr + (i - type));
1711 mutex_lock(&sum->curseg_mutex);
1712 write_sum_page(sbi, sum->sum_blk, blkaddr + (i - type));
1713 mutex_unlock(&sum->curseg_mutex);
1714 }
1715} 1786}
1716 1787
1717void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk) 1788void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
@@ -1727,24 +1798,24 @@ void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
1727 write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); 1798 write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
1728} 1799}
1729 1800
1730int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, 1801int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
1731 unsigned int val, int alloc) 1802 unsigned int val, int alloc)
1732{ 1803{
1733 int i; 1804 int i;
1734 1805
1735 if (type == NAT_JOURNAL) { 1806 if (type == NAT_JOURNAL) {
1736 for (i = 0; i < nats_in_cursum(sum); i++) { 1807 for (i = 0; i < nats_in_cursum(journal); i++) {
1737 if (le32_to_cpu(nid_in_journal(sum, i)) == val) 1808 if (le32_to_cpu(nid_in_journal(journal, i)) == val)
1738 return i; 1809 return i;
1739 } 1810 }
1740 if (alloc && __has_cursum_space(sum, 1, NAT_JOURNAL)) 1811 if (alloc && __has_cursum_space(journal, 1, NAT_JOURNAL))
1741 return update_nats_in_cursum(sum, 1); 1812 return update_nats_in_cursum(journal, 1);
1742 } else if (type == SIT_JOURNAL) { 1813 } else if (type == SIT_JOURNAL) {
1743 for (i = 0; i < sits_in_cursum(sum); i++) 1814 for (i = 0; i < sits_in_cursum(journal); i++)
1744 if (le32_to_cpu(segno_in_journal(sum, i)) == val) 1815 if (le32_to_cpu(segno_in_journal(journal, i)) == val)
1745 return i; 1816 return i;
1746 if (alloc && __has_cursum_space(sum, 1, SIT_JOURNAL)) 1817 if (alloc && __has_cursum_space(journal, 1, SIT_JOURNAL))
1747 return update_sits_in_cursum(sum, 1); 1818 return update_sits_in_cursum(journal, 1);
1748 } 1819 }
1749 return -1; 1820 return -1;
1750} 1821}
@@ -1848,20 +1919,22 @@ static void add_sits_in_set(struct f2fs_sb_info *sbi)
1848static void remove_sits_in_journal(struct f2fs_sb_info *sbi) 1919static void remove_sits_in_journal(struct f2fs_sb_info *sbi)
1849{ 1920{
1850 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); 1921 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
1851 struct f2fs_summary_block *sum = curseg->sum_blk; 1922 struct f2fs_journal *journal = curseg->journal;
1852 int i; 1923 int i;
1853 1924
1854 for (i = sits_in_cursum(sum) - 1; i >= 0; i--) { 1925 down_write(&curseg->journal_rwsem);
1926 for (i = 0; i < sits_in_cursum(journal); i++) {
1855 unsigned int segno; 1927 unsigned int segno;
1856 bool dirtied; 1928 bool dirtied;
1857 1929
1858 segno = le32_to_cpu(segno_in_journal(sum, i)); 1930 segno = le32_to_cpu(segno_in_journal(journal, i));
1859 dirtied = __mark_sit_entry_dirty(sbi, segno); 1931 dirtied = __mark_sit_entry_dirty(sbi, segno);
1860 1932
1861 if (!dirtied) 1933 if (!dirtied)
1862 add_sit_entry(segno, &SM_I(sbi)->sit_entry_set); 1934 add_sit_entry(segno, &SM_I(sbi)->sit_entry_set);
1863 } 1935 }
1864 update_sits_in_cursum(sum, -sits_in_cursum(sum)); 1936 update_sits_in_cursum(journal, -i);
1937 up_write(&curseg->journal_rwsem);
1865} 1938}
1866 1939
1867/* 1940/*
@@ -1873,13 +1946,12 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1873 struct sit_info *sit_i = SIT_I(sbi); 1946 struct sit_info *sit_i = SIT_I(sbi);
1874 unsigned long *bitmap = sit_i->dirty_sentries_bitmap; 1947 unsigned long *bitmap = sit_i->dirty_sentries_bitmap;
1875 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); 1948 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
1876 struct f2fs_summary_block *sum = curseg->sum_blk; 1949 struct f2fs_journal *journal = curseg->journal;
1877 struct sit_entry_set *ses, *tmp; 1950 struct sit_entry_set *ses, *tmp;
1878 struct list_head *head = &SM_I(sbi)->sit_entry_set; 1951 struct list_head *head = &SM_I(sbi)->sit_entry_set;
1879 bool to_journal = true; 1952 bool to_journal = true;
1880 struct seg_entry *se; 1953 struct seg_entry *se;
1881 1954
1882 mutex_lock(&curseg->curseg_mutex);
1883 mutex_lock(&sit_i->sentry_lock); 1955 mutex_lock(&sit_i->sentry_lock);
1884 1956
1885 if (!sit_i->dirty_sentries) 1957 if (!sit_i->dirty_sentries)
@@ -1896,7 +1968,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1896 * entries, remove all entries from journal and add and account 1968 * entries, remove all entries from journal and add and account
1897 * them in sit entry set. 1969 * them in sit entry set.
1898 */ 1970 */
1899 if (!__has_cursum_space(sum, sit_i->dirty_sentries, SIT_JOURNAL)) 1971 if (!__has_cursum_space(journal, sit_i->dirty_sentries, SIT_JOURNAL))
1900 remove_sits_in_journal(sbi); 1972 remove_sits_in_journal(sbi);
1901 1973
1902 /* 1974 /*
@@ -1913,10 +1985,12 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1913 unsigned int segno = start_segno; 1985 unsigned int segno = start_segno;
1914 1986
1915 if (to_journal && 1987 if (to_journal &&
1916 !__has_cursum_space(sum, ses->entry_cnt, SIT_JOURNAL)) 1988 !__has_cursum_space(journal, ses->entry_cnt, SIT_JOURNAL))
1917 to_journal = false; 1989 to_journal = false;
1918 1990
1919 if (!to_journal) { 1991 if (to_journal) {
1992 down_write(&curseg->journal_rwsem);
1993 } else {
1920 page = get_next_sit_page(sbi, start_segno); 1994 page = get_next_sit_page(sbi, start_segno);
1921 raw_sit = page_address(page); 1995 raw_sit = page_address(page);
1922 } 1996 }
@@ -1934,13 +2008,13 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1934 } 2008 }
1935 2009
1936 if (to_journal) { 2010 if (to_journal) {
1937 offset = lookup_journal_in_cursum(sum, 2011 offset = lookup_journal_in_cursum(journal,
1938 SIT_JOURNAL, segno, 1); 2012 SIT_JOURNAL, segno, 1);
1939 f2fs_bug_on(sbi, offset < 0); 2013 f2fs_bug_on(sbi, offset < 0);
1940 segno_in_journal(sum, offset) = 2014 segno_in_journal(journal, offset) =
1941 cpu_to_le32(segno); 2015 cpu_to_le32(segno);
1942 seg_info_to_raw_sit(se, 2016 seg_info_to_raw_sit(se,
1943 &sit_in_journal(sum, offset)); 2017 &sit_in_journal(journal, offset));
1944 } else { 2018 } else {
1945 sit_offset = SIT_ENTRY_OFFSET(sit_i, segno); 2019 sit_offset = SIT_ENTRY_OFFSET(sit_i, segno);
1946 seg_info_to_raw_sit(se, 2020 seg_info_to_raw_sit(se,
@@ -1952,7 +2026,9 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1952 ses->entry_cnt--; 2026 ses->entry_cnt--;
1953 } 2027 }
1954 2028
1955 if (!to_journal) 2029 if (to_journal)
2030 up_write(&curseg->journal_rwsem);
2031 else
1956 f2fs_put_page(page, 1); 2032 f2fs_put_page(page, 1);
1957 2033
1958 f2fs_bug_on(sbi, ses->entry_cnt); 2034 f2fs_bug_on(sbi, ses->entry_cnt);
@@ -1967,7 +2043,6 @@ out:
1967 add_discard_addrs(sbi, cpc); 2043 add_discard_addrs(sbi, cpc);
1968 } 2044 }
1969 mutex_unlock(&sit_i->sentry_lock); 2045 mutex_unlock(&sit_i->sentry_lock);
1970 mutex_unlock(&curseg->curseg_mutex);
1971 2046
1972 set_prefree_as_free_segments(sbi); 2047 set_prefree_as_free_segments(sbi);
1973} 2048}
@@ -2099,6 +2174,11 @@ static int build_curseg(struct f2fs_sb_info *sbi)
2099 array[i].sum_blk = kzalloc(PAGE_CACHE_SIZE, GFP_KERNEL); 2174 array[i].sum_blk = kzalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
2100 if (!array[i].sum_blk) 2175 if (!array[i].sum_blk)
2101 return -ENOMEM; 2176 return -ENOMEM;
2177 init_rwsem(&array[i].journal_rwsem);
2178 array[i].journal = kzalloc(sizeof(struct f2fs_journal),
2179 GFP_KERNEL);
2180 if (!array[i].journal)
2181 return -ENOMEM;
2102 array[i].segno = NULL_SEGNO; 2182 array[i].segno = NULL_SEGNO;
2103 array[i].next_blkoff = 0; 2183 array[i].next_blkoff = 0;
2104 } 2184 }
@@ -2109,11 +2189,11 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
2109{ 2189{
2110 struct sit_info *sit_i = SIT_I(sbi); 2190 struct sit_info *sit_i = SIT_I(sbi);
2111 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); 2191 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
2112 struct f2fs_summary_block *sum = curseg->sum_blk; 2192 struct f2fs_journal *journal = curseg->journal;
2113 int sit_blk_cnt = SIT_BLK_CNT(sbi); 2193 int sit_blk_cnt = SIT_BLK_CNT(sbi);
2114 unsigned int i, start, end; 2194 unsigned int i, start, end;
2115 unsigned int readed, start_blk = 0; 2195 unsigned int readed, start_blk = 0;
2116 int nrpages = MAX_BIO_BLOCKS(sbi); 2196 int nrpages = MAX_BIO_BLOCKS(sbi) * 8;
2117 2197
2118 do { 2198 do {
2119 readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true); 2199 readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true);
@@ -2127,16 +2207,16 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
2127 struct f2fs_sit_entry sit; 2207 struct f2fs_sit_entry sit;
2128 struct page *page; 2208 struct page *page;
2129 2209
2130 mutex_lock(&curseg->curseg_mutex); 2210 down_read(&curseg->journal_rwsem);
2131 for (i = 0; i < sits_in_cursum(sum); i++) { 2211 for (i = 0; i < sits_in_cursum(journal); i++) {
2132 if (le32_to_cpu(segno_in_journal(sum, i)) 2212 if (le32_to_cpu(segno_in_journal(journal, i))
2133 == start) { 2213 == start) {
2134 sit = sit_in_journal(sum, i); 2214 sit = sit_in_journal(journal, i);
2135 mutex_unlock(&curseg->curseg_mutex); 2215 up_read(&curseg->journal_rwsem);
2136 goto got_it; 2216 goto got_it;
2137 } 2217 }
2138 } 2218 }
2139 mutex_unlock(&curseg->curseg_mutex); 2219 up_read(&curseg->journal_rwsem);
2140 2220
2141 page = get_current_sit_page(sbi, start); 2221 page = get_current_sit_page(sbi, start);
2142 sit_blk = (struct f2fs_sit_block *)page_address(page); 2222 sit_blk = (struct f2fs_sit_block *)page_address(page);
@@ -2371,8 +2451,10 @@ static void destroy_curseg(struct f2fs_sb_info *sbi)
2371 if (!array) 2451 if (!array)
2372 return; 2452 return;
2373 SM_I(sbi)->curseg_array = NULL; 2453 SM_I(sbi)->curseg_array = NULL;
2374 for (i = 0; i < NR_CURSEG_TYPE; i++) 2454 for (i = 0; i < NR_CURSEG_TYPE; i++) {
2375 kfree(array[i].sum_blk); 2455 kfree(array[i].sum_blk);
2456 kfree(array[i].journal);
2457 }
2376 kfree(array); 2458 kfree(array);
2377} 2459}
2378 2460