Re: [LTP] [PATCH v4] ioctl_fiemap01: New test for fiemap ioctl()

Cyril Hrubis
2024-11-06T10:34:37Z

Hi!
> +/*\
> + * [Description]
> + *
> + * Verify basic fiemap ioctl.

This should explain better what the test actually does.

We are doing several things here, that should be described including
checks for invalid flags, empty file, and then finally check that we get
sane data extend data from the call in two different situations. These
subtests should be described here.

> + */
> +
> +#include <linux/fs.h>
> +#include <linux/fiemap.h>
> +#include <stdlib.h>
> +#include <sys/statvfs.h>
> +
> +#include "tst_test.h"
> +
> +#define MNTPOINT "mntpoint"
> +#define TESTFILE "testfile"
> +#define NUM_EXTENT 3
> +
> +static void print_extens(struct fiemap *fiemap)
> +{
> + tst_res(TDEBUG, "File extent count: %u", fiemap->fm_mapped_extents);
> +
> + for (unsigned int i = 0; i < fiemap->fm_mapped_extents; ++i) {
> + tst_res(TDEBUG, "Extent %u: Logical offset: %llu, Physical offset: %llu, flags: %u, Length: %llu",
> + i + 1,
> + fiemap->fm_extents[i].fe_logical,
> + fiemap->fm_extents[i].fe_physical,
> + fiemap->fm_extents[i].fe_flags,
> + fiemap->fm_extents[i].fe_length);
> + }
> +}
> +
> +static void check_extent(struct fiemap *fiemap, unsigned int fm_mapped_extents, int index_extents, int fe_flags, unsigned int min_fe_physical, unsigned int fe_length)

Didn't make check complain that this line is too long?

> +{
> + TST_EXP_EXPR(fiemap->fm_mapped_extents == fm_mapped_extents,
> + "Check extent fm_mapped_extents is %d", fm_mapped_extents);
> + TST_EXP_EXPR(fiemap->fm_extents[index_extents].fe_flags & fe_flags,
> + "Check fe_flags is %d", fe_flags);
> + TST_EXP_EXPR(fiemap->fm_extents[index_extents].fe_physical >= min_fe_physical,
> + "Check fe_physical > %d", min_fe_physical);
> + TST_EXP_EXPR(fiemap->fm_extents[index_extents].fe_length == fe_length,
> + "Check fe_length is %d", fe_length);
> +}
> +
> +static void verify_ioctl(void)
> +{
> + int fd;
> + struct fiemap *fiemap;
> + struct statvfs fs_info;
> + unsigned long blk_size;
> +
> + SAFE_CHDIR(MNTPOINT);
> + fd = SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT, 0644);
> +
> + if (statvfs(".", &fs_info) != 0)
> + tst_brk(TBROK, "statvfs failed");

It would be nicer if we added SAFE_STATVFS() in a separate patch and
then used it here.

> + blk_size = fs_info.f_bsize;
> +
> + fiemap = SAFE_MALLOC(sizeof(struct fiemap) + sizeof(struct fiemap_extent) * NUM_EXTENT);
> + fiemap->fm_start = 0;
> + fiemap->fm_length = ~0ULL;
> + fiemap->fm_extent_count = 1;
> +
> + fiemap->fm_flags = -1;
> + TST_EXP_FAIL(ioctl(fd, FS_IOC_FIEMAP, fiemap), EBADR);
> +
> + fiemap->fm_flags = 0;
> + TST_EXP_PASS(ioctl(fd, FS_IOC_FIEMAP, fiemap));
> + print_extens(fiemap);
> + TST_EXP_EXPR(fiemap->fm_mapped_extents == 0,
> + "Check extent fm_mapped_extents is 0");
^
Maybe better "Empty file should have 0 extends mapped"

Or something that actually explains better why it should be 0.

> + char *buf = SAFE_MALLOC(blk_size);
> +
> + SAFE_WRITE(SAFE_WRITE_ANY, fd, buf, blk_size);
> + fiemap->fm_flags = FIEMAP_FLAG_SYNC;
> + TST_EXP_PASS(ioctl(fd, FS_IOC_FIEMAP, fiemap));
> + print_extens(fiemap);
> + check_extent(fiemap, 1, 0, FIEMAP_EXTENT_LAST, 1, blk_size);
> +
> + fiemap->fm_extent_count = NUM_EXTENT;
> + SAFE_LSEEK(fd, 2 * blk_size, SEEK_SET);
> + SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, blk_size);
> + SAFE_LSEEK(fd, 4 * blk_size, SEEK_SET);
> + SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, blk_size);
> + TST_EXP_PASS(ioctl(fd, FS_IOC_FIEMAP, fiemap));
> + print_extens(fiemap);
> + check_extent(fiemap, NUM_EXTENT, NUM_EXTENT - 1, FIEMAP_EXTENT_LAST, 1, blk_size);
> +
> + free(buf);
> + free(fiemap);
> + SAFE_CLOSE(fd);
> + SAFE_UNLINK(TESTFILE);
> +}
> +
> +static struct tst_test test = {
> + .mount_device = 1,
> + .mntpoint = MNTPOINT,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *const[]) {
> + "exfat", "vfat", "ntfs", "tmpfs", NULL
> + },
> + .test_all = verify_ioctl,
> + .needs_root = 1,
> +};
> --
> 2.35.3
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp

--
Cyril Hrubis
chrubis@suse.cz