]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/compat.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
10 #include <sys/param.h>
11 #include <sys/mount.h>
12 #if defined(__linux__)
16 #include "include/compat.h"
17 #include "common/safe_io.h"
19 // The type-value for a ZFS FS in fstatfs.
20 #define FS_ZFS_TYPE 0xde
22 // On FreeBSD, ZFS fallocate always fails since it is considered impossible to
23 // reserve space on a COW filesystem. posix_fallocate() returns EINVAL
24 // Linux in this case already emulates the reservation in glibc
25 // In which case it is allocated manually, and still that is not a real guarantee
26 // that a full buffer is allocated on disk, since it could be compressed.
27 // To prevent this the written buffer needs to be loaded with random data.
28 int manual_fallocate(int fd
, off_t offset
, off_t len
) {
29 int r
= lseek(fd
, offset
, SEEK_SET
);
33 // TODO: compressing filesystems would require random data
34 memset(data
, 0x42, sizeof(data
));
35 for (off_t off
= 0; off
< len
; off
+= sizeof(data
)) {
36 if (off
+ sizeof(data
) > len
)
37 r
= safe_write(fd
, data
, len
- off
);
39 r
= safe_write(fd
, data
, sizeof(data
));
47 int on_zfs(int basedir_fd
) {
49 (void)fstatfs(basedir_fd
, &basefs
);
50 return (basefs
.f_type
== FS_ZFS_TYPE
);
53 int ceph_posix_fallocate(int fd
, off_t offset
, off_t len
) {
54 // Return 0 if oke, otherwise errno > 0
56 #ifdef HAVE_POSIX_FALLOCATE
58 return manual_fallocate(fd
, offset
, len
);
60 return posix_fallocate(fd
, offset
, len
);
62 #elif defined(__APPLE__)
64 store
.fst_flags
= F_ALLOCATECONTIG
;
65 store
.fst_posmode
= F_PEOFPOSMODE
;
66 store
.fst_offset
= offset
;
67 store
.fst_length
= len
;
69 int ret
= fcntl(fd
, F_PREALLOCATE
, &store
);
75 return manual_fallocate(fd
, offset
, len
);