186 lines
4.6 KiB
C
186 lines
4.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (c) Zilogic Systems Pvt. Ltd., 2018
|
|
* Email: code@zilogic.com
|
|
*/
|
|
|
|
/*
|
|
* Test statx
|
|
*
|
|
* This code tests if the attributes field of statx received expected value.
|
|
* File set with following flags by using SAFE_IOCTL:
|
|
* 1) STATX_ATTR_COMPRESSED - The file is compressed by the filesystem.
|
|
* 2) STATX_ATTR_IMMUTABLE - The file cannot be modified.
|
|
* 3) STATX_ATTR_APPEND - The file can only be opened in append mode for
|
|
* writing.
|
|
* 4) STATX_ATTR_NODUMP - File is not a candidate for backup when a backup
|
|
* program such as dump(8) is run.
|
|
*
|
|
* Two directories are tested.
|
|
* First directory has all flags set.
|
|
* Second directory has no flags set.
|
|
*
|
|
* Minimum kernel version required is 4.11.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include "tst_test.h"
|
|
#include "lapi/fs.h"
|
|
#include <stdlib.h>
|
|
#include "lapi/stat.h"
|
|
|
|
#define MOUNT_POINT "mntpoint"
|
|
#define TESTDIR_FLAGGED MOUNT_POINT"/test_dir1"
|
|
#define TESTDIR_UNFLAGGED MOUNT_POINT"/test_dir2"
|
|
|
|
static int fd, clear_flags;
|
|
|
|
static void test_flagged(void)
|
|
{
|
|
struct statx buf;
|
|
|
|
TEST(statx(AT_FDCWD, TESTDIR_FLAGGED, 0, 0, &buf));
|
|
if (TST_RET == 0)
|
|
tst_res(TPASS,
|
|
"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED);
|
|
else
|
|
tst_brk(TFAIL | TTERRNO,
|
|
"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED);
|
|
|
|
if (buf.stx_attributes & STATX_ATTR_COMPRESSED)
|
|
tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is not set");
|
|
|
|
if (buf.stx_attributes & STATX_ATTR_APPEND)
|
|
tst_res(TPASS, "STATX_ATTR_APPEND flag is set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_APPEND flag is not set");
|
|
|
|
if (buf.stx_attributes & STATX_ATTR_IMMUTABLE)
|
|
tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is not set");
|
|
|
|
if (buf.stx_attributes & STATX_ATTR_NODUMP)
|
|
tst_res(TPASS, "STATX_ATTR_NODUMP flag is set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_NODUMP flag is not set");
|
|
}
|
|
|
|
static void test_unflagged(void)
|
|
{
|
|
struct statx buf;
|
|
|
|
TEST(statx(AT_FDCWD, TESTDIR_UNFLAGGED, 0, 0, &buf));
|
|
if (TST_RET == 0)
|
|
tst_res(TPASS,
|
|
"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
|
|
TESTDIR_UNFLAGGED);
|
|
else
|
|
tst_brk(TFAIL | TTERRNO,
|
|
"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
|
|
TESTDIR_UNFLAGGED);
|
|
|
|
if ((buf.stx_attributes & STATX_ATTR_COMPRESSED) == 0)
|
|
tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is not set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is set");
|
|
|
|
if ((buf.stx_attributes & STATX_ATTR_APPEND) == 0)
|
|
tst_res(TPASS, "STATX_ATTR_APPEND flag is not set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_APPEND flag is set");
|
|
|
|
if ((buf.stx_attributes & STATX_ATTR_IMMUTABLE) == 0)
|
|
tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is not set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is set");
|
|
|
|
if ((buf.stx_attributes & STATX_ATTR_NODUMP) == 0)
|
|
tst_res(TPASS, "STATX_ATTR_NODUMP flag is not set");
|
|
else
|
|
tst_res(TFAIL, "STATX_ATTR_NODUMP flag is set");
|
|
}
|
|
|
|
struct test_cases {
|
|
void (*tfunc)(void);
|
|
} tcases[] = {
|
|
{&test_flagged},
|
|
{&test_unflagged},
|
|
};
|
|
|
|
static void run(unsigned int i)
|
|
{
|
|
tcases[i].tfunc();
|
|
}
|
|
|
|
static void caid_flags_setup(void)
|
|
{
|
|
int attr, ret;
|
|
|
|
fd = SAFE_OPEN(TESTDIR_FLAGGED, O_RDONLY | O_DIRECTORY);
|
|
|
|
ret = ioctl(fd, FS_IOC_GETFLAGS, &attr);
|
|
if (ret < 0) {
|
|
if (errno == ENOTTY)
|
|
tst_brk(TCONF | TERRNO, "FS_IOC_GETFLAGS not supported");
|
|
|
|
/* ntfs3g fuse fs returns wrong errno for unimplemented ioctls */
|
|
if (!strcmp(tst_device->fs_type, "ntfs")) {
|
|
tst_brk(TCONF | TERRNO,
|
|
"ntfs3g does not support FS_IOC_GETFLAGS");
|
|
}
|
|
|
|
tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_GETFLAGS, ...)", fd);
|
|
}
|
|
|
|
attr |= FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL;
|
|
|
|
ret = ioctl(fd, FS_IOC_SETFLAGS, &attr);
|
|
if (ret < 0) {
|
|
if (errno == EOPNOTSUPP)
|
|
tst_brk(TCONF, "Flags not supported");
|
|
tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_SETFLAGS, %i)", fd, attr);
|
|
}
|
|
|
|
clear_flags = 1;
|
|
}
|
|
|
|
static void setup(void)
|
|
{
|
|
SAFE_MKDIR(TESTDIR_FLAGGED, 0777);
|
|
SAFE_MKDIR(TESTDIR_UNFLAGGED, 0777);
|
|
|
|
if (!strcmp(tst_device->fs_type, "btrfs") && tst_kvercmp(4, 13, 0) < 0)
|
|
tst_brk(TCONF, "Btrfs statx() supported since 4.13");
|
|
|
|
caid_flags_setup();
|
|
}
|
|
|
|
static void cleanup(void)
|
|
{
|
|
int attr;
|
|
|
|
if (clear_flags) {
|
|
SAFE_IOCTL(fd, FS_IOC_GETFLAGS, &attr);
|
|
attr &= ~(FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL);
|
|
SAFE_IOCTL(fd, FS_IOC_SETFLAGS, &attr);
|
|
}
|
|
|
|
if (fd > 0)
|
|
SAFE_CLOSE(fd);
|
|
}
|
|
|
|
static struct tst_test test = {
|
|
.test = run,
|
|
.tcnt = ARRAY_SIZE(tcases),
|
|
.setup = setup,
|
|
.cleanup = cleanup,
|
|
.needs_root = 1,
|
|
.all_filesystems = 1,
|
|
.mount_device = 1,
|
|
.mntpoint = MOUNT_POINT,
|
|
.min_kver = "4.11",
|
|
};
|