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 void usage(char *prog)
56 fprintf(stderr, "usage: %s <filepath>\n", prog);
57 fprintf(stderr, "filepath: absolute pathname of Lustre file\n");
61 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 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 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 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 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 int do_fallocate(int fd, int mode, loff_t offset, loff_t expected_new_size)
155 rc = __do_fallocate(fd, mode, offset, len);
159 rc = post_fallocate_checks(fd, mode, offset, len, expected_new_size);
161 fprintf(stderr, "post_fallocate_checks failed for mode %d\n",
170 int test_prealloc_nonsparse(int fd)
173 loff_t offset, expected_new_size;
176 lseek(fd, 0, SEEK_SET);
177 rc = write_data_to_file(fd);
181 rc = get_stat(fd, &st);
185 /* test default mode */
187 offset = lseek(fd, 0, SEEK_END);
188 expected_new_size = WRITE_BLOCKS * blksize + blksize;
189 rc = do_fallocate(fd, mode, offset, expected_new_size);
194 int test_prealloc_sparse(int fd)
197 loff_t offset, expected_new_size;
200 rc = ftruncate(fd, 0);
202 fprintf(stderr, "ftruncate error %s\n", strerror(errno));
207 lseek(fd, 0, SEEK_SET);
208 rc = create_hole(fd);
212 rc = get_stat(fd, &st);
216 /* test default mode */
218 offset = lseek(fd, (WRITE_BLOCKS + HOLE_BLOCKS / 2) * blksize,
220 expected_new_size = (2 * WRITE_BLOCKS + HOLE_BLOCKS) * blksize;
221 rc = do_fallocate(fd, mode, offset, expected_new_size);
226 int main(int argc, char *argv[])
228 char *fname, *mount_point = NULL;
229 int rc = -EINVAL, fd;
238 if (fname[0] != '/') {
239 fprintf(stderr, "Need absolute path of the file\n");
243 fd = open(fname, O_RDWR | O_CREAT, 0700);
245 fprintf(stderr, "open file %s error: %s\n",
246 fname, strerror(errno));
251 mntpt = setmntent("/etc/mtab", "r");
253 fprintf(stderr, "setmntent error: %s\n",
259 while (NULL != (ent = getmntent(mntpt))) {
260 if (llapi_is_lustre_mnttype(ent->mnt_fsname) == 0) {
261 mount_point = ent->mnt_dir;
267 if (mount_point == NULL) {
268 fprintf(stderr, "file not on lustre filesystem?\n");
272 rc = get_stat(fd, &st);
275 blksize = st.st_blksize;
277 rc = test_prealloc_nonsparse(fd);
281 rc = test_prealloc_sparse(fd);