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);
99 "fallocate failed, error %s, mode %d, offset %llu, len %llu\n",
100 strerror(errno), mode, (unsigned long long)offset,
101 (unsigned long long)len);
108 static int post_fallocate_checks(int fd, int mode, loff_t offset, loff_t len,
109 loff_t expected_new_size)
114 /* check the new size */
115 rc = get_stat(fd, &st);
119 if (st.st_size != expected_new_size) {
121 "fallocate succeeded but size reported is wrong\n");
123 "mode %d, offset %llu, len %llu, new_size %llu, expected_new_size %llu\n",
124 mode, (unsigned long long)offset,
125 (unsigned long long)len, (unsigned long long)st.st_size,
126 (unsigned long long)expected_new_size);
133 static int create_hole(int fd)
137 rc = write_data_to_file(fd);
141 lseek(fd, HOLE_BLOCKS * blksize, SEEK_CUR);
143 rc = write_data_to_file(fd);
150 static int do_fallocate(int fd, int mode, loff_t offset,
151 loff_t expected_new_size)
157 rc = __do_fallocate(fd, mode, offset, len);
161 rc = post_fallocate_checks(fd, mode, offset, len, expected_new_size);
163 fprintf(stderr, "post_fallocate_checks failed for mode %d\n",
172 static int test_prealloc_nonsparse(int fd)
175 loff_t offset, expected_new_size;
178 lseek(fd, 0, SEEK_SET);
179 rc = write_data_to_file(fd);
183 rc = get_stat(fd, &st);
187 /* test default mode */
189 offset = lseek(fd, 0, SEEK_END);
190 expected_new_size = WRITE_BLOCKS * blksize + blksize;
191 rc = do_fallocate(fd, mode, offset, expected_new_size);
196 static int test_prealloc_sparse(int fd)
199 loff_t offset, expected_new_size;
202 rc = ftruncate(fd, 0);
204 fprintf(stderr, "ftruncate error %s\n", strerror(errno));
209 lseek(fd, 0, SEEK_SET);
210 rc = create_hole(fd);
214 rc = get_stat(fd, &st);
218 /* test default mode */
220 offset = lseek(fd, (WRITE_BLOCKS + HOLE_BLOCKS / 2) * blksize,
222 expected_new_size = (2 * WRITE_BLOCKS + HOLE_BLOCKS) * blksize;
223 rc = do_fallocate(fd, mode, offset, expected_new_size);
228 int main(int argc, char *argv[])
230 char *fname, *mount_point = NULL;
231 int rc = -EINVAL, fd;
240 if (fname[0] != '/') {
241 fprintf(stderr, "Need absolute path of the file\n");
245 fd = open(fname, O_RDWR | O_CREAT, 0700);
247 fprintf(stderr, "open file %s error: %s\n",
248 fname, strerror(errno));
253 mntpt = setmntent("/etc/mtab", "r");
255 fprintf(stderr, "setmntent error: %s\n",
261 while (NULL != (ent = getmntent(mntpt))) {
262 if (llapi_is_lustre_mnttype(ent->mnt_fsname) == 0) {
263 mount_point = ent->mnt_dir;
269 if (mount_point == NULL) {
270 fprintf(stderr, "file not on lustre filesystem?\n");
274 rc = get_stat(fd, &st);
277 blksize = st.st_blksize;
279 rc = test_prealloc_nonsparse(fd);
283 rc = test_prealloc_sparse(fd);