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