]>
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
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
7 * Copyright (C) 2018 Red Hat, Inc.
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
20 #include <sys/mount.h>
21 #include <sys/param.h>
22 #include <sys/socket.h>
24 #include <sys/types.h>
26 #if defined(__linux__)
30 #include "include/compat.h"
31 #include "include/sock_compat.h"
32 #include "common/safe_io.h"
34 // The type-value for a ZFS FS in fstatfs.
35 #define FS_ZFS_TYPE 0xde
37 // On FreeBSD, ZFS fallocate always fails since it is considered impossible to
38 // reserve space on a COW filesystem. posix_fallocate() returns EINVAL
39 // Linux in this case already emulates the reservation in glibc
40 // In which case it is allocated manually, and still that is not a real guarantee
41 // that a full buffer is allocated on disk, since it could be compressed.
42 // To prevent this the written buffer needs to be loaded with random data.
43 int manual_fallocate(int fd
, off_t offset
, off_t len
) {
44 int r
= lseek(fd
, offset
, SEEK_SET
);
48 // TODO: compressing filesystems would require random data
49 memset(data
, 0x42, sizeof(data
));
50 for (off_t off
= 0; off
< len
; off
+= sizeof(data
)) {
51 if (off
+ static_cast<off_t
>(sizeof(data
)) > len
)
52 r
= safe_write(fd
, data
, len
- off
);
54 r
= safe_write(fd
, data
, sizeof(data
));
62 int on_zfs(int basedir_fd
) {
64 (void)fstatfs(basedir_fd
, &basefs
);
65 return (basefs
.f_type
== FS_ZFS_TYPE
);
68 int ceph_posix_fallocate(int fd
, off_t offset
, off_t len
) {
69 // Return 0 if oke, otherwise errno > 0
71 #ifdef HAVE_POSIX_FALLOCATE
73 return manual_fallocate(fd
, offset
, len
);
75 return posix_fallocate(fd
, offset
, len
);
77 #elif defined(__APPLE__)
79 store
.fst_flags
= F_ALLOCATECONTIG
;
80 store
.fst_posmode
= F_PEOFPOSMODE
;
81 store
.fst_offset
= offset
;
82 store
.fst_length
= len
;
84 int ret
= fcntl(fd
, F_PREALLOCATE
, &store
);
90 return manual_fallocate(fd
, offset
, len
);
94 int pipe_cloexec(int pipefd
[2])
96 #if defined(HAVE_PIPE2)
97 return pipe2(pipefd
, O_CLOEXEC
);
99 if (pipe(pipefd
) == -1)
103 * The old-fashioned, race-condition prone way that we have to fall
104 * back on if pipe2 does not exist.
106 if (fcntl(pipefd
[0], F_SETFD
, FD_CLOEXEC
) < 0) {
110 if (fcntl(pipefd
[1], F_SETFD
, FD_CLOEXEC
) < 0) {
116 int save_errno
= errno
;
117 VOID_TEMP_FAILURE_RETRY(close(pipefd
[0]));
118 VOID_TEMP_FAILURE_RETRY(close(pipefd
[1]));
119 return (errno
= save_errno
, -1);
124 int socket_cloexec(int domain
, int type
, int protocol
)
127 return socket(domain
, type
|SOCK_CLOEXEC
, protocol
);
129 int fd
= socket(domain
, type
, protocol
);
133 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) < 0)
138 int save_errno
= errno
;
139 VOID_TEMP_FAILURE_RETRY(close(fd
));
140 return (errno
= save_errno
, -1);
144 int socketpair_cloexec(int domain
, int type
, int protocol
, int sv
[2])
147 return socketpair(domain
, type
|SOCK_CLOEXEC
, protocol
, sv
);
149 int rc
= socketpair(domain
, type
, protocol
, sv
);
153 if (fcntl(sv
[0], F_SETFD
, FD_CLOEXEC
) < 0)
156 if (fcntl(sv
[1], F_SETFD
, FD_CLOEXEC
) < 0)
161 int save_errno
= errno
;
162 VOID_TEMP_FAILURE_RETRY(close(sv
[0]));
163 VOID_TEMP_FAILURE_RETRY(close(sv
[1]));
164 return (errno
= save_errno
, -1);
168 int accept_cloexec(int sockfd
, struct sockaddr
* addr
, socklen_t
* addrlen
)
171 return accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
);
173 int fd
= accept(sockfd
, addr
, addrlen
);
177 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) < 0)
182 int save_errno
= errno
;
183 VOID_TEMP_FAILURE_RETRY(close(fd
));
184 return (errno
= save_errno
, -1);
188 #if defined(__FreeBSD__)
189 int sched_setaffinity(pid_t pid
, size_t cpusetsize
,