1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2017 Fujitsu Ltd. 4 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com> 5 */ 6 7/*\ 8 * [Description] 9 * 10 * quotactl(2) with XGETNEXTQUOTA looks for the next active quota for an user 11 * equal or higher to a given ID, in this test the ID is specified to a value 12 * close to UINT_MAX(max value of unsigned int). When reaching the upper limit 13 * and finding no active quota, it should return -1 and set errno to ENOENT. 14 * Actually, quotactl(2) overflows and and return 0 as the "next" active id. 15 * 16 * This kernel bug of xfs has been fixed in: 17 * 18 * commit 657bdfb7f5e68ca5e2ed009ab473c429b0d6af85 19 * Author: Eric Sandeen <sandeen@redhat.com> 20 * Date: Tue Jan 17 11:43:38 2017 -0800 21 * 22 * xfs: don't wrap ID in xfs_dq_get_next_id 23 */ 24 25#define _GNU_SOURCE 26#include <errno.h> 27#include <unistd.h> 28#include <stdio.h> 29#include <sys/quota.h> 30 31#include "tst_test.h" 32#include "quotactl_syscall_var.h" 33 34#ifdef HAVE_XFS_XQM_H 35# include <xfs/xqm.h> 36 37static uint32_t test_id = 0xfffffffc; 38 39static void verify_quota(void) 40{ 41 struct fs_disk_quota res_dquota; 42 43 res_dquota.d_id = 1; 44 45 TEST(do_quotactl(fd, QCMD(Q_XGETNEXTQUOTA, USRQUOTA), tst_device->dev, 46 test_id, (void *)&res_dquota)); 47 if (TST_RET != -1) { 48 tst_res(TFAIL, "quotactl() found the next active ID: %u unexpectedly", 49 res_dquota.d_id); 50 return; 51 } 52 53 if (TST_ERR == EINVAL) 54 tst_brk(TCONF | TTERRNO, 55 "Q_XGETNEXTQUOTA wasn't supported in quotactl()"); 56 57 if (TST_ERR != ENOENT) 58 tst_res(TFAIL | TTERRNO, "quotactl() failed unexpectedly with %s expected ENOENT", 59 tst_strerrno(TST_ERR)); 60 else 61 tst_res(TPASS, "quotactl() failed with ENOENT as expected"); 62} 63 64static void setup(void) 65{ 66 quotactl_info(); 67 fd = SAFE_OPEN(MNTPOINT, O_RDONLY); 68} 69 70static void cleanup(void) 71{ 72 if (fd > -1) 73 SAFE_CLOSE(fd); 74} 75 76static 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 .mount_device = 1, 86 .dev_fs_type = "xfs", 87 .mntpoint = MNTPOINT, 88 .mnt_data = "usrquota", 89 .test_variants = QUOTACTL_SYSCALL_VARIANTS, 90 .tags = (const struct tst_tag[]) { 91 {"linux-git", "657bdfb7f5e6"}, 92 {} 93 } 94}; 95 96#else 97 TST_TEST_TCONF("System doesn't have <xfs/xqm.h>"); 98#endif 99