[f2fs-dev] [PATCH 3/5] fsck.f2fs: unify the updating of superblocks
Rename write_superblock() to update_superblock() and make it support updating specified one superblock or both two superblocks, then unify all places where sb needs to be updated. Signed-off-by: Junling Zheng --- fsck/fsck.h | 12 ++- fsck/mount.c | 94 +++ fsck/resize.c | 20 ++- 3 files changed, 47 insertions(+), 79 deletions(-) diff --git a/fsck/fsck.h b/fsck/fsck.h index 6042e68..bdd7f8d 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -32,6 +32,16 @@ enum { EUNKNOWN_ARG, }; +enum SB_ADDR { + SB_ADDR_0, + SB_ADDR_1, + SB_ADDR_MAX, +}; + +#define SB_FIRST (1 << SB_ADDR_0) +#define SB_SECOND (1 << SB_ADDR_1) +#define SB_ALL (SB_FIRST | SB_SECOND) + /* fsck.c */ struct orphan_info { u32 nr_inodes; @@ -178,7 +188,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, int); extern void write_curseg_info(struct f2fs_sb_info *); extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int); extern void write_checkpoint(struct f2fs_sb_info *); -extern void write_superblock(struct f2fs_super_block *); +extern void update_superblock(struct f2fs_super_block *, int); extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t); extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t); diff --git a/fsck/mount.c b/fsck/mount.c index 1daef75..74ff7c6 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -475,8 +475,28 @@ void print_sb_state(struct f2fs_super_block *sb) MSG(0, "\n"); } +void update_superblock(struct f2fs_super_block *sb, int sb_mask) +{ + int index, ret; + u_int8_t *buf; + + buf = calloc(BLOCK_SZ, 1); + ASSERT(buf); + + memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb)); + for (index = 0; index < SB_ADDR_MAX; index++) { + if ((1 << index) & sb_mask) { + ret = dev_write_block(buf, index); + ASSERT(ret >= 0); + } + } + + free(buf); + DBG(0, "Info: Done to update superblock\n"); +} + static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, - u64 offset) + enum SB_ADDR sb_addr) { u32 segment0_blkaddr = get_sb(segment0_blkaddr); u32 cp_blkaddr = get_sb(cp_blkaddr); @@ -542,14 +562,11 @@ static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, segment_count_main << log_blocks_per_seg); return -1; } else if (main_end_blkaddr < seg_end_blkaddr) { - int err; - set_sb(segment_count, (main_end_blkaddr - segment0_blkaddr) >> log_blocks_per_seg); - err = dev_write(sb, offset, sizeof(struct f2fs_super_block)); - MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n", - err ? "failed": "done", + update_superblock(sb, 1 << sb_addr); + MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n", main_blkaddr, segment0_blkaddr + (segment_count << log_blocks_per_seg), @@ -558,7 +575,7 @@ static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, return 0; } -int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) +int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr) { unsigned int blocksize; @@ -600,30 +617,24 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) if (get_sb(segment_count) > F2FS_MAX_SEGMENT) return -1; - if (sanity_check_area_boundary(sb, offset)) + if (sanity_check_area_boundary(sb, sb_addr)) return -1; return 0; } -int validate_super_block(struct f2fs_sb_info *sbi, int block) +int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr) { - u64 offset; char buf[F2FS_BLKSIZE]; sbi->raw_super = malloc(sizeof(struct f2fs_super_block)); - if (block == 0) - offset = F2FS_SUPER_OFFSET; - else - offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET; - - if (dev_read_block(buf, block)) + if (dev_read_block(buf, sb_addr)) return -1; memcpy(sbi->raw_super, buf + F2FS_SUPER_OFFSET, sizeof(struct f2fs_super_block)); - if (!sanity_check_raw_super(sbi->raw_super, offset)) { + if (!sanity_check_raw_super(sbi->raw_super, sb_addr)) { /* get kernel version */ if (c.kd >= 0) { dev_read_version(c.version, 0, VERSION_LEN); @@ -642,13 +653,9 @@ int validate_super_block(struct f2fs_sb_info *sbi, int block)
Re: [f2fs-dev] [PATCH 3/5] fsck.f2fs: unify the updating of superblocks
On 09/19, Junling Zheng wrote: > Rename write_superblock() to update_superblock() and make it support updating > specified one superblock or both two superblocks, then unify all places where > sb needs to be updated. > > Signed-off-by: Junling Zheng > --- > fsck/fsck.h | 12 ++- > fsck/mount.c | 94 +++ > fsck/resize.c | 20 ++- > 3 files changed, 47 insertions(+), 79 deletions(-) > > diff --git a/fsck/fsck.h b/fsck/fsck.h > index 6042e68..bdd7f8d 100644 > --- a/fsck/fsck.h > +++ b/fsck/fsck.h > @@ -32,6 +32,16 @@ enum { > EUNKNOWN_ARG, > }; > > +enum SB_ADDR { > + SB_ADDR_0, > + SB_ADDR_1, > + SB_ADDR_MAX, SB0_ADDR = 0, SB1_ADDR, SB_MAX_ADDR, > +}; > + #define SB_MASK(i) (1 << i) #define SB_MASK_ALL (SB_MASK(SB0_ADDR) | SB_MASK(SB1_ADDR)) > +#define SB_FIRST (1 << SB_ADDR_0) > +#define SB_SECOND(1 << SB_ADDR_1) > +#define SB_ALL (SB_FIRST | SB_SECOND) > + > /* fsck.c */ > struct orphan_info { > u32 nr_inodes; > @@ -178,7 +188,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, > int); > extern void write_curseg_info(struct f2fs_sb_info *); > extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int); > extern void write_checkpoint(struct f2fs_sb_info *); > -extern void write_superblock(struct f2fs_super_block *); > +extern void update_superblock(struct f2fs_super_block *, int); > extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t); > extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t); > > diff --git a/fsck/mount.c b/fsck/mount.c > index 1daef75..74ff7c6 100644 > --- a/fsck/mount.c > +++ b/fsck/mount.c > @@ -475,8 +475,28 @@ void print_sb_state(struct f2fs_super_block *sb) > MSG(0, "\n"); > } > > +void update_superblock(struct f2fs_super_block *sb, int sb_mask) > +{ > + int index, ret; > + u_int8_t *buf; > + > + buf = calloc(BLOCK_SZ, 1); > + ASSERT(buf); > + > + memcpy(buf + F2FS_SUPER_OFFSET, sb, sizeof(*sb)); > + for (index = 0; index < SB_ADDR_MAX; index++) { for (addr = SB0_ADDR; addr < SB_MAX_ADDR; addr++) > + if ((1 << index) & sb_mask) { if (SB_MASK(addr) & sb_mask) { > + ret = dev_write_block(buf, index); > + ASSERT(ret >= 0); > + } > + } > + > + free(buf); > + DBG(0, "Info: Done to update superblock\n"); > +} > + > static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, > - u64 offset) > + enum SB_ADDR sb_addr) > { > u32 segment0_blkaddr = get_sb(segment0_blkaddr); > u32 cp_blkaddr = get_sb(cp_blkaddr); > @@ -542,14 +562,11 @@ static inline int sanity_check_area_boundary(struct > f2fs_super_block *sb, > segment_count_main << log_blocks_per_seg); > return -1; > } else if (main_end_blkaddr < seg_end_blkaddr) { > - int err; > - > set_sb(segment_count, (main_end_blkaddr - > segment0_blkaddr) >> log_blocks_per_seg); > > - err = dev_write(sb, offset, sizeof(struct f2fs_super_block)); > - MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n", > - err ? "failed": "done", > + update_superblock(sb, 1 << sb_addr); update_superblock(sb, SB_MASK(sb_addr)); > + MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n", > main_blkaddr, > segment0_blkaddr + > (segment_count << log_blocks_per_seg), > @@ -558,7 +575,7 @@ static inline int sanity_check_area_boundary(struct > f2fs_super_block *sb, > return 0; > } > > -int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) > +int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr) > { > unsigned int blocksize; > > @@ -600,30 +617,24 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, > u64 offset) > if (get_sb(segment_count) > F2FS_MAX_SEGMENT) > return -1; > > - if (sanity_check_area_boundary(sb, offset)) > + if (sanity_check_area_boundary(sb, sb_addr)) > return -1; > return 0; > } > > -int validate_super_block(struct f2fs_sb_info *sbi, int block) > +int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr) > { > - u64 offset; > char buf[F2FS_BLKSIZE]; > > sbi->raw_super = malloc(sizeof(struct f2fs_super_block)); > > - if (block == 0) > - offset = F2FS_SUPER_OFFSET; > - else > - offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET; > - > - if (dev_read_block(buf, block)) > + if (dev_read_block(buf, sb_addr)) > return -1; > >