generic/223: port t_stripealign to FIEMAP

Since XFS has deprecated FIBMAP on FSDAX filesystems, we can't use
FIBMAP to verify stripe alignment anymore.  FIEMAP has existed for
quite some time now, so port it to use that instead, and only fall
back to FIBMAP if FIEMAP doesn't exist.

Tested-by: ross.zwisler@linux.intel.com
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
This commit is contained in:
Darrick J. Wong
2018-06-13 15:50:57 -07:00
committed by Eryu Guan
parent e1ca827f83
commit 16be889bc9
2 changed files with 63 additions and 13 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \
LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
preallo_rw_pattern_writer ftrunc trunc fs_perms testx looptest \
locktest unwritten_mmap bulkstat_unlink_test t_stripealign \
locktest unwritten_mmap bulkstat_unlink_test \
bulkstat_unlink_test_modified t_dir_offset t_futimens t_immutable \
stale_handle pwrite_mmap_blocked t_dir_offset2 seek_sanity_test \
seek_copy_test t_readdir_1 t_readdir_2 fsync-tester nsexec cloner \
@@ -37,7 +37,7 @@ LINUX_TARGETS += loggen
endif
ifeq ($(HAVE_FIEMAP), true)
LINUX_TARGETS += fiemap-tester
LINUX_TARGETS += fiemap-tester t_stripealign
endif
ifeq ($(HAVE_OPEN_BY_HANDLE_AT), true)
+61 -11
View File
@@ -17,8 +17,13 @@
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/fiemap.h>
#include <linux/fs.h>
#define FIBMAP _IO(0x00, 1) /* bmap access */
#define FIEMAP_EXTENT_ACCEPTABLE (FIEMAP_EXTENT_LAST | \
FIEMAP_EXTENT_DATA_ENCRYPTED | FIEMAP_EXTENT_ENCODED | \
FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_MERGED | \
FIEMAP_EXTENT_SHARED)
/*
* If only filename given, print first block.
@@ -28,11 +33,14 @@
int main(int argc, char ** argv)
{
int fd;
int ret;
int sunit = 0; /* in blocks */
char *filename;
unsigned int block = 0;
struct stat sb;
struct fiemap *fie;
struct fiemap_extent *fe;
int fd;
int ret;
int sunit = 0; /* in blocks */
char *filename;
unsigned long long block;
if (argc < 3) {
printf("Usage: %s <filename> <sunit in blocks>\n", argv[0]);
@@ -48,21 +56,63 @@ int main(int argc, char ** argv)
return 1;
}
ret = ioctl(fd, FIBMAP, &block);
if (ret < 0) {
ret = fstat(fd, &sb);
if (ret) {
perror(filename);
close(fd);
perror("fibmap");
return 1;
}
close(fd);
fie = calloc(1, sizeof(struct fiemap) + sizeof(struct fiemap_extent));
if (!fie) {
close(fd);
perror("malloc");
return 1;
}
fie->fm_length = 1;
fie->fm_flags = FIEMAP_FLAG_SYNC;
fie->fm_extent_count = 1;
ret = ioctl(fd, FS_IOC_FIEMAP, fie);
if (ret < 0) {
unsigned int bmap = 0;
ret = ioctl(fd, FIBMAP, &bmap);
if (ret < 0) {
perror("fibmap");
free(fie);
close(fd);
return 1;
}
block = bmap;
goto check;
}
if (fie->fm_mapped_extents != 1) {
printf("%s: no extents?\n", filename);
free(fie);
close(fd);
return 1;
}
fe = &fie->fm_extents[0];
if (fe->fe_flags & ~FIEMAP_EXTENT_ACCEPTABLE) {
printf("%s: bad flags 0x%x\n", filename, fe->fe_flags);
free(fie);
close(fd);
return 1;
}
block = fie->fm_extents[0].fe_physical / sb.st_blksize;
check:
if (block % sunit) {
printf("%s: Start block %u not multiple of sunit %u\n",
printf("%s: Start block %llu not multiple of sunit %u\n",
filename, block, sunit);
return 1;
} else
printf("%s: well-aligned\n", filename);
free(fie);
close(fd);
return 0;
}