1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| int f2fs_resize(struct f2fs_sb_info *sbi) { struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi); struct f2fs_super_block new_sb_raw; struct f2fs_super_block *new_sb = &new_sb_raw; block_t end_blkaddr, old_main_blkaddr, new_main_blkaddr; unsigned int offset; unsigned int offset_seg = 0; int err = -1;
flush_journal_entries(sbi); memcpy(new_sb, F2FS_RAW_SUPER(sbi), sizeof(*new_sb)); if (get_new_sb(new_sb)) return -1;
if (get_sb(segment_count_nat) > get_newsb(segment_count_nat)) { err = shrink_nats(sbi, new_sb); if (err) { MSG(0, "\tError: Failed to shrink NATs\n"); return err; } } print_raw_sb_info(sb); print_raw_sb_info(new_sb);
old_main_blkaddr = get_sb(main_blkaddr); new_main_blkaddr = get_newsb(main_blkaddr);
offset = new_main_blkaddr - old_main_blkaddr; end_blkaddr = (get_sb(segment_count_main) << get_sb(log_blocks_per_seg)) + get_sb(main_blkaddr); err = -EAGAIN; if (new_main_blkaddr < end_blkaddr) { err = f2fs_defragment(sbi, old_main_blkaddr, offset, new_main_blkaddr, 0); if (!err) offset_seg = offset >> get_sb(log_blocks_per_seg); MSG(0, "Try to do defragement: %s\n", err ? "Skip": "Done"); } if (err) migrate_main(sbi, offset);
migrate_ssa(sbi, new_sb, offset_seg); migrate_nat(sbi, new_sb); migrate_sit(sbi, new_sb, offset_seg); rebuild_checkpoint(sbi, new_sb, offset_seg); rebuild_superblock(new_sb); return 0; }
|