diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
-rw-r--r-- | fs/nilfs2/segment.c | 584 |
1 files changed, 220 insertions, 364 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 9fd051a33c4f..bb24ab6c282f 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -104,8 +104,7 @@ struct nilfs_sc_operations { | |||
104 | static void nilfs_segctor_start_timer(struct nilfs_sc_info *); | 104 | static void nilfs_segctor_start_timer(struct nilfs_sc_info *); |
105 | static void nilfs_segctor_do_flush(struct nilfs_sc_info *, int); | 105 | static void nilfs_segctor_do_flush(struct nilfs_sc_info *, int); |
106 | static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *); | 106 | static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *); |
107 | static void nilfs_dispose_list(struct nilfs_sb_info *, struct list_head *, | 107 | static void nilfs_dispose_list(struct the_nilfs *, struct list_head *, int); |
108 | int); | ||
109 | 108 | ||
110 | #define nilfs_cnt32_gt(a, b) \ | 109 | #define nilfs_cnt32_gt(a, b) \ |
111 | (typecheck(__u32, a) && typecheck(__u32, b) && \ | 110 | (typecheck(__u32, a) && typecheck(__u32, b) && \ |
@@ -182,7 +181,6 @@ int nilfs_transaction_begin(struct super_block *sb, | |||
182 | struct nilfs_transaction_info *ti, | 181 | struct nilfs_transaction_info *ti, |
183 | int vacancy_check) | 182 | int vacancy_check) |
184 | { | 183 | { |
185 | struct nilfs_sb_info *sbi; | ||
186 | struct the_nilfs *nilfs; | 184 | struct the_nilfs *nilfs; |
187 | int ret = nilfs_prepare_segment_lock(ti); | 185 | int ret = nilfs_prepare_segment_lock(ti); |
188 | 186 | ||
@@ -191,8 +189,9 @@ int nilfs_transaction_begin(struct super_block *sb, | |||
191 | if (ret > 0) | 189 | if (ret > 0) |
192 | return 0; | 190 | return 0; |
193 | 191 | ||
194 | sbi = NILFS_SB(sb); | 192 | vfs_check_frozen(sb, SB_FREEZE_WRITE); |
195 | nilfs = sbi->s_nilfs; | 193 | |
194 | nilfs = sb->s_fs_info; | ||
196 | down_read(&nilfs->ns_segctor_sem); | 195 | down_read(&nilfs->ns_segctor_sem); |
197 | if (vacancy_check && nilfs_near_disk_full(nilfs)) { | 196 | if (vacancy_check && nilfs_near_disk_full(nilfs)) { |
198 | up_read(&nilfs->ns_segctor_sem); | 197 | up_read(&nilfs->ns_segctor_sem); |
@@ -223,8 +222,7 @@ int nilfs_transaction_begin(struct super_block *sb, | |||
223 | int nilfs_transaction_commit(struct super_block *sb) | 222 | int nilfs_transaction_commit(struct super_block *sb) |
224 | { | 223 | { |
225 | struct nilfs_transaction_info *ti = current->journal_info; | 224 | struct nilfs_transaction_info *ti = current->journal_info; |
226 | struct nilfs_sb_info *sbi; | 225 | struct the_nilfs *nilfs = sb->s_fs_info; |
227 | struct nilfs_sc_info *sci; | ||
228 | int err = 0; | 226 | int err = 0; |
229 | 227 | ||
230 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); | 228 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); |
@@ -233,16 +231,15 @@ int nilfs_transaction_commit(struct super_block *sb) | |||
233 | ti->ti_count--; | 231 | ti->ti_count--; |
234 | return 0; | 232 | return 0; |
235 | } | 233 | } |
236 | sbi = NILFS_SB(sb); | 234 | if (nilfs->ns_writer) { |
237 | sci = NILFS_SC(sbi); | 235 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
238 | if (sci != NULL) { | 236 | |
239 | if (ti->ti_flags & NILFS_TI_COMMIT) | 237 | if (ti->ti_flags & NILFS_TI_COMMIT) |
240 | nilfs_segctor_start_timer(sci); | 238 | nilfs_segctor_start_timer(sci); |
241 | if (atomic_read(&sbi->s_nilfs->ns_ndirtyblks) > | 239 | if (atomic_read(&nilfs->ns_ndirtyblks) > sci->sc_watermark) |
242 | sci->sc_watermark) | ||
243 | nilfs_segctor_do_flush(sci, 0); | 240 | nilfs_segctor_do_flush(sci, 0); |
244 | } | 241 | } |
245 | up_read(&sbi->s_nilfs->ns_segctor_sem); | 242 | up_read(&nilfs->ns_segctor_sem); |
246 | current->journal_info = ti->ti_save; | 243 | current->journal_info = ti->ti_save; |
247 | 244 | ||
248 | if (ti->ti_flags & NILFS_TI_SYNC) | 245 | if (ti->ti_flags & NILFS_TI_SYNC) |
@@ -255,13 +252,14 @@ int nilfs_transaction_commit(struct super_block *sb) | |||
255 | void nilfs_transaction_abort(struct super_block *sb) | 252 | void nilfs_transaction_abort(struct super_block *sb) |
256 | { | 253 | { |
257 | struct nilfs_transaction_info *ti = current->journal_info; | 254 | struct nilfs_transaction_info *ti = current->journal_info; |
255 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
258 | 256 | ||
259 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); | 257 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); |
260 | if (ti->ti_count > 0) { | 258 | if (ti->ti_count > 0) { |
261 | ti->ti_count--; | 259 | ti->ti_count--; |
262 | return; | 260 | return; |
263 | } | 261 | } |
264 | up_read(&NILFS_SB(sb)->s_nilfs->ns_segctor_sem); | 262 | up_read(&nilfs->ns_segctor_sem); |
265 | 263 | ||
266 | current->journal_info = ti->ti_save; | 264 | current->journal_info = ti->ti_save; |
267 | if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC) | 265 | if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC) |
@@ -270,9 +268,8 @@ void nilfs_transaction_abort(struct super_block *sb) | |||
270 | 268 | ||
271 | void nilfs_relax_pressure_in_lock(struct super_block *sb) | 269 | void nilfs_relax_pressure_in_lock(struct super_block *sb) |
272 | { | 270 | { |
273 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 271 | struct the_nilfs *nilfs = sb->s_fs_info; |
274 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 272 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
275 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
276 | 273 | ||
277 | if (!sci || !sci->sc_flush_request) | 274 | if (!sci || !sci->sc_flush_request) |
278 | return; | 275 | return; |
@@ -292,11 +289,13 @@ void nilfs_relax_pressure_in_lock(struct super_block *sb) | |||
292 | downgrade_write(&nilfs->ns_segctor_sem); | 289 | downgrade_write(&nilfs->ns_segctor_sem); |
293 | } | 290 | } |
294 | 291 | ||
295 | static void nilfs_transaction_lock(struct nilfs_sb_info *sbi, | 292 | static void nilfs_transaction_lock(struct super_block *sb, |
296 | struct nilfs_transaction_info *ti, | 293 | struct nilfs_transaction_info *ti, |
297 | int gcflag) | 294 | int gcflag) |
298 | { | 295 | { |
299 | struct nilfs_transaction_info *cur_ti = current->journal_info; | 296 | struct nilfs_transaction_info *cur_ti = current->journal_info; |
297 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
298 | struct nilfs_sc_info *sci = nilfs->ns_writer; | ||
300 | 299 | ||
301 | WARN_ON(cur_ti); | 300 | WARN_ON(cur_ti); |
302 | ti->ti_flags = NILFS_TI_WRITER; | 301 | ti->ti_flags = NILFS_TI_WRITER; |
@@ -307,30 +306,31 @@ static void nilfs_transaction_lock(struct nilfs_sb_info *sbi, | |||
307 | current->journal_info = ti; | 306 | current->journal_info = ti; |
308 | 307 | ||
309 | for (;;) { | 308 | for (;;) { |
310 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 309 | down_write(&nilfs->ns_segctor_sem); |
311 | if (!test_bit(NILFS_SC_PRIOR_FLUSH, &NILFS_SC(sbi)->sc_flags)) | 310 | if (!test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags)) |
312 | break; | 311 | break; |
313 | 312 | ||
314 | nilfs_segctor_do_immediate_flush(NILFS_SC(sbi)); | 313 | nilfs_segctor_do_immediate_flush(sci); |
315 | 314 | ||
316 | up_write(&sbi->s_nilfs->ns_segctor_sem); | 315 | up_write(&nilfs->ns_segctor_sem); |
317 | yield(); | 316 | yield(); |
318 | } | 317 | } |
319 | if (gcflag) | 318 | if (gcflag) |
320 | ti->ti_flags |= NILFS_TI_GC; | 319 | ti->ti_flags |= NILFS_TI_GC; |
321 | } | 320 | } |
322 | 321 | ||
323 | static void nilfs_transaction_unlock(struct nilfs_sb_info *sbi) | 322 | static void nilfs_transaction_unlock(struct super_block *sb) |
324 | { | 323 | { |
325 | struct nilfs_transaction_info *ti = current->journal_info; | 324 | struct nilfs_transaction_info *ti = current->journal_info; |
325 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
326 | 326 | ||
327 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); | 327 | BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC); |
328 | BUG_ON(ti->ti_count > 0); | 328 | BUG_ON(ti->ti_count > 0); |
329 | 329 | ||
330 | up_write(&sbi->s_nilfs->ns_segctor_sem); | 330 | up_write(&nilfs->ns_segctor_sem); |
331 | current->journal_info = ti->ti_save; | 331 | current->journal_info = ti->ti_save; |
332 | if (!list_empty(&ti->ti_garbage)) | 332 | if (!list_empty(&ti->ti_garbage)) |
333 | nilfs_dispose_list(sbi, &ti->ti_garbage, 0); | 333 | nilfs_dispose_list(nilfs, &ti->ti_garbage, 0); |
334 | } | 334 | } |
335 | 335 | ||
336 | static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci, | 336 | static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci, |
@@ -366,8 +366,7 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci) | |||
366 | 366 | ||
367 | if (nilfs_doing_gc()) | 367 | if (nilfs_doing_gc()) |
368 | flags = NILFS_SS_GC; | 368 | flags = NILFS_SS_GC; |
369 | err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, | 369 | err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, sci->sc_cno); |
370 | sci->sc_sbi->s_nilfs->ns_cno); | ||
371 | if (unlikely(err)) | 370 | if (unlikely(err)) |
372 | return err; | 371 | return err; |
373 | 372 | ||
@@ -429,7 +428,8 @@ static void nilfs_segctor_begin_finfo(struct nilfs_sc_info *sci, | |||
429 | nilfs_segctor_map_segsum_entry( | 428 | nilfs_segctor_map_segsum_entry( |
430 | sci, &sci->sc_binfo_ptr, sizeof(struct nilfs_finfo)); | 429 | sci, &sci->sc_binfo_ptr, sizeof(struct nilfs_finfo)); |
431 | 430 | ||
432 | if (inode->i_sb && !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags)) | 431 | if (NILFS_I(inode)->i_root && |
432 | !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags)) | ||
433 | set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); | 433 | set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); |
434 | /* skip finfo */ | 434 | /* skip finfo */ |
435 | } | 435 | } |
@@ -440,17 +440,26 @@ static void nilfs_segctor_end_finfo(struct nilfs_sc_info *sci, | |||
440 | struct nilfs_finfo *finfo; | 440 | struct nilfs_finfo *finfo; |
441 | struct nilfs_inode_info *ii; | 441 | struct nilfs_inode_info *ii; |
442 | struct nilfs_segment_buffer *segbuf; | 442 | struct nilfs_segment_buffer *segbuf; |
443 | __u64 cno; | ||
443 | 444 | ||
444 | if (sci->sc_blk_cnt == 0) | 445 | if (sci->sc_blk_cnt == 0) |
445 | return; | 446 | return; |
446 | 447 | ||
447 | ii = NILFS_I(inode); | 448 | ii = NILFS_I(inode); |
449 | |||
450 | if (test_bit(NILFS_I_GCINODE, &ii->i_state)) | ||
451 | cno = ii->i_cno; | ||
452 | else if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) | ||
453 | cno = 0; | ||
454 | else | ||
455 | cno = sci->sc_cno; | ||
456 | |||
448 | finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr, | 457 | finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr, |
449 | sizeof(*finfo)); | 458 | sizeof(*finfo)); |
450 | finfo->fi_ino = cpu_to_le64(inode->i_ino); | 459 | finfo->fi_ino = cpu_to_le64(inode->i_ino); |
451 | finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt); | 460 | finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt); |
452 | finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt); | 461 | finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt); |
453 | finfo->fi_cno = cpu_to_le64(ii->i_cno); | 462 | finfo->fi_cno = cpu_to_le64(cno); |
454 | 463 | ||
455 | segbuf = sci->sc_curseg; | 464 | segbuf = sci->sc_curseg; |
456 | segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset + | 465 | segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset + |
@@ -494,17 +503,6 @@ static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci, | |||
494 | return err; | 503 | return err; |
495 | } | 504 | } |
496 | 505 | ||
497 | static int nilfs_handle_bmap_error(int err, const char *fname, | ||
498 | struct inode *inode, struct super_block *sb) | ||
499 | { | ||
500 | if (err == -EINVAL) { | ||
501 | nilfs_error(sb, fname, "broken bmap (inode=%lu)\n", | ||
502 | inode->i_ino); | ||
503 | err = -EIO; | ||
504 | } | ||
505 | return err; | ||
506 | } | ||
507 | |||
508 | /* | 506 | /* |
509 | * Callback functions that enumerate, mark, and collect dirty blocks | 507 | * Callback functions that enumerate, mark, and collect dirty blocks |
510 | */ | 508 | */ |
@@ -514,9 +512,8 @@ static int nilfs_collect_file_data(struct nilfs_sc_info *sci, | |||
514 | int err; | 512 | int err; |
515 | 513 | ||
516 | err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); | 514 | err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); |
517 | if (unlikely(err < 0)) | 515 | if (err < 0) |
518 | return nilfs_handle_bmap_error(err, __func__, inode, | 516 | return err; |
519 | sci->sc_super); | ||
520 | 517 | ||
521 | err = nilfs_segctor_add_file_block(sci, bh, inode, | 518 | err = nilfs_segctor_add_file_block(sci, bh, inode, |
522 | sizeof(struct nilfs_binfo_v)); | 519 | sizeof(struct nilfs_binfo_v)); |
@@ -529,13 +526,7 @@ static int nilfs_collect_file_node(struct nilfs_sc_info *sci, | |||
529 | struct buffer_head *bh, | 526 | struct buffer_head *bh, |
530 | struct inode *inode) | 527 | struct inode *inode) |
531 | { | 528 | { |
532 | int err; | 529 | return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); |
533 | |||
534 | err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); | ||
535 | if (unlikely(err < 0)) | ||
536 | return nilfs_handle_bmap_error(err, __func__, inode, | ||
537 | sci->sc_super); | ||
538 | return 0; | ||
539 | } | 530 | } |
540 | 531 | ||
541 | static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci, | 532 | static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci, |
@@ -578,9 +569,8 @@ static int nilfs_collect_dat_data(struct nilfs_sc_info *sci, | |||
578 | int err; | 569 | int err; |
579 | 570 | ||
580 | err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); | 571 | err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); |
581 | if (unlikely(err < 0)) | 572 | if (err < 0) |
582 | return nilfs_handle_bmap_error(err, __func__, inode, | 573 | return err; |
583 | sci->sc_super); | ||
584 | 574 | ||
585 | err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64)); | 575 | err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64)); |
586 | if (!err) | 576 | if (!err) |
@@ -665,13 +655,10 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, | |||
665 | if (unlikely(page->index > last)) | 655 | if (unlikely(page->index > last)) |
666 | break; | 656 | break; |
667 | 657 | ||
668 | if (mapping->host) { | 658 | lock_page(page); |
669 | lock_page(page); | 659 | if (!page_has_buffers(page)) |
670 | if (!page_has_buffers(page)) | 660 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); |
671 | create_empty_buffers(page, | 661 | unlock_page(page); |
672 | 1 << inode->i_blkbits, 0); | ||
673 | unlock_page(page); | ||
674 | } | ||
675 | 662 | ||
676 | bh = head = page_buffers(page); | 663 | bh = head = page_buffers(page); |
677 | do { | 664 | do { |
@@ -722,7 +709,7 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode, | |||
722 | } | 709 | } |
723 | } | 710 | } |
724 | 711 | ||
725 | static void nilfs_dispose_list(struct nilfs_sb_info *sbi, | 712 | static void nilfs_dispose_list(struct the_nilfs *nilfs, |
726 | struct list_head *head, int force) | 713 | struct list_head *head, int force) |
727 | { | 714 | { |
728 | struct nilfs_inode_info *ii, *n; | 715 | struct nilfs_inode_info *ii, *n; |
@@ -730,7 +717,7 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi, | |||
730 | unsigned nv = 0; | 717 | unsigned nv = 0; |
731 | 718 | ||
732 | while (!list_empty(head)) { | 719 | while (!list_empty(head)) { |
733 | spin_lock(&sbi->s_inode_lock); | 720 | spin_lock(&nilfs->ns_inode_lock); |
734 | list_for_each_entry_safe(ii, n, head, i_dirty) { | 721 | list_for_each_entry_safe(ii, n, head, i_dirty) { |
735 | list_del_init(&ii->i_dirty); | 722 | list_del_init(&ii->i_dirty); |
736 | if (force) { | 723 | if (force) { |
@@ -741,34 +728,33 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi, | |||
741 | } else if (test_bit(NILFS_I_DIRTY, &ii->i_state)) { | 728 | } else if (test_bit(NILFS_I_DIRTY, &ii->i_state)) { |
742 | set_bit(NILFS_I_QUEUED, &ii->i_state); | 729 | set_bit(NILFS_I_QUEUED, &ii->i_state); |
743 | list_add_tail(&ii->i_dirty, | 730 | list_add_tail(&ii->i_dirty, |
744 | &sbi->s_dirty_files); | 731 | &nilfs->ns_dirty_files); |
745 | continue; | 732 | continue; |
746 | } | 733 | } |
747 | ivec[nv++] = ii; | 734 | ivec[nv++] = ii; |
748 | if (nv == SC_N_INODEVEC) | 735 | if (nv == SC_N_INODEVEC) |
749 | break; | 736 | break; |
750 | } | 737 | } |
751 | spin_unlock(&sbi->s_inode_lock); | 738 | spin_unlock(&nilfs->ns_inode_lock); |
752 | 739 | ||
753 | for (pii = ivec; nv > 0; pii++, nv--) | 740 | for (pii = ivec; nv > 0; pii++, nv--) |
754 | iput(&(*pii)->vfs_inode); | 741 | iput(&(*pii)->vfs_inode); |
755 | } | 742 | } |
756 | } | 743 | } |
757 | 744 | ||
758 | static int nilfs_test_metadata_dirty(struct nilfs_sb_info *sbi) | 745 | static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs, |
746 | struct nilfs_root *root) | ||
759 | { | 747 | { |
760 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
761 | int ret = 0; | 748 | int ret = 0; |
762 | 749 | ||
763 | if (nilfs_mdt_fetch_dirty(sbi->s_ifile)) | 750 | if (nilfs_mdt_fetch_dirty(root->ifile)) |
764 | ret++; | 751 | ret++; |
765 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) | 752 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) |
766 | ret++; | 753 | ret++; |
767 | if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile)) | 754 | if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile)) |
768 | ret++; | 755 | ret++; |
769 | if (ret || nilfs_doing_gc()) | 756 | if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat)) |
770 | if (nilfs_mdt_fetch_dirty(nilfs_dat_inode(nilfs))) | 757 | ret++; |
771 | ret++; | ||
772 | return ret; | 758 | return ret; |
773 | } | 759 | } |
774 | 760 | ||
@@ -782,34 +768,33 @@ static int nilfs_segctor_clean(struct nilfs_sc_info *sci) | |||
782 | 768 | ||
783 | static int nilfs_segctor_confirm(struct nilfs_sc_info *sci) | 769 | static int nilfs_segctor_confirm(struct nilfs_sc_info *sci) |
784 | { | 770 | { |
785 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 771 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
786 | int ret = 0; | 772 | int ret = 0; |
787 | 773 | ||
788 | if (nilfs_test_metadata_dirty(sbi)) | 774 | if (nilfs_test_metadata_dirty(nilfs, sci->sc_root)) |
789 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 775 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
790 | 776 | ||
791 | spin_lock(&sbi->s_inode_lock); | 777 | spin_lock(&nilfs->ns_inode_lock); |
792 | if (list_empty(&sbi->s_dirty_files) && nilfs_segctor_clean(sci)) | 778 | if (list_empty(&nilfs->ns_dirty_files) && nilfs_segctor_clean(sci)) |
793 | ret++; | 779 | ret++; |
794 | 780 | ||
795 | spin_unlock(&sbi->s_inode_lock); | 781 | spin_unlock(&nilfs->ns_inode_lock); |
796 | return ret; | 782 | return ret; |
797 | } | 783 | } |
798 | 784 | ||
799 | static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) | 785 | static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) |
800 | { | 786 | { |
801 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 787 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
802 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
803 | 788 | ||
804 | nilfs_mdt_clear_dirty(sbi->s_ifile); | 789 | nilfs_mdt_clear_dirty(sci->sc_root->ifile); |
805 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); | 790 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); |
806 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); | 791 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); |
807 | nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); | 792 | nilfs_mdt_clear_dirty(nilfs->ns_dat); |
808 | } | 793 | } |
809 | 794 | ||
810 | static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) | 795 | static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) |
811 | { | 796 | { |
812 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | 797 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
813 | struct buffer_head *bh_cp; | 798 | struct buffer_head *bh_cp; |
814 | struct nilfs_checkpoint *raw_cp; | 799 | struct nilfs_checkpoint *raw_cp; |
815 | int err; | 800 | int err; |
@@ -821,7 +806,7 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) | |||
821 | /* The following code is duplicated with cpfile. But, it is | 806 | /* The following code is duplicated with cpfile. But, it is |
822 | needed to collect the checkpoint even if it was not newly | 807 | needed to collect the checkpoint even if it was not newly |
823 | created */ | 808 | created */ |
824 | nilfs_mdt_mark_buffer_dirty(bh_cp); | 809 | mark_buffer_dirty(bh_cp); |
825 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); | 810 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); |
826 | nilfs_cpfile_put_checkpoint( | 811 | nilfs_cpfile_put_checkpoint( |
827 | nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); | 812 | nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); |
@@ -833,8 +818,7 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) | |||
833 | 818 | ||
834 | static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | 819 | static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) |
835 | { | 820 | { |
836 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 821 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
837 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
838 | struct buffer_head *bh_cp; | 822 | struct buffer_head *bh_cp; |
839 | struct nilfs_checkpoint *raw_cp; | 823 | struct nilfs_checkpoint *raw_cp; |
840 | int err; | 824 | int err; |
@@ -848,9 +832,9 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | |||
848 | raw_cp->cp_snapshot_list.ssl_next = 0; | 832 | raw_cp->cp_snapshot_list.ssl_next = 0; |
849 | raw_cp->cp_snapshot_list.ssl_prev = 0; | 833 | raw_cp->cp_snapshot_list.ssl_prev = 0; |
850 | raw_cp->cp_inodes_count = | 834 | raw_cp->cp_inodes_count = |
851 | cpu_to_le64(atomic_read(&sbi->s_inodes_count)); | 835 | cpu_to_le64(atomic_read(&sci->sc_root->inodes_count)); |
852 | raw_cp->cp_blocks_count = | 836 | raw_cp->cp_blocks_count = |
853 | cpu_to_le64(atomic_read(&sbi->s_blocks_count)); | 837 | cpu_to_le64(atomic_read(&sci->sc_root->blocks_count)); |
854 | raw_cp->cp_nblk_inc = | 838 | raw_cp->cp_nblk_inc = |
855 | cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc); | 839 | cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc); |
856 | raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime); | 840 | raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime); |
@@ -861,7 +845,8 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | |||
861 | else | 845 | else |
862 | nilfs_checkpoint_set_minor(raw_cp); | 846 | nilfs_checkpoint_set_minor(raw_cp); |
863 | 847 | ||
864 | nilfs_write_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode, 1); | 848 | nilfs_write_inode_common(sci->sc_root->ifile, |
849 | &raw_cp->cp_ifile_inode, 1); | ||
865 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); | 850 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); |
866 | return 0; | 851 | return 0; |
867 | 852 | ||
@@ -886,13 +871,12 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile, | |||
886 | } | 871 | } |
887 | } | 872 | } |
888 | 873 | ||
889 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci, | 874 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci) |
890 | struct inode *ifile) | ||
891 | { | 875 | { |
892 | struct nilfs_inode_info *ii; | 876 | struct nilfs_inode_info *ii; |
893 | 877 | ||
894 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { | 878 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { |
895 | nilfs_fill_in_file_bmap(ifile, ii); | 879 | nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii); |
896 | set_bit(NILFS_I_COLLECTED, &ii->i_state); | 880 | set_bit(NILFS_I_COLLECTED, &ii->i_state); |
897 | } | 881 | } |
898 | } | 882 | } |
@@ -902,23 +886,26 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, | |||
902 | { | 886 | { |
903 | struct buffer_head *bh_sr; | 887 | struct buffer_head *bh_sr; |
904 | struct nilfs_super_root *raw_sr; | 888 | struct nilfs_super_root *raw_sr; |
905 | unsigned isz = nilfs->ns_inode_size; | 889 | unsigned isz, srsz; |
906 | 890 | ||
907 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; | 891 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; |
908 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; | 892 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; |
893 | isz = nilfs->ns_inode_size; | ||
894 | srsz = NILFS_SR_BYTES(isz); | ||
909 | 895 | ||
910 | raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES); | 896 | raw_sr->sr_bytes = cpu_to_le16(srsz); |
911 | raw_sr->sr_nongc_ctime | 897 | raw_sr->sr_nongc_ctime |
912 | = cpu_to_le64(nilfs_doing_gc() ? | 898 | = cpu_to_le64(nilfs_doing_gc() ? |
913 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); | 899 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); |
914 | raw_sr->sr_flags = 0; | 900 | raw_sr->sr_flags = 0; |
915 | 901 | ||
916 | nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr + | 902 | nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr + |
917 | NILFS_SR_DAT_OFFSET(isz), 1); | 903 | NILFS_SR_DAT_OFFSET(isz), 1); |
918 | nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr + | 904 | nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr + |
919 | NILFS_SR_CPFILE_OFFSET(isz), 1); | 905 | NILFS_SR_CPFILE_OFFSET(isz), 1); |
920 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + | 906 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + |
921 | NILFS_SR_SUFILE_OFFSET(isz), 1); | 907 | NILFS_SR_SUFILE_OFFSET(isz), 1); |
908 | memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz); | ||
922 | } | 909 | } |
923 | 910 | ||
924 | static void nilfs_redirty_inodes(struct list_head *head) | 911 | static void nilfs_redirty_inodes(struct list_head *head) |
@@ -967,8 +954,8 @@ static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci, | |||
967 | 954 | ||
968 | dispose_buffers: | 955 | dispose_buffers: |
969 | while (!list_empty(listp)) { | 956 | while (!list_empty(listp)) { |
970 | bh = list_entry(listp->next, struct buffer_head, | 957 | bh = list_first_entry(listp, struct buffer_head, |
971 | b_assoc_buffers); | 958 | b_assoc_buffers); |
972 | list_del_init(&bh->b_assoc_buffers); | 959 | list_del_init(&bh->b_assoc_buffers); |
973 | brelse(bh); | 960 | brelse(bh); |
974 | } | 961 | } |
@@ -1058,8 +1045,7 @@ static int nilfs_segctor_scan_file_dsync(struct nilfs_sc_info *sci, | |||
1058 | 1045 | ||
1059 | static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | 1046 | static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) |
1060 | { | 1047 | { |
1061 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 1048 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
1062 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
1063 | struct list_head *head; | 1049 | struct list_head *head; |
1064 | struct nilfs_inode_info *ii; | 1050 | struct nilfs_inode_info *ii; |
1065 | size_t ndone; | 1051 | size_t ndone; |
@@ -1135,7 +1121,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1135 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; | 1121 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; |
1136 | /* Fall through */ | 1122 | /* Fall through */ |
1137 | case NILFS_ST_IFILE: | 1123 | case NILFS_ST_IFILE: |
1138 | err = nilfs_segctor_scan_file(sci, sbi->s_ifile, | 1124 | err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile, |
1139 | &nilfs_sc_file_ops); | 1125 | &nilfs_sc_file_ops); |
1140 | if (unlikely(err)) | 1126 | if (unlikely(err)) |
1141 | break; | 1127 | break; |
@@ -1169,7 +1155,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1169 | sci->sc_stage.scnt++; /* Fall through */ | 1155 | sci->sc_stage.scnt++; /* Fall through */ |
1170 | case NILFS_ST_DAT: | 1156 | case NILFS_ST_DAT: |
1171 | dat_stage: | 1157 | dat_stage: |
1172 | err = nilfs_segctor_scan_file(sci, nilfs_dat_inode(nilfs), | 1158 | err = nilfs_segctor_scan_file(sci, nilfs->ns_dat, |
1173 | &nilfs_sc_dat_ops); | 1159 | &nilfs_sc_dat_ops); |
1174 | if (unlikely(err)) | 1160 | if (unlikely(err)) |
1175 | break; | 1161 | break; |
@@ -1514,10 +1500,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci, | |||
1514 | nblocks = le32_to_cpu(finfo->fi_nblocks); | 1500 | nblocks = le32_to_cpu(finfo->fi_nblocks); |
1515 | ndatablk = le32_to_cpu(finfo->fi_ndatablk); | 1501 | ndatablk = le32_to_cpu(finfo->fi_ndatablk); |
1516 | 1502 | ||
1517 | if (buffer_nilfs_node(bh)) | 1503 | inode = bh->b_page->mapping->host; |
1518 | inode = NILFS_BTNC_I(bh->b_page->mapping); | ||
1519 | else | ||
1520 | inode = NILFS_AS_I(bh->b_page->mapping); | ||
1521 | 1504 | ||
1522 | if (mode == SC_LSEG_DSYNC) | 1505 | if (mode == SC_LSEG_DSYNC) |
1523 | sc_op = &nilfs_sc_dsync_ops; | 1506 | sc_op = &nilfs_sc_dsync_ops; |
@@ -1553,7 +1536,6 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci, | |||
1553 | return 0; | 1536 | return 0; |
1554 | 1537 | ||
1555 | failed_bmap: | 1538 | failed_bmap: |
1556 | err = nilfs_handle_bmap_error(err, __func__, inode, sci->sc_super); | ||
1557 | return err; | 1539 | return err; |
1558 | } | 1540 | } |
1559 | 1541 | ||
@@ -1571,83 +1553,24 @@ static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode) | |||
1571 | return 0; | 1553 | return 0; |
1572 | } | 1554 | } |
1573 | 1555 | ||
1574 | static int | 1556 | static void nilfs_begin_page_io(struct page *page) |
1575 | nilfs_copy_replace_page_buffers(struct page *page, struct list_head *out) | ||
1576 | { | ||
1577 | struct page *clone_page; | ||
1578 | struct buffer_head *bh, *head, *bh2; | ||
1579 | void *kaddr; | ||
1580 | |||
1581 | bh = head = page_buffers(page); | ||
1582 | |||
1583 | clone_page = nilfs_alloc_private_page(bh->b_bdev, bh->b_size, 0); | ||
1584 | if (unlikely(!clone_page)) | ||
1585 | return -ENOMEM; | ||
1586 | |||
1587 | bh2 = page_buffers(clone_page); | ||
1588 | kaddr = kmap_atomic(page, KM_USER0); | ||
1589 | do { | ||
1590 | if (list_empty(&bh->b_assoc_buffers)) | ||
1591 | continue; | ||
1592 | get_bh(bh2); | ||
1593 | page_cache_get(clone_page); /* for each bh */ | ||
1594 | memcpy(bh2->b_data, kaddr + bh_offset(bh), bh2->b_size); | ||
1595 | bh2->b_blocknr = bh->b_blocknr; | ||
1596 | list_replace(&bh->b_assoc_buffers, &bh2->b_assoc_buffers); | ||
1597 | list_add_tail(&bh->b_assoc_buffers, out); | ||
1598 | } while (bh = bh->b_this_page, bh2 = bh2->b_this_page, bh != head); | ||
1599 | kunmap_atomic(kaddr, KM_USER0); | ||
1600 | |||
1601 | if (!TestSetPageWriteback(clone_page)) | ||
1602 | inc_zone_page_state(clone_page, NR_WRITEBACK); | ||
1603 | unlock_page(clone_page); | ||
1604 | |||
1605 | return 0; | ||
1606 | } | ||
1607 | |||
1608 | static int nilfs_test_page_to_be_frozen(struct page *page) | ||
1609 | { | ||
1610 | struct address_space *mapping = page->mapping; | ||
1611 | |||
1612 | if (!mapping || !mapping->host || S_ISDIR(mapping->host->i_mode)) | ||
1613 | return 0; | ||
1614 | |||
1615 | if (page_mapped(page)) { | ||
1616 | ClearPageChecked(page); | ||
1617 | return 1; | ||
1618 | } | ||
1619 | return PageChecked(page); | ||
1620 | } | ||
1621 | |||
1622 | static int nilfs_begin_page_io(struct page *page, struct list_head *out) | ||
1623 | { | 1557 | { |
1624 | if (!page || PageWriteback(page)) | 1558 | if (!page || PageWriteback(page)) |
1625 | /* For split b-tree node pages, this function may be called | 1559 | /* For split b-tree node pages, this function may be called |
1626 | twice. We ignore the 2nd or later calls by this check. */ | 1560 | twice. We ignore the 2nd or later calls by this check. */ |
1627 | return 0; | 1561 | return; |
1628 | 1562 | ||
1629 | lock_page(page); | 1563 | lock_page(page); |
1630 | clear_page_dirty_for_io(page); | 1564 | clear_page_dirty_for_io(page); |
1631 | set_page_writeback(page); | 1565 | set_page_writeback(page); |
1632 | unlock_page(page); | 1566 | unlock_page(page); |
1633 | |||
1634 | if (nilfs_test_page_to_be_frozen(page)) { | ||
1635 | int err = nilfs_copy_replace_page_buffers(page, out); | ||
1636 | if (unlikely(err)) | ||
1637 | return err; | ||
1638 | } | ||
1639 | return 0; | ||
1640 | } | 1567 | } |
1641 | 1568 | ||
1642 | static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | 1569 | static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) |
1643 | struct page **failed_page) | ||
1644 | { | 1570 | { |
1645 | struct nilfs_segment_buffer *segbuf; | 1571 | struct nilfs_segment_buffer *segbuf; |
1646 | struct page *bd_page = NULL, *fs_page = NULL; | 1572 | struct page *bd_page = NULL, *fs_page = NULL; |
1647 | struct list_head *list = &sci->sc_copied_buffers; | ||
1648 | int err; | ||
1649 | 1573 | ||
1650 | *failed_page = NULL; | ||
1651 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1574 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { |
1652 | struct buffer_head *bh; | 1575 | struct buffer_head *bh; |
1653 | 1576 | ||
@@ -1677,11 +1600,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
1677 | break; | 1600 | break; |
1678 | } | 1601 | } |
1679 | if (bh->b_page != fs_page) { | 1602 | if (bh->b_page != fs_page) { |
1680 | err = nilfs_begin_page_io(fs_page, list); | 1603 | nilfs_begin_page_io(fs_page); |
1681 | if (unlikely(err)) { | ||
1682 | *failed_page = fs_page; | ||
1683 | goto out; | ||
1684 | } | ||
1685 | fs_page = bh->b_page; | 1604 | fs_page = bh->b_page; |
1686 | } | 1605 | } |
1687 | } | 1606 | } |
@@ -1692,11 +1611,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
1692 | set_page_writeback(bd_page); | 1611 | set_page_writeback(bd_page); |
1693 | unlock_page(bd_page); | 1612 | unlock_page(bd_page); |
1694 | } | 1613 | } |
1695 | err = nilfs_begin_page_io(fs_page, list); | 1614 | nilfs_begin_page_io(fs_page); |
1696 | if (unlikely(err)) | ||
1697 | *failed_page = fs_page; | ||
1698 | out: | ||
1699 | return err; | ||
1700 | } | 1615 | } |
1701 | 1616 | ||
1702 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, | 1617 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, |
@@ -1709,24 +1624,6 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
1709 | return ret; | 1624 | return ret; |
1710 | } | 1625 | } |
1711 | 1626 | ||
1712 | static void __nilfs_end_page_io(struct page *page, int err) | ||
1713 | { | ||
1714 | if (!err) { | ||
1715 | if (!nilfs_page_buffers_clean(page)) | ||
1716 | __set_page_dirty_nobuffers(page); | ||
1717 | ClearPageError(page); | ||
1718 | } else { | ||
1719 | __set_page_dirty_nobuffers(page); | ||
1720 | SetPageError(page); | ||
1721 | } | ||
1722 | |||
1723 | if (buffer_nilfs_allocated(page_buffers(page))) { | ||
1724 | if (TestClearPageWriteback(page)) | ||
1725 | dec_zone_page_state(page, NR_WRITEBACK); | ||
1726 | } else | ||
1727 | end_page_writeback(page); | ||
1728 | } | ||
1729 | |||
1730 | static void nilfs_end_page_io(struct page *page, int err) | 1627 | static void nilfs_end_page_io(struct page *page, int err) |
1731 | { | 1628 | { |
1732 | if (!page) | 1629 | if (!page) |
@@ -1753,39 +1650,19 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
1753 | return; | 1650 | return; |
1754 | } | 1651 | } |
1755 | 1652 | ||
1756 | __nilfs_end_page_io(page, err); | 1653 | if (!err) { |
1757 | } | 1654 | if (!nilfs_page_buffers_clean(page)) |
1758 | 1655 | __set_page_dirty_nobuffers(page); | |
1759 | static void nilfs_clear_copied_buffers(struct list_head *list, int err) | 1656 | ClearPageError(page); |
1760 | { | 1657 | } else { |
1761 | struct buffer_head *bh, *head; | 1658 | __set_page_dirty_nobuffers(page); |
1762 | struct page *page; | 1659 | SetPageError(page); |
1763 | |||
1764 | while (!list_empty(list)) { | ||
1765 | bh = list_entry(list->next, struct buffer_head, | ||
1766 | b_assoc_buffers); | ||
1767 | page = bh->b_page; | ||
1768 | page_cache_get(page); | ||
1769 | head = bh = page_buffers(page); | ||
1770 | do { | ||
1771 | if (!list_empty(&bh->b_assoc_buffers)) { | ||
1772 | list_del_init(&bh->b_assoc_buffers); | ||
1773 | if (!err) { | ||
1774 | set_buffer_uptodate(bh); | ||
1775 | clear_buffer_dirty(bh); | ||
1776 | clear_buffer_nilfs_volatile(bh); | ||
1777 | } | ||
1778 | brelse(bh); /* for b_assoc_buffers */ | ||
1779 | } | ||
1780 | } while ((bh = bh->b_this_page) != head); | ||
1781 | |||
1782 | __nilfs_end_page_io(page, err); | ||
1783 | page_cache_release(page); | ||
1784 | } | 1660 | } |
1661 | |||
1662 | end_page_writeback(page); | ||
1785 | } | 1663 | } |
1786 | 1664 | ||
1787 | static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, | 1665 | static void nilfs_abort_logs(struct list_head *logs, int err) |
1788 | int err) | ||
1789 | { | 1666 | { |
1790 | struct nilfs_segment_buffer *segbuf; | 1667 | struct nilfs_segment_buffer *segbuf; |
1791 | struct page *bd_page = NULL, *fs_page = NULL; | 1668 | struct page *bd_page = NULL, *fs_page = NULL; |
@@ -1815,8 +1692,6 @@ static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, | |||
1815 | } | 1692 | } |
1816 | if (bh->b_page != fs_page) { | 1693 | if (bh->b_page != fs_page) { |
1817 | nilfs_end_page_io(fs_page, err); | 1694 | nilfs_end_page_io(fs_page, err); |
1818 | if (fs_page && fs_page == failed_page) | ||
1819 | return; | ||
1820 | fs_page = bh->b_page; | 1695 | fs_page = bh->b_page; |
1821 | } | 1696 | } |
1822 | } | 1697 | } |
@@ -1835,12 +1710,11 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, | |||
1835 | 1710 | ||
1836 | list_splice_tail_init(&sci->sc_write_logs, &logs); | 1711 | list_splice_tail_init(&sci->sc_write_logs, &logs); |
1837 | ret = nilfs_wait_on_logs(&logs); | 1712 | ret = nilfs_wait_on_logs(&logs); |
1838 | nilfs_abort_logs(&logs, NULL, ret ? : err); | 1713 | nilfs_abort_logs(&logs, ret ? : err); |
1839 | 1714 | ||
1840 | list_splice_tail_init(&sci->sc_segbufs, &logs); | 1715 | list_splice_tail_init(&sci->sc_segbufs, &logs); |
1841 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); | 1716 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); |
1842 | nilfs_free_incomplete_logs(&logs, nilfs); | 1717 | nilfs_free_incomplete_logs(&logs, nilfs); |
1843 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); | ||
1844 | 1718 | ||
1845 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { | 1719 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { |
1846 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | 1720 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, |
@@ -1868,7 +1742,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1868 | { | 1742 | { |
1869 | struct nilfs_segment_buffer *segbuf; | 1743 | struct nilfs_segment_buffer *segbuf; |
1870 | struct page *bd_page = NULL, *fs_page = NULL; | 1744 | struct page *bd_page = NULL, *fs_page = NULL; |
1871 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | 1745 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
1872 | int update_sr = false; | 1746 | int update_sr = false; |
1873 | 1747 | ||
1874 | list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { | 1748 | list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { |
@@ -1899,7 +1773,9 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1899 | b_assoc_buffers) { | 1773 | b_assoc_buffers) { |
1900 | set_buffer_uptodate(bh); | 1774 | set_buffer_uptodate(bh); |
1901 | clear_buffer_dirty(bh); | 1775 | clear_buffer_dirty(bh); |
1776 | clear_buffer_delay(bh); | ||
1902 | clear_buffer_nilfs_volatile(bh); | 1777 | clear_buffer_nilfs_volatile(bh); |
1778 | clear_buffer_nilfs_redirected(bh); | ||
1903 | if (bh == segbuf->sb_super_root) { | 1779 | if (bh == segbuf->sb_super_root) { |
1904 | if (bh->b_page != bd_page) { | 1780 | if (bh->b_page != bd_page) { |
1905 | end_page_writeback(bd_page); | 1781 | end_page_writeback(bd_page); |
@@ -1932,15 +1808,11 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1932 | 1808 | ||
1933 | nilfs_end_page_io(fs_page, 0); | 1809 | nilfs_end_page_io(fs_page, 0); |
1934 | 1810 | ||
1935 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, 0); | ||
1936 | |||
1937 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); | 1811 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); |
1938 | 1812 | ||
1939 | if (nilfs_doing_gc()) { | 1813 | if (nilfs_doing_gc()) |
1940 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); | 1814 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); |
1941 | if (update_sr) | 1815 | else |
1942 | nilfs_commit_gcdat_inode(nilfs); | ||
1943 | } else | ||
1944 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; | 1816 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; |
1945 | 1817 | ||
1946 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; | 1818 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; |
@@ -1972,75 +1844,64 @@ static int nilfs_segctor_wait(struct nilfs_sc_info *sci) | |||
1972 | return ret; | 1844 | return ret; |
1973 | } | 1845 | } |
1974 | 1846 | ||
1975 | static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | 1847 | static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, |
1976 | struct nilfs_sb_info *sbi) | 1848 | struct the_nilfs *nilfs) |
1977 | { | 1849 | { |
1978 | struct nilfs_inode_info *ii, *n; | 1850 | struct nilfs_inode_info *ii, *n; |
1979 | __u64 cno = sbi->s_nilfs->ns_cno; | 1851 | struct inode *ifile = sci->sc_root->ifile; |
1980 | 1852 | ||
1981 | spin_lock(&sbi->s_inode_lock); | 1853 | spin_lock(&nilfs->ns_inode_lock); |
1982 | retry: | 1854 | retry: |
1983 | list_for_each_entry_safe(ii, n, &sbi->s_dirty_files, i_dirty) { | 1855 | list_for_each_entry_safe(ii, n, &nilfs->ns_dirty_files, i_dirty) { |
1984 | if (!ii->i_bh) { | 1856 | if (!ii->i_bh) { |
1985 | struct buffer_head *ibh; | 1857 | struct buffer_head *ibh; |
1986 | int err; | 1858 | int err; |
1987 | 1859 | ||
1988 | spin_unlock(&sbi->s_inode_lock); | 1860 | spin_unlock(&nilfs->ns_inode_lock); |
1989 | err = nilfs_ifile_get_inode_block( | 1861 | err = nilfs_ifile_get_inode_block( |
1990 | sbi->s_ifile, ii->vfs_inode.i_ino, &ibh); | 1862 | ifile, ii->vfs_inode.i_ino, &ibh); |
1991 | if (unlikely(err)) { | 1863 | if (unlikely(err)) { |
1992 | nilfs_warning(sbi->s_super, __func__, | 1864 | nilfs_warning(sci->sc_super, __func__, |
1993 | "failed to get inode block.\n"); | 1865 | "failed to get inode block.\n"); |
1994 | return err; | 1866 | return err; |
1995 | } | 1867 | } |
1996 | nilfs_mdt_mark_buffer_dirty(ibh); | 1868 | mark_buffer_dirty(ibh); |
1997 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 1869 | nilfs_mdt_mark_dirty(ifile); |
1998 | spin_lock(&sbi->s_inode_lock); | 1870 | spin_lock(&nilfs->ns_inode_lock); |
1999 | if (likely(!ii->i_bh)) | 1871 | if (likely(!ii->i_bh)) |
2000 | ii->i_bh = ibh; | 1872 | ii->i_bh = ibh; |
2001 | else | 1873 | else |
2002 | brelse(ibh); | 1874 | brelse(ibh); |
2003 | goto retry; | 1875 | goto retry; |
2004 | } | 1876 | } |
2005 | ii->i_cno = cno; | ||
2006 | 1877 | ||
2007 | clear_bit(NILFS_I_QUEUED, &ii->i_state); | 1878 | clear_bit(NILFS_I_QUEUED, &ii->i_state); |
2008 | set_bit(NILFS_I_BUSY, &ii->i_state); | 1879 | set_bit(NILFS_I_BUSY, &ii->i_state); |
2009 | list_del(&ii->i_dirty); | 1880 | list_move_tail(&ii->i_dirty, &sci->sc_dirty_files); |
2010 | list_add_tail(&ii->i_dirty, &sci->sc_dirty_files); | ||
2011 | } | 1881 | } |
2012 | spin_unlock(&sbi->s_inode_lock); | 1882 | spin_unlock(&nilfs->ns_inode_lock); |
2013 | |||
2014 | NILFS_I(sbi->s_ifile)->i_cno = cno; | ||
2015 | 1883 | ||
2016 | return 0; | 1884 | return 0; |
2017 | } | 1885 | } |
2018 | 1886 | ||
2019 | static void nilfs_segctor_check_out_files(struct nilfs_sc_info *sci, | 1887 | static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, |
2020 | struct nilfs_sb_info *sbi) | 1888 | struct the_nilfs *nilfs) |
2021 | { | 1889 | { |
2022 | struct nilfs_transaction_info *ti = current->journal_info; | 1890 | struct nilfs_transaction_info *ti = current->journal_info; |
2023 | struct nilfs_inode_info *ii, *n; | 1891 | struct nilfs_inode_info *ii, *n; |
2024 | __u64 cno = sbi->s_nilfs->ns_cno; | ||
2025 | 1892 | ||
2026 | spin_lock(&sbi->s_inode_lock); | 1893 | spin_lock(&nilfs->ns_inode_lock); |
2027 | list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) { | 1894 | list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) { |
2028 | if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) || | 1895 | if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) || |
2029 | test_bit(NILFS_I_DIRTY, &ii->i_state)) { | 1896 | test_bit(NILFS_I_DIRTY, &ii->i_state)) |
2030 | /* The current checkpoint number (=nilfs->ns_cno) is | ||
2031 | changed between check-in and check-out only if the | ||
2032 | super root is written out. So, we can update i_cno | ||
2033 | for the inodes that remain in the dirty list. */ | ||
2034 | ii->i_cno = cno; | ||
2035 | continue; | 1897 | continue; |
2036 | } | 1898 | |
2037 | clear_bit(NILFS_I_BUSY, &ii->i_state); | 1899 | clear_bit(NILFS_I_BUSY, &ii->i_state); |
2038 | brelse(ii->i_bh); | 1900 | brelse(ii->i_bh); |
2039 | ii->i_bh = NULL; | 1901 | ii->i_bh = NULL; |
2040 | list_del(&ii->i_dirty); | 1902 | list_move_tail(&ii->i_dirty, &ti->ti_garbage); |
2041 | list_add_tail(&ii->i_dirty, &ti->ti_garbage); | ||
2042 | } | 1903 | } |
2043 | spin_unlock(&sbi->s_inode_lock); | 1904 | spin_unlock(&nilfs->ns_inode_lock); |
2044 | } | 1905 | } |
2045 | 1906 | ||
2046 | /* | 1907 | /* |
@@ -2048,18 +1909,17 @@ static void nilfs_segctor_check_out_files(struct nilfs_sc_info *sci, | |||
2048 | */ | 1909 | */ |
2049 | static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | 1910 | static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) |
2050 | { | 1911 | { |
2051 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 1912 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
2052 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
2053 | struct page *failed_page; | ||
2054 | int err; | 1913 | int err; |
2055 | 1914 | ||
2056 | sci->sc_stage.scnt = NILFS_ST_INIT; | 1915 | sci->sc_stage.scnt = NILFS_ST_INIT; |
1916 | sci->sc_cno = nilfs->ns_cno; | ||
2057 | 1917 | ||
2058 | err = nilfs_segctor_check_in_files(sci, sbi); | 1918 | err = nilfs_segctor_collect_dirty_files(sci, nilfs); |
2059 | if (unlikely(err)) | 1919 | if (unlikely(err)) |
2060 | goto out; | 1920 | goto out; |
2061 | 1921 | ||
2062 | if (nilfs_test_metadata_dirty(sbi)) | 1922 | if (nilfs_test_metadata_dirty(nilfs, sci->sc_root)) |
2063 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 1923 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
2064 | 1924 | ||
2065 | if (nilfs_segctor_clean(sci)) | 1925 | if (nilfs_segctor_clean(sci)) |
@@ -2091,7 +1951,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2091 | goto failed; | 1951 | goto failed; |
2092 | 1952 | ||
2093 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) | 1953 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) |
2094 | nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); | 1954 | nilfs_segctor_fill_in_file_bmap(sci); |
2095 | 1955 | ||
2096 | if (mode == SC_LSEG_SR && | 1956 | if (mode == SC_LSEG_SR && |
2097 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { | 1957 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { |
@@ -2104,11 +1964,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2104 | nilfs_segctor_update_segusage(sci, nilfs->ns_sufile); | 1964 | nilfs_segctor_update_segusage(sci, nilfs->ns_sufile); |
2105 | 1965 | ||
2106 | /* Write partial segments */ | 1966 | /* Write partial segments */ |
2107 | err = nilfs_segctor_prepare_write(sci, &failed_page); | 1967 | nilfs_segctor_prepare_write(sci); |
2108 | if (err) { | ||
2109 | nilfs_abort_logs(&sci->sc_segbufs, failed_page, err); | ||
2110 | goto failed_to_write; | ||
2111 | } | ||
2112 | 1968 | ||
2113 | nilfs_add_checksums_on_logs(&sci->sc_segbufs, | 1969 | nilfs_add_checksums_on_logs(&sci->sc_segbufs, |
2114 | nilfs->ns_crc_seed); | 1970 | nilfs->ns_crc_seed); |
@@ -2133,7 +1989,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2133 | } while (sci->sc_stage.scnt != NILFS_ST_DONE); | 1989 | } while (sci->sc_stage.scnt != NILFS_ST_DONE); |
2134 | 1990 | ||
2135 | out: | 1991 | out: |
2136 | nilfs_segctor_check_out_files(sci, sbi); | 1992 | nilfs_segctor_drop_written_files(sci, nilfs); |
2137 | return err; | 1993 | return err; |
2138 | 1994 | ||
2139 | failed_to_write: | 1995 | failed_to_write: |
@@ -2186,8 +2042,8 @@ static void nilfs_segctor_do_flush(struct nilfs_sc_info *sci, int bn) | |||
2186 | */ | 2042 | */ |
2187 | void nilfs_flush_segment(struct super_block *sb, ino_t ino) | 2043 | void nilfs_flush_segment(struct super_block *sb, ino_t ino) |
2188 | { | 2044 | { |
2189 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 2045 | struct the_nilfs *nilfs = sb->s_fs_info; |
2190 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2046 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
2191 | 2047 | ||
2192 | if (!sci || nilfs_doing_construction()) | 2048 | if (!sci || nilfs_doing_construction()) |
2193 | return; | 2049 | return; |
@@ -2276,8 +2132,8 @@ static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err) | |||
2276 | */ | 2132 | */ |
2277 | int nilfs_construct_segment(struct super_block *sb) | 2133 | int nilfs_construct_segment(struct super_block *sb) |
2278 | { | 2134 | { |
2279 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 2135 | struct the_nilfs *nilfs = sb->s_fs_info; |
2280 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2136 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
2281 | struct nilfs_transaction_info *ti; | 2137 | struct nilfs_transaction_info *ti; |
2282 | int err; | 2138 | int err; |
2283 | 2139 | ||
@@ -2314,8 +2170,8 @@ int nilfs_construct_segment(struct super_block *sb) | |||
2314 | int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | 2170 | int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, |
2315 | loff_t start, loff_t end) | 2171 | loff_t start, loff_t end) |
2316 | { | 2172 | { |
2317 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 2173 | struct the_nilfs *nilfs = sb->s_fs_info; |
2318 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2174 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
2319 | struct nilfs_inode_info *ii; | 2175 | struct nilfs_inode_info *ii; |
2320 | struct nilfs_transaction_info ti; | 2176 | struct nilfs_transaction_info ti; |
2321 | int err = 0; | 2177 | int err = 0; |
@@ -2323,33 +2179,33 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | |||
2323 | if (!sci) | 2179 | if (!sci) |
2324 | return -EROFS; | 2180 | return -EROFS; |
2325 | 2181 | ||
2326 | nilfs_transaction_lock(sbi, &ti, 0); | 2182 | nilfs_transaction_lock(sb, &ti, 0); |
2327 | 2183 | ||
2328 | ii = NILFS_I(inode); | 2184 | ii = NILFS_I(inode); |
2329 | if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) || | 2185 | if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) || |
2330 | nilfs_test_opt(sbi, STRICT_ORDER) || | 2186 | nilfs_test_opt(nilfs, STRICT_ORDER) || |
2331 | test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) || | 2187 | test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) || |
2332 | nilfs_discontinued(sbi->s_nilfs)) { | 2188 | nilfs_discontinued(nilfs)) { |
2333 | nilfs_transaction_unlock(sbi); | 2189 | nilfs_transaction_unlock(sb); |
2334 | err = nilfs_segctor_sync(sci); | 2190 | err = nilfs_segctor_sync(sci); |
2335 | return err; | 2191 | return err; |
2336 | } | 2192 | } |
2337 | 2193 | ||
2338 | spin_lock(&sbi->s_inode_lock); | 2194 | spin_lock(&nilfs->ns_inode_lock); |
2339 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && | 2195 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && |
2340 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { | 2196 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { |
2341 | spin_unlock(&sbi->s_inode_lock); | 2197 | spin_unlock(&nilfs->ns_inode_lock); |
2342 | nilfs_transaction_unlock(sbi); | 2198 | nilfs_transaction_unlock(sb); |
2343 | return 0; | 2199 | return 0; |
2344 | } | 2200 | } |
2345 | spin_unlock(&sbi->s_inode_lock); | 2201 | spin_unlock(&nilfs->ns_inode_lock); |
2346 | sci->sc_dsync_inode = ii; | 2202 | sci->sc_dsync_inode = ii; |
2347 | sci->sc_dsync_start = start; | 2203 | sci->sc_dsync_start = start; |
2348 | sci->sc_dsync_end = end; | 2204 | sci->sc_dsync_end = end; |
2349 | 2205 | ||
2350 | err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC); | 2206 | err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC); |
2351 | 2207 | ||
2352 | nilfs_transaction_unlock(sbi); | 2208 | nilfs_transaction_unlock(sb); |
2353 | return err; | 2209 | return err; |
2354 | } | 2210 | } |
2355 | 2211 | ||
@@ -2405,8 +2261,7 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) | |||
2405 | */ | 2261 | */ |
2406 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | 2262 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) |
2407 | { | 2263 | { |
2408 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2264 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
2409 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
2410 | struct nilfs_super_block **sbp; | 2265 | struct nilfs_super_block **sbp; |
2411 | int err = 0; | 2266 | int err = 0; |
2412 | 2267 | ||
@@ -2424,11 +2279,12 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | |||
2424 | nilfs_discontinued(nilfs)) { | 2279 | nilfs_discontinued(nilfs)) { |
2425 | down_write(&nilfs->ns_sem); | 2280 | down_write(&nilfs->ns_sem); |
2426 | err = -EIO; | 2281 | err = -EIO; |
2427 | sbp = nilfs_prepare_super(sbi, | 2282 | sbp = nilfs_prepare_super(sci->sc_super, |
2428 | nilfs_sb_will_flip(nilfs)); | 2283 | nilfs_sb_will_flip(nilfs)); |
2429 | if (likely(sbp)) { | 2284 | if (likely(sbp)) { |
2430 | nilfs_set_log_cursor(sbp[0], nilfs); | 2285 | nilfs_set_log_cursor(sbp[0], nilfs); |
2431 | err = nilfs_commit_super(sbi, NILFS_SB_COMMIT); | 2286 | err = nilfs_commit_super(sci->sc_super, |
2287 | NILFS_SB_COMMIT); | ||
2432 | } | 2288 | } |
2433 | up_write(&nilfs->ns_sem); | 2289 | up_write(&nilfs->ns_sem); |
2434 | } | 2290 | } |
@@ -2452,33 +2308,33 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head) | |||
2452 | list_for_each_entry_safe(ii, n, head, i_dirty) { | 2308 | list_for_each_entry_safe(ii, n, head, i_dirty) { |
2453 | if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) | 2309 | if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) |
2454 | continue; | 2310 | continue; |
2455 | hlist_del_init(&ii->vfs_inode.i_hash); | ||
2456 | list_del_init(&ii->i_dirty); | 2311 | list_del_init(&ii->i_dirty); |
2457 | nilfs_clear_gcinode(&ii->vfs_inode); | 2312 | iput(&ii->vfs_inode); |
2458 | } | 2313 | } |
2459 | } | 2314 | } |
2460 | 2315 | ||
2461 | int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | 2316 | int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, |
2462 | void **kbufs) | 2317 | void **kbufs) |
2463 | { | 2318 | { |
2464 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 2319 | struct the_nilfs *nilfs = sb->s_fs_info; |
2465 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2320 | struct nilfs_sc_info *sci = nilfs->ns_writer; |
2466 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
2467 | struct nilfs_transaction_info ti; | 2321 | struct nilfs_transaction_info ti; |
2468 | int err; | 2322 | int err; |
2469 | 2323 | ||
2470 | if (unlikely(!sci)) | 2324 | if (unlikely(!sci)) |
2471 | return -EROFS; | 2325 | return -EROFS; |
2472 | 2326 | ||
2473 | nilfs_transaction_lock(sbi, &ti, 1); | 2327 | nilfs_transaction_lock(sb, &ti, 1); |
2474 | 2328 | ||
2475 | err = nilfs_init_gcdat_inode(nilfs); | 2329 | err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat); |
2476 | if (unlikely(err)) | 2330 | if (unlikely(err)) |
2477 | goto out_unlock; | 2331 | goto out_unlock; |
2478 | 2332 | ||
2479 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); | 2333 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); |
2480 | if (unlikely(err)) | 2334 | if (unlikely(err)) { |
2335 | nilfs_mdt_restore_from_shadow_map(nilfs->ns_dat); | ||
2481 | goto out_unlock; | 2336 | goto out_unlock; |
2337 | } | ||
2482 | 2338 | ||
2483 | sci->sc_freesegs = kbufs[4]; | 2339 | sci->sc_freesegs = kbufs[4]; |
2484 | sci->sc_nfreesegs = argv[4].v_nmembs; | 2340 | sci->sc_nfreesegs = argv[4].v_nmembs; |
@@ -2496,31 +2352,30 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2496 | set_current_state(TASK_INTERRUPTIBLE); | 2352 | set_current_state(TASK_INTERRUPTIBLE); |
2497 | schedule_timeout(sci->sc_interval); | 2353 | schedule_timeout(sci->sc_interval); |
2498 | } | 2354 | } |
2499 | if (nilfs_test_opt(sbi, DISCARD)) { | 2355 | if (nilfs_test_opt(nilfs, DISCARD)) { |
2500 | int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs, | 2356 | int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs, |
2501 | sci->sc_nfreesegs); | 2357 | sci->sc_nfreesegs); |
2502 | if (ret) { | 2358 | if (ret) { |
2503 | printk(KERN_WARNING | 2359 | printk(KERN_WARNING |
2504 | "NILFS warning: error %d on discard request, " | 2360 | "NILFS warning: error %d on discard request, " |
2505 | "turning discards off for the device\n", ret); | 2361 | "turning discards off for the device\n", ret); |
2506 | nilfs_clear_opt(sbi, DISCARD); | 2362 | nilfs_clear_opt(nilfs, DISCARD); |
2507 | } | 2363 | } |
2508 | } | 2364 | } |
2509 | 2365 | ||
2510 | out_unlock: | 2366 | out_unlock: |
2511 | sci->sc_freesegs = NULL; | 2367 | sci->sc_freesegs = NULL; |
2512 | sci->sc_nfreesegs = 0; | 2368 | sci->sc_nfreesegs = 0; |
2513 | nilfs_clear_gcdat_inode(nilfs); | 2369 | nilfs_mdt_clear_shadow_map(nilfs->ns_dat); |
2514 | nilfs_transaction_unlock(sbi); | 2370 | nilfs_transaction_unlock(sb); |
2515 | return err; | 2371 | return err; |
2516 | } | 2372 | } |
2517 | 2373 | ||
2518 | static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode) | 2374 | static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode) |
2519 | { | 2375 | { |
2520 | struct nilfs_sb_info *sbi = sci->sc_sbi; | ||
2521 | struct nilfs_transaction_info ti; | 2376 | struct nilfs_transaction_info ti; |
2522 | 2377 | ||
2523 | nilfs_transaction_lock(sbi, &ti, 0); | 2378 | nilfs_transaction_lock(sci->sc_super, &ti, 0); |
2524 | nilfs_segctor_construct(sci, mode); | 2379 | nilfs_segctor_construct(sci, mode); |
2525 | 2380 | ||
2526 | /* | 2381 | /* |
@@ -2531,7 +2386,7 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode) | |||
2531 | if (test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags)) | 2386 | if (test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags)) |
2532 | nilfs_segctor_start_timer(sci); | 2387 | nilfs_segctor_start_timer(sci); |
2533 | 2388 | ||
2534 | nilfs_transaction_unlock(sbi); | 2389 | nilfs_transaction_unlock(sci->sc_super); |
2535 | } | 2390 | } |
2536 | 2391 | ||
2537 | static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci) | 2392 | static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci) |
@@ -2577,7 +2432,7 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci) | |||
2577 | static int nilfs_segctor_thread(void *arg) | 2432 | static int nilfs_segctor_thread(void *arg) |
2578 | { | 2433 | { |
2579 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; | 2434 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; |
2580 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | 2435 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
2581 | int timeout = 0; | 2436 | int timeout = 0; |
2582 | 2437 | ||
2583 | sci->sc_timer.data = (unsigned long)current; | 2438 | sci->sc_timer.data = (unsigned long)current; |
@@ -2672,6 +2527,8 @@ static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci) | |||
2672 | } | 2527 | } |
2673 | 2528 | ||
2674 | static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) | 2529 | static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) |
2530 | __acquires(&sci->sc_state_lock) | ||
2531 | __releases(&sci->sc_state_lock) | ||
2675 | { | 2532 | { |
2676 | sci->sc_state |= NILFS_SEGCTOR_QUIT; | 2533 | sci->sc_state |= NILFS_SEGCTOR_QUIT; |
2677 | 2534 | ||
@@ -2686,16 +2543,20 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) | |||
2686 | /* | 2543 | /* |
2687 | * Setup & clean-up functions | 2544 | * Setup & clean-up functions |
2688 | */ | 2545 | */ |
2689 | static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | 2546 | static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, |
2547 | struct nilfs_root *root) | ||
2690 | { | 2548 | { |
2549 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
2691 | struct nilfs_sc_info *sci; | 2550 | struct nilfs_sc_info *sci; |
2692 | 2551 | ||
2693 | sci = kzalloc(sizeof(*sci), GFP_KERNEL); | 2552 | sci = kzalloc(sizeof(*sci), GFP_KERNEL); |
2694 | if (!sci) | 2553 | if (!sci) |
2695 | return NULL; | 2554 | return NULL; |
2696 | 2555 | ||
2697 | sci->sc_sbi = sbi; | 2556 | sci->sc_super = sb; |
2698 | sci->sc_super = sbi->s_super; | 2557 | |
2558 | nilfs_get_root(root); | ||
2559 | sci->sc_root = root; | ||
2699 | 2560 | ||
2700 | init_waitqueue_head(&sci->sc_wait_request); | 2561 | init_waitqueue_head(&sci->sc_wait_request); |
2701 | init_waitqueue_head(&sci->sc_wait_daemon); | 2562 | init_waitqueue_head(&sci->sc_wait_daemon); |
@@ -2705,17 +2566,16 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2705 | INIT_LIST_HEAD(&sci->sc_segbufs); | 2566 | INIT_LIST_HEAD(&sci->sc_segbufs); |
2706 | INIT_LIST_HEAD(&sci->sc_write_logs); | 2567 | INIT_LIST_HEAD(&sci->sc_write_logs); |
2707 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2568 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
2708 | INIT_LIST_HEAD(&sci->sc_copied_buffers); | ||
2709 | init_timer(&sci->sc_timer); | 2569 | init_timer(&sci->sc_timer); |
2710 | 2570 | ||
2711 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; | 2571 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; |
2712 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; | 2572 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; |
2713 | sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK; | 2573 | sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK; |
2714 | 2574 | ||
2715 | if (sbi->s_interval) | 2575 | if (nilfs->ns_interval) |
2716 | sci->sc_interval = sbi->s_interval; | 2576 | sci->sc_interval = HZ * nilfs->ns_interval; |
2717 | if (sbi->s_watermark) | 2577 | if (nilfs->ns_watermark) |
2718 | sci->sc_watermark = sbi->s_watermark; | 2578 | sci->sc_watermark = nilfs->ns_watermark; |
2719 | return sci; | 2579 | return sci; |
2720 | } | 2580 | } |
2721 | 2581 | ||
@@ -2726,12 +2586,11 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) | |||
2726 | /* The segctord thread was stopped and its timer was removed. | 2586 | /* The segctord thread was stopped and its timer was removed. |
2727 | But some tasks remain. */ | 2587 | But some tasks remain. */ |
2728 | do { | 2588 | do { |
2729 | struct nilfs_sb_info *sbi = sci->sc_sbi; | ||
2730 | struct nilfs_transaction_info ti; | 2589 | struct nilfs_transaction_info ti; |
2731 | 2590 | ||
2732 | nilfs_transaction_lock(sbi, &ti, 0); | 2591 | nilfs_transaction_lock(sci->sc_super, &ti, 0); |
2733 | ret = nilfs_segctor_construct(sci, SC_LSEG_SR); | 2592 | ret = nilfs_segctor_construct(sci, SC_LSEG_SR); |
2734 | nilfs_transaction_unlock(sbi); | 2593 | nilfs_transaction_unlock(sci->sc_super); |
2735 | 2594 | ||
2736 | } while (ret && retrycount-- > 0); | 2595 | } while (ret && retrycount-- > 0); |
2737 | } | 2596 | } |
@@ -2746,10 +2605,10 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) | |||
2746 | */ | 2605 | */ |
2747 | static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | 2606 | static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) |
2748 | { | 2607 | { |
2749 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2608 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
2750 | int flag; | 2609 | int flag; |
2751 | 2610 | ||
2752 | up_write(&sbi->s_nilfs->ns_segctor_sem); | 2611 | up_write(&nilfs->ns_segctor_sem); |
2753 | 2612 | ||
2754 | spin_lock(&sci->sc_state_lock); | 2613 | spin_lock(&sci->sc_state_lock); |
2755 | nilfs_segctor_kill_thread(sci); | 2614 | nilfs_segctor_kill_thread(sci); |
@@ -2760,92 +2619,89 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2760 | if (flag || !nilfs_segctor_confirm(sci)) | 2619 | if (flag || !nilfs_segctor_confirm(sci)) |
2761 | nilfs_segctor_write_out(sci); | 2620 | nilfs_segctor_write_out(sci); |
2762 | 2621 | ||
2763 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); | ||
2764 | |||
2765 | if (!list_empty(&sci->sc_dirty_files)) { | 2622 | if (!list_empty(&sci->sc_dirty_files)) { |
2766 | nilfs_warning(sbi->s_super, __func__, | 2623 | nilfs_warning(sci->sc_super, __func__, |
2767 | "dirty file(s) after the final construction\n"); | 2624 | "dirty file(s) after the final construction\n"); |
2768 | nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1); | 2625 | nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1); |
2769 | } | 2626 | } |
2770 | 2627 | ||
2771 | WARN_ON(!list_empty(&sci->sc_segbufs)); | 2628 | WARN_ON(!list_empty(&sci->sc_segbufs)); |
2772 | WARN_ON(!list_empty(&sci->sc_write_logs)); | 2629 | WARN_ON(!list_empty(&sci->sc_write_logs)); |
2773 | 2630 | ||
2774 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2631 | nilfs_put_root(sci->sc_root); |
2632 | |||
2633 | down_write(&nilfs->ns_segctor_sem); | ||
2775 | 2634 | ||
2776 | del_timer_sync(&sci->sc_timer); | 2635 | del_timer_sync(&sci->sc_timer); |
2777 | kfree(sci); | 2636 | kfree(sci); |
2778 | } | 2637 | } |
2779 | 2638 | ||
2780 | /** | 2639 | /** |
2781 | * nilfs_attach_segment_constructor - attach a segment constructor | 2640 | * nilfs_attach_log_writer - attach log writer |
2782 | * @sbi: nilfs_sb_info | 2641 | * @sb: super block instance |
2642 | * @root: root object of the current filesystem tree | ||
2783 | * | 2643 | * |
2784 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, | 2644 | * This allocates a log writer object, initializes it, and starts the |
2785 | * initializes it, and starts the segment constructor. | 2645 | * log writer. |
2786 | * | 2646 | * |
2787 | * Return Value: On success, 0 is returned. On error, one of the following | 2647 | * Return Value: On success, 0 is returned. On error, one of the following |
2788 | * negative error code is returned. | 2648 | * negative error code is returned. |
2789 | * | 2649 | * |
2790 | * %-ENOMEM - Insufficient memory available. | 2650 | * %-ENOMEM - Insufficient memory available. |
2791 | */ | 2651 | */ |
2792 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | 2652 | int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root) |
2793 | { | 2653 | { |
2794 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2654 | struct the_nilfs *nilfs = sb->s_fs_info; |
2795 | int err; | 2655 | int err; |
2796 | 2656 | ||
2797 | if (NILFS_SC(sbi)) { | 2657 | if (nilfs->ns_writer) { |
2798 | /* | 2658 | /* |
2799 | * This happens if the filesystem was remounted | 2659 | * This happens if the filesystem was remounted |
2800 | * read/write after nilfs_error degenerated it into a | 2660 | * read/write after nilfs_error degenerated it into a |
2801 | * read-only mount. | 2661 | * read-only mount. |
2802 | */ | 2662 | */ |
2803 | nilfs_detach_segment_constructor(sbi); | 2663 | nilfs_detach_log_writer(sb); |
2804 | } | 2664 | } |
2805 | 2665 | ||
2806 | sbi->s_sc_info = nilfs_segctor_new(sbi); | 2666 | nilfs->ns_writer = nilfs_segctor_new(sb, root); |
2807 | if (!sbi->s_sc_info) | 2667 | if (!nilfs->ns_writer) |
2808 | return -ENOMEM; | 2668 | return -ENOMEM; |
2809 | 2669 | ||
2810 | nilfs_attach_writer(nilfs, sbi); | 2670 | err = nilfs_segctor_start_thread(nilfs->ns_writer); |
2811 | err = nilfs_segctor_start_thread(NILFS_SC(sbi)); | ||
2812 | if (err) { | 2671 | if (err) { |
2813 | nilfs_detach_writer(nilfs, sbi); | 2672 | kfree(nilfs->ns_writer); |
2814 | kfree(sbi->s_sc_info); | 2673 | nilfs->ns_writer = NULL; |
2815 | sbi->s_sc_info = NULL; | ||
2816 | } | 2674 | } |
2817 | return err; | 2675 | return err; |
2818 | } | 2676 | } |
2819 | 2677 | ||
2820 | /** | 2678 | /** |
2821 | * nilfs_detach_segment_constructor - destroy the segment constructor | 2679 | * nilfs_detach_log_writer - destroy log writer |
2822 | * @sbi: nilfs_sb_info | 2680 | * @sb: super block instance |
2823 | * | 2681 | * |
2824 | * nilfs_detach_segment_constructor() kills the segment constructor daemon, | 2682 | * This kills log writer daemon, frees the log writer object, and |
2825 | * frees the struct nilfs_sc_info, and destroy the dirty file list. | 2683 | * destroys list of dirty files. |
2826 | */ | 2684 | */ |
2827 | void nilfs_detach_segment_constructor(struct nilfs_sb_info *sbi) | 2685 | void nilfs_detach_log_writer(struct super_block *sb) |
2828 | { | 2686 | { |
2829 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2687 | struct the_nilfs *nilfs = sb->s_fs_info; |
2830 | LIST_HEAD(garbage_list); | 2688 | LIST_HEAD(garbage_list); |
2831 | 2689 | ||
2832 | down_write(&nilfs->ns_segctor_sem); | 2690 | down_write(&nilfs->ns_segctor_sem); |
2833 | if (NILFS_SC(sbi)) { | 2691 | if (nilfs->ns_writer) { |
2834 | nilfs_segctor_destroy(NILFS_SC(sbi)); | 2692 | nilfs_segctor_destroy(nilfs->ns_writer); |
2835 | sbi->s_sc_info = NULL; | 2693 | nilfs->ns_writer = NULL; |
2836 | } | 2694 | } |
2837 | 2695 | ||
2838 | /* Force to free the list of dirty files */ | 2696 | /* Force to free the list of dirty files */ |
2839 | spin_lock(&sbi->s_inode_lock); | 2697 | spin_lock(&nilfs->ns_inode_lock); |
2840 | if (!list_empty(&sbi->s_dirty_files)) { | 2698 | if (!list_empty(&nilfs->ns_dirty_files)) { |
2841 | list_splice_init(&sbi->s_dirty_files, &garbage_list); | 2699 | list_splice_init(&nilfs->ns_dirty_files, &garbage_list); |
2842 | nilfs_warning(sbi->s_super, __func__, | 2700 | nilfs_warning(sb, __func__, |
2843 | "Non empty dirty list after the last " | 2701 | "Hit dirty file after stopped log writer\n"); |
2844 | "segment construction\n"); | 2702 | } |
2845 | } | 2703 | spin_unlock(&nilfs->ns_inode_lock); |
2846 | spin_unlock(&sbi->s_inode_lock); | ||
2847 | up_write(&nilfs->ns_segctor_sem); | 2704 | up_write(&nilfs->ns_segctor_sem); |
2848 | 2705 | ||
2849 | nilfs_dispose_list(sbi, &garbage_list, 1); | 2706 | nilfs_dispose_list(nilfs, &garbage_list, 1); |
2850 | nilfs_detach_writer(nilfs, sbi); | ||
2851 | } | 2707 | } |