3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 only,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License version 2 for more details (a copy is included
13 * in the LICENSE file that accompanied this code).
15 * You should have received a copy of the GNU General Public License
16 * version 2 along with this program; If not, see
17 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (C) 2014, DataDirect Networks, Inc.
24 * Author: Swapnil Pimpale <spimpale@ddn.com>
28 * This test case tests the following scenarios
29 * 1) Preallocate: try to fallocate memory blocks and write to it
33 * - create a hole in a file and preallocate using both the
35 * Rest of mode flags is not supported currenlty
46 #include <lustre/lustreapi.h>
48 #define WRITE_BLOCKS 10
49 #define HOLE_BLOCKS 10
54 static void usage(char *prog)
56 fprintf(stderr, "usage: %s <filepath>\n", prog);
57 fprintf(stderr, "filepath: absolute pathname of Lustre file\n");
61 static int write_data_to_file(int fd)
63 char buf[blksize + 1];
66 for (i = 0; i < WRITE_BLOCKS; i++) {
67 for (j = 0; j < blksize; j++)
70 rc = write(fd, buf, blksize);
72 fprintf(stderr, "write failed error %s\n",
80 static int get_stat(int fd, struct stat *st)
84 bzero(st, sizeof(struct stat));
86 fprintf(stderr, "stat file error: %s\n", strerror(errno));
92 static int __do_fallocate(int fd, int mode, loff_t offset, loff_t len)
96 rc = fallocate(fd, mode, offset, len);
98 fprintf(stderr, "fallocate failed, error %s, mode %d, "
99 "offset %llu, len %llu\n", strerror(errno), mode,
100 (unsigned long long)offset, (unsigned long long)len);
107 static int post_fallocate_checks(int fd, int mode, loff_t offset, loff_t len,
108 loff_t expected_new_size)
113 /* check the new size */
114 rc = get_stat(fd, &st);
118 if (st.st_size != expected_new_size) {
119 fprintf(stderr, "fallocate succeeded but size reported "
121 fprintf(stderr, "mode %d, offset %llu, len %llu, "
122 "new_size %llu, expected_new_size %llu\n", mode,
123 (unsigned long long)offset, (unsigned long long)len,
124 (unsigned long long)st.st_size,
125 (unsigned long long)expected_new_size);
132 static int create_hole(int fd)
136 rc = write_data_to_file(fd);
140 lseek(fd, HOLE_BLOCKS * blksize, SEEK_CUR);
142 rc = write_data_to_file(fd);
149 static int do_fallocate(int fd, int mode, loff_t offset,
150 loff_t expected_new_size)
156 rc = __do_fallocate(fd, mode, offset, len);
160 rc = post_fallocate_checks(fd, mode, offset, len, expected_new_size);
162 fprintf(stderr, "post_fallocate_checks failed for mode %d\n",
171 static int test_prealloc_nonsparse(int fd)
174 loff_t offset, expected_new_size;
177 lseek(fd, 0, SEEK_SET);
178 rc = write_data_to_file(fd);
182 rc = get_stat(fd, &st);
186 /* test default mode */
188 offset = lseek(fd, 0, SEEK_END);
189 expected_new_size = WRITE_BLOCKS * blksize + blksize;
190 rc = do_fallocate(fd, mode, offset, expected_new_size);
195 static int test_prealloc_sparse(int fd)
198 loff_t offset, expected_new_size;
201 rc = ftruncate(fd, 0);
203 fprintf(stderr, "ftruncate error %s\n", strerror(errno));
208 lseek(fd, 0, SEEK_SET);
209 rc = create_hole(fd);
213 rc = get_stat(fd, &st);
217 /* test default mode */
219 offset = lseek(fd, (WRITE_BLOCKS + HOLE_BLOCKS / 2) * blksize,
221 expected_new_size = (2 * WRITE_BLOCKS + HOLE_BLOCKS) * blksize;
222 rc = do_fallocate(fd, mode, offset, expected_new_size);
227 int main(int argc, char *argv[])
229 char *fname, *mount_point = NULL;
230 int rc = -EINVAL, fd;
239 if (fname[0] != '/') {
240 fprintf(stderr, "Need absolute path of the file\n");
244 fd = open(fname, O_RDWR | O_CREAT, 0700);
246 fprintf(stderr, "open file %s error: %s\n",
247 fname, strerror(errno));
252 mntpt = setmntent("/etc/mtab", "r");
254 fprintf(stderr, "setmntent error: %s\n",
260 while (NULL != (ent = getmntent(mntpt))) {
261 if (llapi_is_lustre_mnttype(ent->mnt_fsname) == 0) {
262 mount_point = ent->mnt_dir;
268 if (mount_point == NULL) {
269 fprintf(stderr, "file not on lustre filesystem?\n");
273 rc = get_stat(fd, &st);
276 blksize = st.st_blksize;
278 rc = test_prealloc_nonsparse(fd);
282 rc = test_prealloc_sparse(fd);