xfsctl sets errno, we need to return this
[libposix_fallocate_xfs.git] / posix_fallocate_xfs.c
blob4e083c27e12a5a82c40372a1bc99752324839255
1 /*
2 posix_fallocate_xfs preloadable library to make posix_fallocate
3 use XFS' more efficient preallocation using unwritten extents
5 Copyright © 2010 Bjoern JACKE <bjoern@j3e.de>
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef RTLD_NEXT
22 # define _GNU_SOURCE
23 #endif
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <dlfcn.h>
29 #include <xfs/xfs.h>
32 static int (*libc_posix_fallocate)(int, off_t, off_t)= NULL;
34 static void __attribute__ ((constructor)) posix_fallocate_xfs_init(void)
36 libc_posix_fallocate= dlsym(RTLD_NEXT, "posix_fallocate");
37 if (!libc_posix_fallocate || dlerror())
38 _exit(1);
41 int posix_fallocate(int fd, off_t offset, off_t len)
43 xfs_flock64_t fl;
44 off_t new_len = offset + len;
45 int ret;
46 struct stat sbuf;
48 if (new_len < 0)
49 return EFBIG;
51 fl.l_whence = SEEK_SET;
52 fl.l_start = offset;
53 fl.l_len = len;
55 ret=xfsctl(NULL, fd, XFS_IOC_RESVSP, &fl);
57 if (ret != 0)
58 return errno;
61 /* Make sure the space shows up when we enlarged the file: */
62 fstat(fd,&sbuf);
63 if (new_len > sbuf.st_size) {
64 ftruncate(fd, new_len);
66 return 0;
69 int posix_fallocate64(int fd, off64_t offset, off64_t len)
71 xfs_flock64_t fl;
72 off64_t new_len = offset + len;
73 int ret;
74 struct stat64 sbuf;
76 fl.l_whence = SEEK_SET;
77 fl.l_start = offset;
78 fl.l_len = len;
80 ret=xfsctl(NULL, fd, XFS_IOC_RESVSP, &fl);
82 if (ret != 0)
83 return errno;
85 /* Make sure the space shows up when we enlarged the file: */
86 fstat64(fd,&sbuf);
87 if (new_len > sbuf.st_size) {
88 ftruncate64(fd, new_len);
90 return 0;