23adc072e5c17af8ae47b59dc3a0776916d5779a
[xfstests-dev.git] / src / attr_replace_test.c
1 // setattr.c by kanda.motohiro@gmail.com
2 // xfs extended attribute corruption bug reproducer
3 #include <stdio.h>
4 #include <string.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/xattr.h>
11 #include <sys/stat.h>
12
13 #define die() do { perror(""); \
14 fprintf(stderr, "error=%d at line %d\n", errno, __LINE__); \
15 exit(1); } while (0)
16
17 #define fail(...) do { \
18 fprintf(stderr, __VA_ARGS__); exit (1); \
19 } while (0)
20
21 int main(int argc, char *argv[])
22 {
23         int ret;
24         int fd;
25         char *path;
26         char *name = "user.world";
27         char *value;
28         struct stat sbuf;
29         size_t size = sizeof(value);
30
31         if (argc != 2)
32                 fail("Usage: %s <file>\n", argv[0]);
33         path = argv[1];
34
35         fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
36         if (fd < 0) die();
37
38         /*
39          * The value should be 3/4 the size of a fs block to ensure that we
40          * get to extents format.
41          */
42         ret = fstat(fd, &sbuf);
43         if (ret < 0) die();
44         size = sbuf.st_blksize * 3 / 4;
45         if (!size)
46                 fail("Invalid st_blksize(%ld)\n", sbuf.st_blksize);
47         value = malloc(size);
48         if (!value)
49                 fail("Failed to allocate memory\n");
50
51         /* First, create a small xattr. */
52         memset(value, '0', 1);
53         ret = fsetxattr(fd, name, value, 1, XATTR_CREATE);
54         if (ret < 0) die();
55         close(fd);
56
57         fd = open(path, O_RDWR);
58         if (fd < 0) die();
59
60         /* Then, replace it with bigger one, forcing short form to leaf conversion. */
61         memset(value, '1', size);
62         ret = fsetxattr(fd, name, value, size, XATTR_REPLACE);
63         if (ret < 0) die();
64         close(fd);
65
66         return 0;
67 }