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",
 | |
| };
 |