aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--METADATA6
-rw-r--r--fsck/fsck.c53
-rw-r--r--include/f2fs_fs.h20
-rw-r--r--man/f2fs_io.83
-rw-r--r--mkfs/f2fs_format.c5
-rw-r--r--tools/f2fs_io/f2fs_io.c41
-rw-r--r--tools/f2fs_io/f2fs_io.h6
7 files changed, 97 insertions, 37 deletions
diff --git a/METADATA b/METADATA
index 053806a..5ab453a 100644
--- a/METADATA
+++ b/METADATA
@@ -8,13 +8,13 @@ third_party {
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 @@ static int chk_and_fix_wp_with_sit(int UNUSED(i), void *blkzone, void *opaque)
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 @@ extern uint32_t f2fs_get_usable_segments(struct f2fs_super_block *sb);
#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 @@ static inline double get_best_overprovision(struct f2fs_super_block *sb)
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 @@ Move a range of data blocks from source file to destination file
.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 @@ static int f2fs_write_check_point_pack(void)
* 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 @@ static int f2fs_write_check_point_pack(void)
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 @@ static void do_lseek(int argc, char **argv, const struct cmd_desc *cmd)
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 @@ const struct cmd_desc cmd_list[] = {
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 @@ struct fscrypt_get_policy_ex_arg {
#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 */