1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2019-2021 FUJITSU LIMITED. All rights reserved. 4 * Author: Yang Xu <xuyang2018.jy@.fujitsu.com> 5 */ 6 7/*\ 8 * [Description] 9 * 10 * This testcases checks that quotactl(2) on xfs filesystem succeeds to: 11 * 12 * - turn off xfs quota and get xfs quota off status for project 13 * - turn on xfs quota and get xfs quota on status for project 14 * - set and use Q_XGETQUOTA to get xfs disk quota limits for project 15 * - set and use Q_XGETNEXTQUOTA to get xfs disk quota limits greater than or 16 * equal to ID for project 17 * - turn off xfs quota and get xfs quota off statv for project 18 * - turn on xfs quota and get xfs quota on statvfor project 19 */ 20 21#include "quotactl02.h" 22#include "quotactl_syscall_var.h" 23#if defined(HAVE_XFS_XQM_H) 24 25static uint32_t qflagp = XFS_QUOTA_PDQ_ENFD; 26static struct t_case { 27 int cmd; 28 void *addr; 29 void (*func_check)(); 30 int check_subcmd; 31 int flag; 32 char *des; 33 char *tname; 34} tcases[] = { 35 {QCMD(Q_XQUOTAOFF, PRJQUOTA), &qflagp, check_qoff, 36 QCMD(Q_XGETQSTAT, PRJQUOTA), 1, 37 "turn off xfs quota and get xfs quota off status for project", 38 "QCMD(Q_XGETQSTAT, PRJQUOTA) off"}, 39 40 {QCMD(Q_XQUOTAON, PRJQUOTA), &qflagp, check_qon, 41 QCMD(Q_XGETQSTAT, PRJQUOTA), 1, 42 "turn on xfs quota and get xfs quota on status for project", 43 "QCMD(Q_XGETQSTAT, PRJQUOTA) on"}, 44 45 {QCMD(Q_XSETQLIM, PRJQUOTA), &set_dquota, check_qlim, 46 QCMD(Q_XGETQUOTA, PRJQUOTA), 0, 47 "Q_XGETQUOTA for project", "QCMD(Q_XGETQUOTA, PRJQUOTA) qlim"}, 48 49 {QCMD(Q_XSETQLIM, PRJQUOTA), &set_dquota, check_qlim, 50 QCMD(Q_XGETNEXTQUOTA, PRJQUOTA), 0, 51 "Q_XGETNEXTQUOTA for project", "QCMD(Q_XGETNEXTQUOTA, PRJQUOTA)"}, 52 53 {QCMD(Q_XQUOTAOFF, PRJQUOTA), &qflagp, check_qoffv, 54 QCMD(Q_XGETQSTATV, PRJQUOTA), 1, 55 "turn off xfs quota and get xfs quota off statv for project", 56 "QCMD(Q_XGETQSTATV, PRJQUOTA) off"}, 57 58 {QCMD(Q_XQUOTAON, PRJQUOTA), &qflagp, check_qonv, 59 QCMD(Q_XGETQSTATV, PRJQUOTA), 1, 60 "turn on xfs quota and get xfs quota on statv for project", 61 "QCMD(Q_XGETQSTATV, PRJQUOTA) on"}, 62}; 63 64static void setup(void) 65{ 66 quotactl_info(); 67 fd = SAFE_OPEN(MNTPOINT, O_RDONLY); 68 check_support_cmd(PRJQUOTA); 69} 70 71static void cleanup(void) 72{ 73 if (fd > -1) 74 SAFE_CLOSE(fd); 75} 76 77static void verify_quota(unsigned int n) 78{ 79 struct t_case *tc = &tcases[n]; 80 81 tst_res(TINFO, "Test #%d: %s", n, tc->tname); 82 83 if ((tc->check_subcmd == QCMD(Q_XGETNEXTQUOTA, PRJQUOTA)) 84 && x_getnextquota_nsup) { 85 tst_res(TCONF, 86 "current system doesn't support this cmd"); 87 return; 88 } 89 if ((tc->check_subcmd == QCMD(Q_XGETQSTATV, PRJQUOTA)) 90 && x_getstatv_nsup) { 91 tst_res(TCONF, 92 "current system doesn't support this cmd"); 93 return; 94 } 95 96 TST_EXP_PASS_SILENT(do_quotactl(fd, tc->cmd, tst_device->dev, test_id, tc->addr), 97 "do_quotactl()"); 98 if (!TST_PASS) 99 return; 100 101 if (tc->flag) 102 tc->func_check(tc->check_subcmd, tc->des, *(int *)(tc->addr)); 103 else 104 tc->func_check(tc->check_subcmd, tc->des); 105} 106 107static struct tst_test test = { 108 .needs_root = 1, 109 .needs_kconfigs = (const char *[]) { 110 "CONFIG_XFS_QUOTA", 111 NULL 112 }, 113 .test = verify_quota, 114 .tcnt = ARRAY_SIZE(tcases), 115 .mount_device = 1, 116 .dev_fs_type = "xfs", 117 .mntpoint = MNTPOINT, 118 .mnt_data = "prjquota", 119 .setup = setup, 120 .cleanup = cleanup, 121 .test_variants = QUOTACTL_SYSCALL_VARIANTS, 122}; 123 124#else 125 TST_TEST_TCONF("This system didn't have <xfs/xqm.h>"); 126#endif 127