xfs/106: don't test disabling quota accounting
[xfstests-dev.git] / src / chprojid_fail.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2021 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  *
6  * Regression test for failing to undo delalloc quota reservations when
7  * changing project id and we fail some other FSSETXATTR validation.
8  */
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <sys/ioctl.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <linux/fs.h>
18 #include "global.h"
19
20 static char zerobuf[65536];
21
22 int
23 main(
24         int             argc,
25         char            *argv[])
26 {
27         struct fsxattr  fa;
28         ssize_t         sz;
29         int             fd, ret;
30
31         if (argc < 2) {
32                 printf("Usage: %s filename\n", argv[0]);
33                 return 1;
34         }
35
36         fd = open(argv[1], O_CREAT | O_TRUNC | O_RDWR, 0600);
37         if (fd < 0) {
38                 perror(argv[1]);
39                 return 2;
40         }
41
42         /* Zero the project id and the extent size hint. */
43         ret = ioctl(fd, FS_IOC_FSGETXATTR, &fa);
44         if (ret) {
45                 perror("FSGETXATTR check file");
46                 return 2;
47         }
48
49         if (fa.fsx_projid != 0 || fa.fsx_extsize != 0) {
50                 fa.fsx_projid = 0;
51                 fa.fsx_extsize = 0;
52                 ret = ioctl(fd, FS_IOC_FSSETXATTR, &fa);
53                 if (ret) {
54                         perror("FSSETXATTR zeroing");
55                         return 2;
56                 }
57         }
58
59         /* Dirty a few kb of a file to create delalloc extents. */
60         sz = write(fd, zerobuf, sizeof(zerobuf));
61         if (sz != sizeof(zerobuf)) {
62                 perror("delalloc write");
63                 return 2;
64         }
65
66         /*
67          * The regression we're trying to test happens when the fsxattr input
68          * validation decides to bail out after the chown quota reservation has
69          * been made on a file containing delalloc extents.  Extent size hints
70          * can't be set on non-empty files and we can't check the value until
71          * we've reserved resources and taken the file's ILOCK, so this is a
72          * perfect vector for triggering this condition.  In this way we set up
73          * a FSSETXATTR call that will fail.
74          */
75         ret = ioctl(fd, FS_IOC_FSGETXATTR, &fa);
76         if (ret) {
77                 perror("FSGETXATTR");
78                 return 2;
79         }
80
81         fa.fsx_projid = 23652;
82         fa.fsx_extsize = 2;
83         fa.fsx_xflags |= FS_XFLAG_EXTSIZE;
84
85         ret = ioctl(fd, FS_IOC_FSSETXATTR, &fa);
86         if (ret) {
87                 printf("FSSETXATTRR should fail: %s\n", strerror(errno));
88                 return 0;
89         }
90
91         /* Uhoh, that FSSETXATTR call should have failed! */
92         return 3;
93 }