]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/compat.cc
update sources to 12.2.7
[ceph.git] / 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
3
4 #include <fcntl.h>
5 #include <stdint.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <sys/stat.h>
10 #include <sys/param.h>
11 #include <sys/mount.h>
12 #if defined(__linux__)
13 #include <sys/vfs.h>
14 #endif
15
16 #include "include/compat.h"
17 #include "common/safe_io.h"
18
19 // The type-value for a ZFS FS in fstatfs.
20 #define FS_ZFS_TYPE 0xde
21
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);
30 if (r == -1)
31 return errno;
32 char data[1024*128];
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);
38 else
39 r = safe_write(fd, data, sizeof(data));
40 if (r == -1) {
41 return errno;
42 }
43 }
44 return 0;
45 }
46
47 int on_zfs(int basedir_fd) {
48 struct statfs basefs;
49 (void)fstatfs(basedir_fd, &basefs);
50 return (basefs.f_type == FS_ZFS_TYPE);
51 }
52
53 int ceph_posix_fallocate(int fd, off_t offset, off_t len) {
54 // Return 0 if oke, otherwise errno > 0
55
56 #ifdef HAVE_POSIX_FALLOCATE
57 if (on_zfs(fd)) {
58 return manual_fallocate(fd, offset, len);
59 } else {
60 return posix_fallocate(fd, offset, len);
61 }
62 #elif defined(__APPLE__)
63 fstore_t store;
64 store.fst_flags = F_ALLOCATECONTIG;
65 store.fst_posmode = F_PEOFPOSMODE;
66 store.fst_offset = offset;
67 store.fst_length = len;
68
69 int ret = fcntl(fd, F_PREALLOCATE, &store);
70 if (ret == -1) {
71 ret = errno;
72 }
73 return ret;
74 #else
75 return manual_fallocate(fd, offset, len);
76 #endif
77 }
78