1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
6 * Regression test for failing to undo delalloc quota reservations when
7 * changing project id and we fail some other FSSETXATTR validation.
13 #include <sys/ioctl.h>
20 static char zerobuf[65536];
32 printf("Usage: %s filename\n", argv[0]);
36 fd = open(argv[1], O_CREAT | O_TRUNC | O_RDWR, 0600);
42 /* Zero the project id and the extent size hint. */
43 ret = ioctl(fd, FS_IOC_FSGETXATTR, &fa);
45 perror("FSGETXATTR check file");
49 if (fa.fsx_projid != 0 || fa.fsx_extsize != 0) {
52 ret = ioctl(fd, FS_IOC_FSSETXATTR, &fa);
54 perror("FSSETXATTR zeroing");
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");
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.
75 ret = ioctl(fd, FS_IOC_FSGETXATTR, &fa);
81 fa.fsx_projid = 23652;
83 fa.fsx_xflags |= FS_XFLAG_EXTSIZE;
85 ret = ioctl(fd, FS_IOC_FSSETXATTR, &fa);
87 printf("FSSETXATTRR should fail: %s\n", strerror(errno));
91 /* Uhoh, that FSSETXATTR call should have failed! */