various: replace _get_block_size with _get_file_block_size when needed
[xfstests-dev.git] / src / enospc_unlink.c
1 /* 
2  * Write a file until filesystem full is reached and then unlink it.
3  * Demonstrates a particular deadlock that Kaz hit in testing.  Run
4  * several iterations of this in parallel on a near-full filesystem.
5  */
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <malloc.h>
14 #include <sys/mman.h>
15 #include <sys/stat.h>
16
17 int main(int argc, char **argv)
18 {
19         int                     fd, sz, done;
20         void                    *ptr;
21         size_t                  written;
22         unsigned int            i, count = 0;
23         unsigned long long      bytes = 0;
24
25         if (argc < 2) {
26                 fprintf(stderr, "Insufficient arguments\n");
27                 exit(1);
28         }
29         if (argc < 3) {
30                 count = (unsigned int)atoi(argv[2]);
31         }
32
33         sz = 1024 * 1024;
34
35         ptr = memalign(sz, sz);
36         if (!ptr) {
37                 perror("memalign");
38                 exit(1);
39         }
40         memset(ptr, 0xffffffff, sz);
41
42         for (i = 0; i < count; i++) {
43                 fd = open(argv[1], O_CREAT|O_WRONLY, 0666);
44                 if (fd < 0) {
45                         perror(argv[1]);
46                         exit(1);
47                 }
48
49                 done = 0;
50                 while (!done) {
51                         written = write(fd, ptr, sz);
52                         if (written == -1) {
53                                 if (errno == ENOSPC) {
54                                         close(fd);
55                                         unlink(argv[1]);
56                                         printf("Unlinked %s\n", argv[1]);
57                                         done = 1;
58                                 }
59                                 else {
60                                         printf("Skipped unlink %s (%s)\n",
61                                                 argv[1], strerror(errno));
62                                         done = -1;
63                                 }
64                         }
65                         if (written == 0) {
66                                 printf("Wrote zero bytes?\n");
67                                 done = -1;
68                         }
69                         bytes += written;
70                 }
71                 if (done > 0)
72                         printf("Wrote %llu bytes total.\n", bytes);
73                 else
74                         exit(1);
75         }
76         printf("Completed %u iterations of unlink/out-of-space test.\n", i);
77         exit(0);
78 }