recovery.c (d2dd01de9924ae24afeba5aa5bc2e08287701df6) recovery.c (654137dd46bc7e9f088a4a551a2b77a8541dfdb8)
1/*
2 * recovery.c - NILFS recovery logic
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 14 unchanged lines hidden (view full) ---

23#include <linux/buffer_head.h>
24#include <linux/blkdev.h>
25#include <linux/swap.h>
26#include <linux/crc32.h>
27#include "nilfs.h"
28#include "segment.h"
29#include "sufile.h"
30#include "page.h"
1/*
2 * recovery.c - NILFS recovery logic
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 14 unchanged lines hidden (view full) ---

23#include <linux/buffer_head.h>
24#include <linux/blkdev.h>
25#include <linux/swap.h>
26#include <linux/crc32.h>
27#include "nilfs.h"
28#include "segment.h"
29#include "sufile.h"
30#include "page.h"
31#include "seglist.h"
32#include "segbuf.h"
33
34/*
35 * Segment check result
36 */
37enum {
38 NILFS_SEG_VALID,
39 NILFS_SEG_NO_SUPER_ROOT,

--- 350 unchanged lines hidden (view full) ---

390 struct nilfs_recovery_block *rb
391 = list_entry(head->next,
392 struct nilfs_recovery_block, list);
393 list_del(&rb->list);
394 kfree(rb);
395 }
396}
397
31#include "segbuf.h"
32
33/*
34 * Segment check result
35 */
36enum {
37 NILFS_SEG_VALID,
38 NILFS_SEG_NO_SUPER_ROOT,

--- 350 unchanged lines hidden (view full) ---

389 struct nilfs_recovery_block *rb
390 = list_entry(head->next,
391 struct nilfs_recovery_block, list);
392 list_del(&rb->list);
393 kfree(rb);
394 }
395}
396
397struct nilfs_segment_entry {
398 struct list_head list;
399 __u64 segnum;
400};
401
402static int nilfs_segment_list_add(struct list_head *head, __u64 segnum)
403{
404 struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
405
406 if (unlikely(!ent))
407 return -ENOMEM;
408
409 ent->segnum = segnum;
410 INIT_LIST_HEAD(&ent->list);
411 list_add_tail(&ent->list, head);
412 return 0;
413}
414
398void nilfs_dispose_segment_list(struct list_head *head)
399{
400 while (!list_empty(head)) {
401 struct nilfs_segment_entry *ent
402 = list_entry(head->next,
403 struct nilfs_segment_entry, list);
404 list_del(&ent->list);
415void nilfs_dispose_segment_list(struct list_head *head)
416{
417 while (!list_empty(head)) {
418 struct nilfs_segment_entry *ent
419 = list_entry(head->next,
420 struct nilfs_segment_entry, list);
421 list_del(&ent->list);
405 nilfs_free_segment_entry(ent);
422 kfree(ent);
406 }
407}
408
409static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
410 struct nilfs_sb_info *sbi,
411 struct nilfs_recovery_info *ri)
412{
413 struct list_head *head = &ri->ri_used_segments;

--- 12 unchanged lines hidden (view full) ---

426 /*
427 * Releasing the next segment of the latest super root.
428 * The next segment is invalidated by this recovery.
429 */
430 err = nilfs_sufile_free(sufile, segnum[1]);
431 if (unlikely(err))
432 goto failed;
433
423 }
424}
425
426static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
427 struct nilfs_sb_info *sbi,
428 struct nilfs_recovery_info *ri)
429{
430 struct list_head *head = &ri->ri_used_segments;

--- 12 unchanged lines hidden (view full) ---

443 /*
444 * Releasing the next segment of the latest super root.
445 * The next segment is invalidated by this recovery.
446 */
447 err = nilfs_sufile_free(sufile, segnum[1]);
448 if (unlikely(err))
449 goto failed;
450
434 err = -ENOMEM;
435 for (i = 1; i < 4; i++) {
451 for (i = 1; i < 4; i++) {
436 ent = nilfs_alloc_segment_entry(segnum[i]);
437 if (unlikely(!ent))
452 err = nilfs_segment_list_add(head, segnum[i]);
453 if (unlikely(err))
438 goto failed;
454 goto failed;
439 list_add_tail(&ent->list, head);
440 }
441
442 /*
443 * Collecting segments written after the latest super root.
444 * These are marked dirty to avoid being reallocated in the next write.
445 */
446 list_for_each_entry_safe(ent, n, head, list) {
447 if (ent->segnum != segnum[0]) {
448 err = nilfs_sufile_scrap(sufile, ent->segnum);
449 if (unlikely(err))
450 goto failed;
451 }
452 list_del(&ent->list);
455 }
456
457 /*
458 * Collecting segments written after the latest super root.
459 * These are marked dirty to avoid being reallocated in the next write.
460 */
461 list_for_each_entry_safe(ent, n, head, list) {
462 if (ent->segnum != segnum[0]) {
463 err = nilfs_sufile_scrap(sufile, ent->segnum);
464 if (unlikely(err))
465 goto failed;
466 }
467 list_del(&ent->list);
453 nilfs_free_segment_entry(ent);
468 kfree(ent);
454 }
455
456 /* Allocate new segments for recovery */
457 err = nilfs_sufile_alloc(sufile, &segnum[0]);
458 if (unlikely(err))
459 goto failed;
460
461 nilfs->ns_pseg_offset = 0;

--- 324 unchanged lines hidden (view full) ---

786 struct nilfs_recovery_info *ri)
787{
788 struct nilfs_segsum_info ssi;
789 sector_t pseg_start, pseg_end, sr_pseg_start = 0;
790 sector_t seg_start, seg_end; /* range of full segment (block number) */
791 u64 seg_seq;
792 __u64 segnum, nextnum = 0;
793 __u64 cno;
469 }
470
471 /* Allocate new segments for recovery */
472 err = nilfs_sufile_alloc(sufile, &segnum[0]);
473 if (unlikely(err))
474 goto failed;
475
476 nilfs->ns_pseg_offset = 0;

--- 324 unchanged lines hidden (view full) ---

801 struct nilfs_recovery_info *ri)
802{
803 struct nilfs_segsum_info ssi;
804 sector_t pseg_start, pseg_end, sr_pseg_start = 0;
805 sector_t seg_start, seg_end; /* range of full segment (block number) */
806 u64 seg_seq;
807 __u64 segnum, nextnum = 0;
808 __u64 cno;
794 struct nilfs_segment_entry *ent;
795 LIST_HEAD(segments);
796 int empty_seg = 0, scan_newer = 0;
797 int ret;
798
799 pseg_start = nilfs->ns_last_pseg;
800 seg_seq = nilfs->ns_last_seq;
801 cno = nilfs->ns_last_cno;
802 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start);

--- 84 unchanged lines hidden (view full) ---

887 */
888 goto failed;
889
890 feed_segment:
891 /* Looking to the next full segment */
892 if (empty_seg++)
893 goto super_root_found; /* found a valid super root */
894
809 LIST_HEAD(segments);
810 int empty_seg = 0, scan_newer = 0;
811 int ret;
812
813 pseg_start = nilfs->ns_last_pseg;
814 seg_seq = nilfs->ns_last_seq;
815 cno = nilfs->ns_last_cno;
816 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start);

--- 84 unchanged lines hidden (view full) ---

901 */
902 goto failed;
903
904 feed_segment:
905 /* Looking to the next full segment */
906 if (empty_seg++)
907 goto super_root_found; /* found a valid super root */
908
895 ent = nilfs_alloc_segment_entry(segnum);
896 if (unlikely(!ent)) {
897 ret = -ENOMEM;
909 ret = nilfs_segment_list_add(&segments, segnum);
910 if (unlikely(ret))
898 goto failed;
911 goto failed;
899 }
900 list_add_tail(&ent->list, &segments);
901
902 seg_seq++;
903 segnum = nextnum;
904 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
905 pseg_start = seg_start;
906 }
907
908 super_root_found:
909 /* Updating pointers relating to the latest checkpoint */
910 list_splice(&segments, ri->ri_used_segments.prev);
911 nilfs->ns_last_pseg = sr_pseg_start;
912 nilfs->ns_last_seq = nilfs->ns_seg_seq;
913 nilfs->ns_last_cno = ri->ri_cno;
914 return 0;
915
916 failed:
917 nilfs_dispose_segment_list(&segments);
918 return (ret < 0) ? ret : nilfs_warn_segment_error(ret);
919}
912
913 seg_seq++;
914 segnum = nextnum;
915 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
916 pseg_start = seg_start;
917 }
918
919 super_root_found:
920 /* Updating pointers relating to the latest checkpoint */
921 list_splice(&segments, ri->ri_used_segments.prev);
922 nilfs->ns_last_pseg = sr_pseg_start;
923 nilfs->ns_last_seq = nilfs->ns_seg_seq;
924 nilfs->ns_last_cno = ri->ri_cno;
925 return 0;
926
927 failed:
928 nilfs_dispose_segment_list(&segments);
929 return (ret < 0) ? ret : nilfs_warn_segment_error(ret);
930}