summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rosenberg <drosen@google.com>2014-08-15 19:20:33 -0700
committerDaniel Rosenberg <drosen@google.com>2014-08-18 12:33:36 -0700
commitaff4a27b96454d6868a7a22974f560147a13188f (patch)
tree46988fd0bbb3ecfc1f6f232ad173592d959763d1
parentb1c010d64b97131cf87bdf1968962f12458bc247 (diff)
downloadextras-aff4a27b96454d6868a7a22974f560147a13188f.tar.gz
f2fs_sparseblock: Correctly handle f2fs checkpoint flags
Bug: 15749466 Change-Id: I31ecefc0cf2ebfba1652a8b87fd70b045624ffa4 Signed-off-by: Daniel Rosenberg <drosen@google.com>
-rw-r--r--f2fs_utils/f2fs_sparseblock.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/f2fs_utils/f2fs_sparseblock.c b/f2fs_utils/f2fs_sparseblock.c
index fe5cbf97..46d1f72a 100644
--- a/f2fs_utils/f2fs_sparseblock.c
+++ b/f2fs_utils/f2fs_sparseblock.c
@@ -323,14 +323,43 @@ static int gather_sit_info(int fd, struct f2fs_info *info)
return 0;
}
+static inline int is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+{
+ unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
+ return !!(ckpt_flags & f);
+}
+
+static inline u64 sum_blk_addr(struct f2fs_checkpoint *cp, struct f2fs_info *info, int base, int type)
+{
+ return info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_total_block_count)
+ - (base + 1) + type;
+}
+
static int get_sit_summary(int fd, struct f2fs_info *info, struct f2fs_checkpoint *cp)
{
- char buffer[4096];
- read_structure_blk(fd, info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_start_sum), &buffer, 1);
+ char buffer[F2FS_BLKSIZE];
+
info->sit_sums = calloc(1, sizeof(struct f2fs_summary_block));
if (!info->sit_sums)
return -1;
- memcpy(&info->sit_sums->n_sits, &buffer[SUM_JOURNAL_SIZE], SUM_JOURNAL_SIZE);
+
+ /* CURSEG_COLD_DATA where the journaled SIT entries are. */
+ if (is_set_ckpt_flags(cp, CP_COMPACT_SUM_FLAG)) {
+ if (read_structure_blk(fd, info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_start_sum), buffer, 1))
+ return -1;
+ memcpy(&info->sit_sums->n_sits, &buffer[SUM_JOURNAL_SIZE], SUM_JOURNAL_SIZE);
+ } else {
+ u64 blk_addr;
+ if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
+ blk_addr = sum_blk_addr(cp, info, NR_CURSEG_TYPE, CURSEG_COLD_DATA);
+ else
+ blk_addr = sum_blk_addr(cp, info, NR_CURSEG_DATA_TYPE, CURSEG_COLD_DATA);
+
+ if (read_structure_blk(fd, blk_addr, buffer, 1))
+ return -1;
+
+ memcpy(info->sit_sums, buffer, sizeof(struct f2fs_summary_block));
+ }
return 0;
}