bump for release
[uclibc-ng.git] / test / unistd / tst-fallocate.c
blobfc81781bb99d42c24a42308a9a837db6d311134d
1 #include <fcntl.h>
2 #include <sys/stat.h>
4 #ifndef TST_FALLOCATE64
5 # define stat64 stat
6 # define fstat64 fstat
7 # else
8 # ifndef O_LARGEFILE
9 # error no O_LARGEFILE but you want to test with LFS enabled
10 # endif
11 #endif
13 static void do_prepare(void);
14 static int do_test(void);
15 #define PREPARE(argc, argv) do_prepare ()
16 #define TEST_FUNCTION do_test ()
17 #include <test-skeleton.c>
19 static int fd;
20 static void
21 do_prepare (void)
23 fd = create_temp_file ("tst-fallocate.", NULL);
24 if (fd == -1)
26 printf ("cannot create temporary file: %m\n");
27 exit (1);
32 static int
33 do_test (void)
35 struct stat64 st;
36 int c;
37 char garbage[4096];
38 blkcnt_t blksb4;
40 if (fstat64 (fd, &st) != 0)
42 puts ("1st fstat failed");
43 return 1;
46 if (st.st_size != 0)
48 puts ("file not created with size 0");
49 return 1;
52 /* This is the default mode which is identical to posix_fallocate().
53 Note: we need a few extra blocks for FALLOC_FL_PUNCH_HOLE below.
54 While block sizes vary, we'll assume eight 4K blocks for good measure. */
55 if (fallocate (fd, 0, 8 * 4096, 128) != 0)
57 puts ("1st fallocate call failed");
58 return 1;
61 if (fstat64 (fd, &st) != 0)
63 puts ("2nd fstat failed");
64 return 1;
67 if (st.st_size != 8 * 4096 + 128)
69 printf ("file size after 1st fallocate call is %llu, expected %u\n",
70 (unsigned long long int) st.st_size, 8u * 4096u + 128u);
71 return 1;
74 /* Without FALLOC_FL_KEEP_SIZE, this would increaste the size of the file. */
75 if (fallocate (fd, FALLOC_FL_KEEP_SIZE, 0, 16 * 4096) != 0)
77 puts ("2nd fallocate call failed");
78 return 1;
81 if (fstat64 (fd, &st) != 0)
83 puts ("3rd fstat failed");
84 return 1;
87 if (st.st_size != 8 * 4096 + 128)
89 printf ("file size changed in 2nd fallocate call to %llu, expected %u\n",
90 (unsigned long long int) st.st_size, 8u * 4096u + 128u);
91 return 1;
94 /* Let's fill up the first eight 4k blocks with 'x' to force some allocations. */
96 memset(garbage, 'x', 4096);
97 for(c=0; c < 8; c++)
98 if(write(fd, garbage, 4096) == -1)
100 puts ("write failed");
101 return 1;
104 if (fstat64 (fd, &st) != 0)
106 puts ("4th fstat failed");
107 return 1;
110 blksb4 = st.st_blocks;
112 /* Let's punch a hole in the entire file, turning it effectively into a sparse file. */
113 if (fallocate (fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 8 * 4096 + 128) != 0)
115 puts ("3rd fallocate call failed");
116 return 1;
119 if (fstat64 (fd, &st) != 0)
121 puts ("5th fstat failed");
122 return 1;
125 if (st.st_size != 8 * 4096 + 128)
127 printf ("file size after 3rd fallocate call is %llu, expected %u\n",
128 (unsigned long long int) st.st_size, 8u * 4096u + 128u);
129 return 1;
132 /* The number of allocated blocks should decrease. I hope this works on
133 all filesystems! */
134 if (st.st_blocks >= blksb4)
136 printf ("number of blocks after 3rd fallocate call is %lu, expected less than %lu\n",
137 (unsigned long int) st.st_blocks, blksb4);
138 return 1;
141 #ifdef TST_FALLOCATE64
142 /* We'll just do a mode = 0 test for fallocate64() */
143 if (fallocate64 (fd, 0, 4097ULL, 4294967295ULL + 2ULL) != 0)
145 puts ("1st fallocate64 call failed");
146 return 1;
149 if (fstat64 (fd, &st) != 0)
151 puts ("6th fstat failed");
152 return 1;
155 if (st.st_size != 4097ULL + 4294967295ULL + 2ULL)
157 printf ("file size after 1st fallocate64 call is %llu, expected %llu\n",
158 (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL);
159 return 1;
161 #endif
162 close (fd);
164 return 0;