1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) Zilogic Systems Pvt. Ltd., 2018 4 * Email: code (at) zilogic.com 5 */ 6 7 /* 8 * Test statx 9 * 10 * This code tests if the attributes field of statx received expected value. 11 * File set with following flags by using SAFE_IOCTL: 12 * 1) STATX_ATTR_COMPRESSED - The file is compressed by the filesystem. 13 * 2) STATX_ATTR_IMMUTABLE - The file cannot be modified. 14 * 3) STATX_ATTR_APPEND - The file can only be opened in append mode for 15 * writing. 16 * 4) STATX_ATTR_NODUMP - File is not a candidate for backup when a backup 17 * program such as dump(8) is run. 18 * 19 * Two directories are tested. 20 * First directory has all flags set. 21 * Second directory has no flags set. 22 * 23 * Minimum kernel version required is 4.11. 24 */ 25 26 #define _GNU_SOURCE 27 #include "tst_test.h" 28 #include "lapi/fs.h" 29 #include <stdlib.h> 30 #include "lapi/stat.h" 31 32 #define MOUNT_POINT "mntpoint" 33 #define TESTDIR_FLAGGED MOUNT_POINT"/test_dir1" 34 #define TESTDIR_UNFLAGGED MOUNT_POINT"/test_dir2" 35 36 static int fd, clear_flags; 37 38 static void test_flagged(void) 39 { 40 struct statx buf; 41 42 TEST(statx(AT_FDCWD, TESTDIR_FLAGGED, 0, 0, &buf)); 43 if (TST_RET == 0) 44 tst_res(TPASS, 45 "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED); 46 else 47 tst_brk(TFAIL | TTERRNO, 48 "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTDIR_FLAGGED); 49 50 if (buf.stx_attributes & STATX_ATTR_COMPRESSED) 51 tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is set"); 52 else 53 tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is not set"); 54 55 if (buf.stx_attributes & STATX_ATTR_APPEND) 56 tst_res(TPASS, "STATX_ATTR_APPEND flag is set"); 57 else 58 tst_res(TFAIL, "STATX_ATTR_APPEND flag is not set"); 59 60 if (buf.stx_attributes & STATX_ATTR_IMMUTABLE) 61 tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is set"); 62 else 63 tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is not set"); 64 65 if (buf.stx_attributes & STATX_ATTR_NODUMP) 66 tst_res(TPASS, "STATX_ATTR_NODUMP flag is set"); 67 else 68 tst_res(TFAIL, "STATX_ATTR_NODUMP flag is not set"); 69 } 70 71 static void test_unflagged(void) 72 { 73 struct statx buf; 74 75 TEST(statx(AT_FDCWD, TESTDIR_UNFLAGGED, 0, 0, &buf)); 76 if (TST_RET == 0) 77 tst_res(TPASS, 78 "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", 79 TESTDIR_UNFLAGGED); 80 else 81 tst_brk(TFAIL | TTERRNO, 82 "sys_statx(AT_FDCWD, %s, 0, 0, &buf)", 83 TESTDIR_UNFLAGGED); 84 85 if ((buf.stx_attributes & STATX_ATTR_COMPRESSED) == 0) 86 tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is not set"); 87 else 88 tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is set"); 89 90 if ((buf.stx_attributes & STATX_ATTR_APPEND) == 0) 91 tst_res(TPASS, "STATX_ATTR_APPEND flag is not set"); 92 else 93 tst_res(TFAIL, "STATX_ATTR_APPEND flag is set"); 94 95 if ((buf.stx_attributes & STATX_ATTR_IMMUTABLE) == 0) 96 tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is not set"); 97 else 98 tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is set"); 99 100 if ((buf.stx_attributes & STATX_ATTR_NODUMP) == 0) 101 tst_res(TPASS, "STATX_ATTR_NODUMP flag is not set"); 102 else 103 tst_res(TFAIL, "STATX_ATTR_NODUMP flag is set"); 104 } 105 106 struct test_cases { 107 void (*tfunc)(void); 108 } tcases[] = { 109 {&test_flagged}, 110 {&test_unflagged}, 111 }; 112 113 static void run(unsigned int i) 114 { 115 tcases[i].tfunc(); 116 } 117 118 static void caid_flags_setup(void) 119 { 120 int attr, ret; 121 122 fd = SAFE_OPEN(TESTDIR_FLAGGED, O_RDONLY | O_DIRECTORY); 123 124 ret = ioctl(fd, FS_IOC_GETFLAGS, &attr); 125 if (ret < 0) { 126 if (errno == ENOTTY) 127 tst_brk(TCONF | TERRNO, "FS_IOC_GETFLAGS not supported"); 128 129 /* ntfs3g fuse fs returns wrong errno for unimplemented ioctls */ 130 if (!strcmp(tst_device->fs_type, "ntfs")) { 131 tst_brk(TCONF | TERRNO, 132 "ntfs3g does not support FS_IOC_GETFLAGS"); 133 } 134 135 tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_GETFLAGS, ...)", fd); 136 } 137 138 attr |= FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL; 139 140 ret = ioctl(fd, FS_IOC_SETFLAGS, &attr); 141 if (ret < 0) { 142 if (errno == EOPNOTSUPP) 143 tst_brk(TCONF, "Flags not supported"); 144 tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_SETFLAGS, %i)", fd, attr); 145 } 146 147 clear_flags = 1; 148 } 149 150 static void setup(void) 151 { 152 SAFE_MKDIR(TESTDIR_FLAGGED, 0777); 153 SAFE_MKDIR(TESTDIR_UNFLAGGED, 0777); 154 155 if (!strcmp(tst_device->fs_type, "btrfs") && tst_kvercmp(4, 13, 0) < 0) 156 tst_brk(TCONF, "Btrfs statx() supported since 4.13"); 157 158 caid_flags_setup(); 159 } 160 161 static void cleanup(void) 162 { 163 int attr; 164 165 if (clear_flags) { 166 SAFE_IOCTL(fd, FS_IOC_GETFLAGS, &attr); 167 attr &= ~(FS_COMPR_FL | FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL); 168 SAFE_IOCTL(fd, FS_IOC_SETFLAGS, &attr); 169 } 170 171 if (fd > 0) 172 SAFE_CLOSE(fd); 173 } 174 175 static struct tst_test test = { 176 .test = run, 177 .tcnt = ARRAY_SIZE(tcases), 178 .setup = setup, 179 .cleanup = cleanup, 180 .needs_root = 1, 181 .all_filesystems = 1, 182 .mount_device = 1, 183 .needs_tmpdir = 1, 184 .mntpoint = MOUNT_POINT, 185 .min_kver = "4.11", 186 }; 187