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