Upgrade f2fs-tools to 5da4e5241503b385e4a7e75b1b2bb3367b38be96

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/f2fs-tools
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: Ibe4de8495cd39c0d59915a90af970ad7da849a64
diff --git a/METADATA b/METADATA
index 053806a..5ab453a 100644
--- a/METADATA
+++ b/METADATA
@@ -8,13 +8,13 @@
   license_type: RESTRICTED
   last_upgrade_date {
     year: 2024
-    month: 3
-    day: 7
+    month: 4
+    day: 9
   }
   homepage: "https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git/"
   identifier {
     type: "Git"
     value: "https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git"
-    version: "efcff4bc169fbcb7276769ab0ad5444b1df33a70"
+    version: "5da4e5241503b385e4a7e75b1b2bb3367b38be96"
   }
 }
diff --git a/fsck/fsck.c b/fsck/fsck.c
index a42b597..5d345d0 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -3288,38 +3288,39 @@
 
 	last_valid_blkoff = last_vblk_off_in_zone(sbi, zone_segno);
 
-	/*
-	 * When there is no valid block in the zone, check write pointer is
-	 * at zone start. If not, reset the write pointer.
-	 */
-	if (last_valid_blkoff < 0 &&
-	    blk_zone_wp_sector(blkz) != blk_zone_sector(blkz)) {
-		if (!c.fix_on) {
-			MSG(0, "Inconsistent write pointer: wp[0x%x,0x%x]\n",
-			    wp_segno, wp_blkoff);
-			fsck->chk.wp_inconsistent_zones++;
-			return 0;
-		}
-
-		FIX_MSG("Reset write pointer of zone at segment 0x%x",
-			zone_segno);
-		ret = f2fs_reset_zone(wpd->dev_index, blkz);
-		if (ret) {
-			printf("[FSCK] Write pointer reset failed: %s\n",
-			       dev->path);
-			return ret;
-		}
-		fsck->chk.wp_fixed = 1;
-		return 0;
-	}
-
 	/* if a curseg points to the zone, do not finishing zone */
 	for (i = 0; i < NO_CHECK_TYPE; i++) {
 		struct curseg_info *cs = CURSEG_I(sbi, i);
 
 		if (zone_segno <= cs->segno &&
-				cs->segno < zone_segno + segs_per_zone)
+				cs->segno < zone_segno + segs_per_zone) {
+			/*
+			 * When there is no valid block in the zone, check
+			 * write pointer is at zone start. If not, reset
+			 * the write pointer.
+			 */
+			if (last_valid_blkoff < 0 &&
+			    blk_zone_wp_sector(blkz) != blk_zone_sector(blkz)) {
+				if (!c.fix_on) {
+					MSG(0, "Inconsistent write pointer: "
+					       "wp[0x%x,0x%x]\n",
+					       wp_segno, wp_blkoff);
+					fsck->chk.wp_inconsistent_zones++;
+					return 0;
+				}
+
+				FIX_MSG("Reset write pointer of zone at "
+					"segment 0x%x", zone_segno);
+				ret = f2fs_reset_zone(wpd->dev_index, blkz);
+				if (ret) {
+					printf("[FSCK] Write pointer reset "
+					       "failed: %s\n", dev->path);
+					return ret;
+				}
+				fsck->chk.wp_fixed = 1;
+			}
 			return 0;
+		}
 	}
 
 	/*
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 9056e02..870a6e4 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1760,25 +1760,33 @@
 #define ZONE_ALIGN(blks)	SIZE_ALIGN(blks, c.blks_per_seg * \
 					c.segs_per_zone)
 
-static inline double get_reserved(struct f2fs_super_block *sb, double ovp)
+static inline uint32_t get_reserved(struct f2fs_super_block *sb, double ovp)
 {
-	double reserved;
 	uint32_t usable_main_segs = f2fs_get_usable_segments(sb);
 	uint32_t segs_per_sec = round_up(usable_main_segs, get_sb(section_count));
+	uint32_t reserved;
 
 	if (c.conf_reserved_sections)
 		reserved = c.conf_reserved_sections * segs_per_sec;
 	else
 		reserved = (100 / ovp + 1 + NR_CURSEG_TYPE) * segs_per_sec;
 
-	return reserved;
+	/* Let's keep the section alignment */
+	return round_up(reserved, segs_per_sec) * segs_per_sec;
+}
+
+static inline uint32_t overprovision_segment_buffer(struct f2fs_super_block *sb)
+{
+	/* Give 6 current sections to avoid huge GC overheads. */
+	return 6 * get_sb(segs_per_sec);
 }
 
 static inline double get_best_overprovision(struct f2fs_super_block *sb)
 {
-	double reserved, ovp, candidate, end, diff, space;
+	double ovp, candidate, end, diff, space;
 	double max_ovp = 0, max_space = 0;
 	uint32_t usable_main_segs = f2fs_get_usable_segments(sb);
+	uint32_t reserved;
 
 	if (get_sb(segment_count_main) < 256) {
 		candidate = 10;
@@ -1795,8 +1803,8 @@
 		ovp = (usable_main_segs - reserved) * candidate / 100;
 		if (ovp < 0)
 			continue;
-		space = usable_main_segs - max(reserved, ovp) -
-					2 * get_sb(segs_per_sec);
+		space = usable_main_segs - max((double)reserved, ovp) -
+					overprovision_segment_buffer(sb);
 		if (max_space < space) {
 			max_space = space;
 			max_ovp = candidate;
diff --git a/man/f2fs_io.8 b/man/f2fs_io.8
index ecaab02..f097bde 100644
--- a/man/f2fs_io.8
+++ b/man/f2fs_io.8
@@ -171,6 +171,9 @@
 .TP
 \fBgc_range\fR \fI[sync_mode] [start in 4kb] [length in 4kb] [file]\fR
 Trigger gc to move data blocks from specified address range
+.TP
+\fBget_advise\fR \fI[file]\fR
+Get i_advise value and info in file
 .SH AUTHOR
 This version of
 .B f2fs_io
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 8f632f8..e26a513 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -778,7 +778,8 @@
 		 * In non configurable reserved section case, overprovision
 		 * segments are always bigger than two sections.
 		 */
-		if (get_cp(overprov_segment_count) < 2 * get_sb(segs_per_sec)) {
+		if (get_cp(overprov_segment_count) <
+					overprovision_segment_buffer(sb)) {
 			MSG(0, "\tError: Not enough overprovision segments (%u)\n",
 			    get_cp(overprov_segment_count));
 			goto free_cp_payload;
@@ -787,7 +788,7 @@
 				get_cp(rsvd_segment_count));
 	 } else {
 		set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
-				2 * get_sb(segs_per_sec));
+				overprovision_segment_buffer(sb));
 	 }
 
 	if (f2fs_get_usable_segments(sb) <= get_cp(overprov_segment_count)) {
diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c
index 7059cbf..b8e4f02 100644
--- a/tools/f2fs_io/f2fs_io.c
+++ b/tools/f2fs_io/f2fs_io.c
@@ -1743,6 +1743,46 @@
 	exit(0);
 }
 
+#define get_advise_desc "get_advise"
+#define get_advise_help "f2fs_io get_advise [file_path]\n\n"
+
+static void do_get_advise(int argc, char **argv, const struct cmd_desc *cmd)
+{
+	int ret;
+	unsigned char value;
+
+	if (argc != 2) {
+		fputs("Excess arguments\n\n", stderr);
+		fputs(cmd->cmd_help, stderr);
+		exit(1);
+	}
+
+	ret = getxattr(argv[1], F2FS_SYSTEM_ADVISE_NAME, &value, sizeof(value));
+	if (ret != sizeof(value)) {
+		perror("getxattr");
+		exit(1);
+	}
+
+	printf("i_advise=0x%x, advise_type: ", value);
+	if (value & FADVISE_COLD_BIT)
+		printf("cold ");
+	if (value & FADVISE_LOST_PINO_BIT)
+		printf("lost_pino ");
+	if (value & FADVISE_ENCRYPT_BIT)
+		printf("encrypt ");
+	if (value & FADVISE_ENC_NAME_BIT)
+		printf("enc_name ");
+	if (value & FADVISE_KEEP_SIZE_BIT)
+		printf("keep_size ");
+	if (value & FADVISE_HOT_BIT)
+		printf("hot ");
+	if (value & FADVISE_VERITY_BIT)
+		printf("verity ");
+	if (value & FADVISE_TRUNC_BIT)
+		printf("trunc ");
+	printf("\n");
+}
+
 #define CMD_HIDDEN 	0x0001
 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 }
 #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN }
@@ -1786,6 +1826,7 @@
 	CMD(setxattr),
 	CMD(removexattr),
 	CMD(lseek),
+	CMD(get_advise),
 	{ NULL, NULL, NULL, NULL, 0 }
 };
 
diff --git a/tools/f2fs_io/f2fs_io.h b/tools/f2fs_io/f2fs_io.h
index d2641cb..b5c82f5 100644
--- a/tools/f2fs_io/f2fs_io.h
+++ b/tools/f2fs_io/f2fs_io.h
@@ -169,7 +169,13 @@
 
 #define F2FS_SYSTEM_ADVISE_NAME	"system.advise"
 #define FADVISE_COLD_BIT	0x01
+#define FADVISE_LOST_PINO_BIT	0x02
+#define FADVISE_ENCRYPT_BIT	0x04
+#define FADVISE_ENC_NAME_BIT	0x08
+#define FADVISE_KEEP_SIZE_BIT	0x10
 #define FADVISE_HOT_BIT		0x20
+#define FADVISE_VERITY_BIT	0x40
+#define FADVISE_TRUNC_BIT	0x80
 
 #ifndef FS_IMMUTABLE_FL
 #define FS_IMMUTABLE_FL			0x00000010 /* Immutable file */