• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
4  * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * This is not only a functional test but also a error test for Q_XQUOTARM.
11  *
12  * It is a regresstion test for kernel commit 3dd4d40b4208
13  * ("xfs: Sanity check flags of Q_XQUOTARM call").
14  */
15 
16 #include <errno.h>
17 #include <unistd.h>
18 #include <stdio.h>
19 #include <sys/quota.h>
20 #include <sys/statvfs.h>
21 #include "tst_test.h"
22 #include "quotactl_syscall_var.h"
23 
24 #ifdef HAVE_XFS_XQM_H
25 # include <xfs/xqm.h>
26 
27 /* Include a valid quota type to avoid other EINVAL error */
28 static unsigned int invalid_type = XFS_GROUP_QUOTA << 1 | XFS_USER_QUOTA;
29 static unsigned int valid_type = XFS_USER_QUOTA;
30 static int mount_flag;
31 
verify_quota(void)32 static void verify_quota(void)
33 {
34 	struct statfs before, after;
35 
36 	SAFE_STATFS(MNTPOINT, &before);
37 	TST_EXP_PASS(do_quotactl(fd, QCMD(Q_XQUOTARM, USRQUOTA), tst_device->dev, 0,
38 			(void *)&valid_type), "do_quotactl(Q_XQUOTARM,valid_type)");
39 	SAFE_STATFS(MNTPOINT, &after);
40 	if (before.f_bavail <= after.f_bavail)
41 		tst_res(TPASS, "Q_XQUOTARM to free space, delta(%lu)", after.f_bavail - before.f_bavail);
42 	else
43 		tst_res(TFAIL, "Q_XQUOTARM to free space, delta(-%lu)", before.f_bavail - after.f_bavail);
44 
45 	TST_EXP_FAIL(do_quotactl(fd, QCMD(Q_XQUOTARM, USRQUOTA), tst_device->dev, 0,
46 			(void *)&invalid_type), EINVAL, "do_quotactl(Q_XQUOTARM, invalid_type)");
47 }
48 
setup(void)49 static void setup(void)
50 {
51 	quotactl_info();
52 
53 	/*
54 	 * Ensure superblock has quota data, but not running. In here, we must unmount
55 	 * completely and mount again with '-o no quota' because 'mount -o remount, noquota'
56 	 * isn't sufficient to disable accounting feature.
57 	 */
58 	SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, "usrquota");
59 	mount_flag = 1;
60 	SAFE_UMOUNT(MNTPOINT);
61 	mount_flag = 0;
62 	SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, "noquota");
63 	mount_flag = 1;
64 
65 	fd = SAFE_OPEN(MNTPOINT, O_RDONLY);
66 }
67 
cleanup(void)68 static void cleanup(void)
69 {
70 	if (fd > -1)
71 		SAFE_CLOSE(fd);
72 	if (mount_flag && tst_umount(MNTPOINT))
73 		tst_res(TWARN | TERRNO, "umount(%s)", MNTPOINT);
74 }
75 
76 static struct tst_test test = {
77 	.setup = setup,
78 	.cleanup = cleanup,
79 	.needs_root = 1,
80 	.needs_kconfigs = (const char *[]) {
81 		"CONFIG_XFS_QUOTA",
82 		NULL
83 	},
84 	.test_all = verify_quota,
85 	.format_device = 1,
86 	.dev_fs_type = "xfs",
87 	.mntpoint = MNTPOINT,
88 	.test_variants = QUOTACTL_SYSCALL_VARIANTS,
89 	.tags = (const struct tst_tag[]) {
90 		{"linux-git", "3dd4d40b4208"},
91 		{}
92 	}
93 };
94 #else
95 	TST_TEST_TCONF("System doesn't have <xfs/xqm.h>");
96 #endif
97