From: Darrick J. Wong <djwong@xxxxxxxxxx> Support FALLOC_FL_MAP_FREE_SPACE as a fallocate mode. This is experimental code to see if we can build a free space defragmenter out of this. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- io/prealloc.c | 37 +++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 8 +++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/io/prealloc.c b/io/prealloc.c index 5805897a4a0..02de16651c1 100644 --- a/io/prealloc.c +++ b/io/prealloc.c @@ -32,6 +32,10 @@ #define FALLOC_FL_UNSHARE_RANGE 0x40 #endif +#ifndef FALLOC_FL_MAP_FREE_SPACE +#define FALLOC_FL_MAP_FREE_SPACE (1U << 30) +#endif + static cmdinfo_t allocsp_cmd; static cmdinfo_t freesp_cmd; static cmdinfo_t resvsp_cmd; @@ -44,6 +48,7 @@ static cmdinfo_t fcollapse_cmd; static cmdinfo_t finsert_cmd; static cmdinfo_t fzero_cmd; static cmdinfo_t funshare_cmd; +static cmdinfo_t fmapfree_cmd; #endif static int @@ -381,6 +386,28 @@ funshare_f( } return 0; } + +static int +fmapfree_f( + int argc, + char **argv) +{ + xfs_flock64_t segment; + int mode = FALLOC_FL_MAP_FREE_SPACE; + int index = 1; + + if (!offset_length(argv[index], argv[index + 1], &segment)) { + exitcode = 1; + return 0; + } + + if (fallocate(file->fd, mode, segment.l_start, segment.l_len)) { + perror("fallocate"); + exitcode = 1; + return 0; + } + return 0; +} #endif /* HAVE_FALLOCATE */ void @@ -496,5 +523,15 @@ prealloc_init(void) funshare_cmd.oneline = _("unshares shared blocks within the range"); add_command(&funshare_cmd); + + fmapfree_cmd.name = "fmapfree"; + fmapfree_cmd.cfunc = fmapfree_f; + fmapfree_cmd.argmin = 2; + fmapfree_cmd.argmax = 2; + fmapfree_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + fmapfree_cmd.args = _("off len"); + fmapfree_cmd.oneline = + _("maps free space into a file"); + add_command(&fmapfree_cmd); #endif /* HAVE_FALLOCATE */ } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index ece778fc76c..b10523325ee 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -513,8 +513,14 @@ Call fallocate with FALLOC_FL_INSERT_RANGE flag as described in the .BR fallocate (2) manual page to create the hole by shifting data blocks. .TP +.BI fmapfree " offset length" +Maps free physical space into the file by calling fallocate with +the FALLOC_FL_MAP_FREE_SPACE flag as described in the +.BR fallocate (2) +manual page. +.TP .BI fpunch " offset length" -Punches (de-allocates) blocks in the file by calling fallocate with +Punches (de-allocates) blocks in the file by calling fallocate with the FALLOC_FL_PUNCH_HOLE flag as described in the .BR fallocate (2) manual page.