"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/libglusterfs/src/syscall.c" (16 Sep 2020, 23421 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "syscall.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 7.6_vs_7.7.

    1 /*
    2   Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "glusterfs/compat.h"
   12 #include "glusterfs/syscall.h"
   13 #include "glusterfs/mem-pool.h"
   14 #include "glusterfs/libglusterfs-messages.h"
   15 
   16 #include <sys/types.h>
   17 #include <utime.h>
   18 #include <sys/time.h>
   19 #include <fcntl.h>
   20 #include <unistd.h>
   21 #include <stdarg.h>
   22 #ifdef HAVE_COPY_FILE_RANGE_SYS
   23 #include <sys/syscall.h>
   24 #endif
   25 
   26 #define FS_ERROR_LOG(result)                                                   \
   27     do {                                                                       \
   28         gf_msg_callingfn("FS", GF_LOG_CRITICAL, EIO,                           \
   29                          LG_MSG_SYSCALL_RETURNS_WRONG,                         \
   30                          "returned %zd for the syscall", (ssize_t)result);     \
   31     } while (0)
   32 
   33 /*
   34  * Input to these macros is generally a function call, so capture the result
   35  * i.e. (_ret) in another variable and use that instead of using _ret again
   36  */
   37 #define FS_RET_CHECK(_ret, err)                                                \
   38     ({                                                                         \
   39         typeof(_ret) _result = (_ret);                                         \
   40         if (_result < -1) {                                                    \
   41             FS_ERROR_LOG(_result);                                             \
   42             _result = -1;                                                      \
   43             err = EIO;                                                         \
   44         }                                                                      \
   45         _result;                                                               \
   46     })
   47 
   48 #define FS_RET_CHECK0(_ret, err)                                               \
   49     ({                                                                         \
   50         typeof(_ret) _result0 = (_ret);                                        \
   51         if (_result0 < -1 || _result0 > 0) {                                   \
   52             FS_ERROR_LOG(_result0);                                            \
   53             _result0 = -1;                                                     \
   54             err = EIO;                                                         \
   55         }                                                                      \
   56         _result0;                                                              \
   57     })
   58 
   59 #define FS_RET_CHECK_ERRNO(_ret, err)                                          \
   60     ({                                                                         \
   61         typeof(_ret) _result1 = (_ret);                                        \
   62         if (_result1 < 0) {                                                    \
   63             FS_ERROR_LOG(_result1);                                            \
   64             _result1 = -1;                                                     \
   65             err = EIO;                                                         \
   66         } else if (_result1 > 0) {                                             \
   67             err = _result1;                                                    \
   68             _result1 = -1;                                                     \
   69         }                                                                      \
   70         _result1;                                                              \
   71     })
   72 
   73 int
   74 sys_lstat(const char *path, struct stat *buf)
   75 {
   76     return FS_RET_CHECK0(lstat(path, buf), errno);
   77 }
   78 
   79 int
   80 sys_stat(const char *path, struct stat *buf)
   81 {
   82     return FS_RET_CHECK0(stat(path, buf), errno);
   83 }
   84 
   85 int
   86 sys_fstat(int fd, struct stat *buf)
   87 {
   88     return FS_RET_CHECK0(fstat(fd, buf), errno);
   89 }
   90 
   91 int
   92 sys_fstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
   93 {
   94 #ifdef GF_DARWIN_HOST_OS
   95     if (fchdir(dirfd) < 0)
   96         return -1;
   97     if (flags & AT_SYMLINK_NOFOLLOW)
   98         return FS_RET_CHECK0(lstat(pathname, buf), errno);
   99     else
  100         return FS_RET_CHECK0(stat(pathname, buf), errno);
  101 #else
  102     return FS_RET_CHECK0(fstatat(dirfd, pathname, buf, flags), errno);
  103 #endif
  104 }
  105 
  106 int
  107 sys_openat(int dirfd, const char *pathname, int flags, int mode)
  108 {
  109     int fd;
  110 
  111 #ifdef GF_DARWIN_HOST_OS
  112     if (fchdir(dirfd) < 0)
  113         return -1;
  114     fd = open(pathname, flags, mode);
  115     /* TODO: Shouldn't we restore the old current directory */
  116 #else /* GF_DARWIN_HOST_OS */
  117     fd = openat(dirfd, pathname, flags, mode);
  118 #ifdef __FreeBSD__
  119     /* On FreeBSD S_ISVTX flag is ignored for an open() with O_CREAT set.
  120      * We need to force the flag using fchmod(). */
  121     if ((fd >= 0) && ((flags & O_CREAT) != 0) && ((mode & S_ISVTX) != 0)) {
  122         sys_fchmod(fd, mode);
  123         /* TODO: It's unlikely that fchmod could fail here. However,
  124                  if it fails we cannot always restore the old state
  125                  (if the file existed, we cannot recover it). We would
  126                  need many more system calls to correctly handle all
  127                  possible cases and it doesn't worth it. For now we
  128                  simply ignore the error. */
  129     }
  130 #endif /* __FreeBSD__ */
  131 #endif /* !GF_DARWIN_HOST_OS */
  132 
  133     return FS_RET_CHECK(fd, errno);
  134 }
  135 
  136 int
  137 sys_open(const char *pathname, int flags, int mode)
  138 {
  139     return FS_RET_CHECK(sys_openat(AT_FDCWD, pathname, flags, mode), errno);
  140 }
  141 
  142 DIR *
  143 sys_opendir(const char *name)
  144 {
  145     return opendir(name);
  146 }
  147 
  148 int
  149 sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
  150 {
  151 #ifdef GF_DARWIN_HOST_OS
  152     if (fchdir(dirfd) < 0)
  153         return -1;
  154     return FS_RET_CHECK0(mkdir(pathname, mode), errno);
  155 #else
  156     return FS_RET_CHECK0(mkdirat(dirfd, pathname, mode), errno);
  157 #endif
  158 }
  159 
  160 struct dirent *
  161 sys_readdir(DIR *dir, struct dirent *de)
  162 {
  163 #if !defined(__GLIBC__)
  164     /*
  165      * World+Dog says glibc's readdir(3) is MT-SAFE as long as
  166      * two threads are not accessing the same DIR; there's a
  167      * potential buffer overflow in glibc's readdir_r(3); and
  168      * glibc's readdir_r(3) is deprecated after version 2.22
  169      * with presumed eventual removal.
  170      * Given all that, World+Dog says everyone should just use
  171      * readdir(3). But it's unknown, unclear whether the same
  172      * is also true for *BSD, MacOS, and, etc.
  173      */
  174     struct dirent *entry = NULL;
  175 
  176     (void)readdir_r(dir, de, &entry);
  177     return entry;
  178 #else
  179     return readdir(dir);
  180 #endif
  181 }
  182 
  183 ssize_t
  184 sys_readlink(const char *path, char *buf, size_t bufsiz)
  185 {
  186     return FS_RET_CHECK(readlink(path, buf, bufsiz), errno);
  187 }
  188 
  189 int
  190 sys_closedir(DIR *dir)
  191 {
  192     return FS_RET_CHECK0(closedir(dir), errno);
  193 }
  194 
  195 int
  196 sys_mknod(const char *pathname, mode_t mode, dev_t dev)
  197 {
  198     return FS_RET_CHECK0(mknod(pathname, mode, dev), errno);
  199 }
  200 
  201 int
  202 sys_mkdir(const char *pathname, mode_t mode)
  203 {
  204     return FS_RET_CHECK0(mkdir(pathname, mode), errno);
  205 }
  206 
  207 int
  208 sys_unlink(const char *pathname)
  209 {
  210 #ifdef GF_SOLARIS_HOST_OS
  211     return FS_RET_CHECK0(solaris_unlink(pathname), errno);
  212 #endif
  213     return FS_RET_CHECK0(unlink(pathname), errno);
  214 }
  215 
  216 int
  217 sys_unlinkat(int dfd, const char *pathname)
  218 {
  219 #ifdef GF_SOLARIS_HOST_OS
  220     return FS_RET_CHECK0(solaris_unlinkat(dfd, pathname, 0), errno);
  221 #endif
  222     return FS_RET_CHECK0(unlinkat(dfd, pathname, 0), errno);
  223 }
  224 
  225 int
  226 sys_rmdir(const char *pathname)
  227 {
  228     return FS_RET_CHECK0(rmdir(pathname), errno);
  229 }
  230 
  231 int
  232 sys_symlink(const char *oldpath, const char *newpath)
  233 {
  234     return FS_RET_CHECK0(symlink(oldpath, newpath), errno);
  235 }
  236 
  237 int
  238 sys_symlinkat(const char *oldpath, int dirfd, const char *newpath)
  239 {
  240     return FS_RET_CHECK0(symlinkat(oldpath, dirfd, newpath), errno);
  241 }
  242 
  243 int
  244 sys_rename(const char *oldpath, const char *newpath)
  245 {
  246 #ifdef GF_SOLARIS_HOST_OS
  247     return FS_RET_CHECK0(solaris_rename(oldpath, newpath), errno);
  248 #endif
  249     return FS_RET_CHECK0(rename(oldpath, newpath), errno);
  250 }
  251 
  252 int
  253 sys_link(const char *oldpath, const char *newpath)
  254 {
  255 #ifdef HAVE_LINKAT
  256     /*
  257      * On most systems (Linux being the notable exception), link(2)
  258      * first resolves symlinks. If the target is a directory or
  259      * is nonexistent, it will fail. linkat(2) operates on the
  260      * symlink instead of its target when the AT_SYMLINK_FOLLOW
  261      * flag is not supplied.
  262      */
  263     return FS_RET_CHECK0(linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0),
  264                          errno);
  265 #else
  266     return FS_RET_CHECK0(link(oldpath, newpath), errno);
  267 #endif
  268 }
  269 
  270 int
  271 sys_linkat(int oldfd, const char *oldpath, int newfd, const char *newpath)
  272 {
  273     return FS_RET_CHECK0(linkat(oldfd, oldpath, newfd, newpath, 0), errno);
  274 }
  275 
  276 int
  277 sys_chmod(const char *path, mode_t mode)
  278 {
  279     return FS_RET_CHECK0(chmod(path, mode), errno);
  280 }
  281 
  282 int
  283 sys_fchmod(int fd, mode_t mode)
  284 {
  285     return FS_RET_CHECK0(fchmod(fd, mode), errno);
  286 }
  287 
  288 int
  289 sys_chown(const char *path, uid_t owner, gid_t group)
  290 {
  291     return FS_RET_CHECK0(chown(path, owner, group), errno);
  292 }
  293 
  294 int
  295 sys_fchown(int fd, uid_t owner, gid_t group)
  296 {
  297     return FS_RET_CHECK0(fchown(fd, owner, group), errno);
  298 }
  299 
  300 int
  301 sys_lchown(const char *path, uid_t owner, gid_t group)
  302 {
  303     return FS_RET_CHECK0(lchown(path, owner, group), errno);
  304 }
  305 
  306 int
  307 sys_truncate(const char *path, off_t length)
  308 {
  309     return FS_RET_CHECK0(truncate(path, length), errno);
  310 }
  311 
  312 int
  313 sys_ftruncate(int fd, off_t length)
  314 {
  315     return FS_RET_CHECK0(ftruncate(fd, length), errno);
  316 }
  317 
  318 int
  319 sys_utimes(const char *filename, const struct timeval times[2])
  320 {
  321     return FS_RET_CHECK0(utimes(filename, times), errno);
  322 }
  323 
  324 #if defined(HAVE_UTIMENSAT)
  325 int
  326 sys_utimensat(int dirfd, const char *filename, const struct timespec times[2],
  327               int flags)
  328 {
  329     return FS_RET_CHECK0(utimensat(dirfd, filename, times, flags), errno);
  330 }
  331 #endif
  332 
  333 int
  334 sys_futimes(int fd, const struct timeval times[2])
  335 {
  336     return futimes(fd, times);
  337 }
  338 
  339 int
  340 sys_creat(const char *pathname, mode_t mode)
  341 {
  342     return FS_RET_CHECK(sys_open(pathname, O_CREAT | O_TRUNC | O_WRONLY, mode),
  343                         errno);
  344 }
  345 
  346 ssize_t
  347 sys_readv(int fd, const struct iovec *iov, int iovcnt)
  348 {
  349     return FS_RET_CHECK(readv(fd, iov, iovcnt), errno);
  350 }
  351 
  352 ssize_t
  353 sys_writev(int fd, const struct iovec *iov, int iovcnt)
  354 {
  355     return FS_RET_CHECK(writev(fd, iov, iovcnt), errno);
  356 }
  357 
  358 ssize_t
  359 sys_read(int fd, void *buf, size_t count)
  360 {
  361     return FS_RET_CHECK(read(fd, buf, count), errno);
  362 }
  363 
  364 ssize_t
  365 sys_write(int fd, const void *buf, size_t count)
  366 {
  367     return FS_RET_CHECK(write(fd, buf, count), errno);
  368 }
  369 
  370 ssize_t
  371 sys_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
  372 {
  373     return FS_RET_CHECK(preadv(fd, iov, iovcnt, offset), errno);
  374 }
  375 
  376 ssize_t
  377 sys_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
  378 {
  379     return FS_RET_CHECK(pwritev(fd, iov, iovcnt, offset), errno);
  380 }
  381 
  382 ssize_t
  383 sys_pread(int fd, void *buf, size_t count, off_t offset)
  384 {
  385     return FS_RET_CHECK(pread(fd, buf, count, offset), errno);
  386 }
  387 
  388 ssize_t
  389 sys_pwrite(int fd, const void *buf, size_t count, off_t offset)
  390 {
  391     return FS_RET_CHECK(pwrite(fd, buf, count, offset), errno);
  392 }
  393 
  394 off_t
  395 sys_lseek(int fd, off_t offset, int whence)
  396 {
  397     return FS_RET_CHECK(lseek(fd, offset, whence), errno);
  398 }
  399 
  400 int
  401 sys_statvfs(const char *path, struct statvfs *buf)
  402 {
  403     int ret;
  404 
  405     ret = statvfs(path, buf);
  406 #ifdef __FreeBSD__
  407     /* FreeBSD doesn't return the expected value in buf->f_bsize. It
  408      * contains the optimal I/O size instead of the file system block
  409      * size. Gluster expects that this field contains the block size.
  410      */
  411     if (ret == 0) {
  412         buf->f_bsize = buf->f_frsize;
  413     }
  414 #endif /* __FreeBSD__ */
  415 
  416     return FS_RET_CHECK0(ret, errno);
  417 }
  418 
  419 int
  420 sys_fstatvfs(int fd, struct statvfs *buf)
  421 {
  422     int ret;
  423 
  424     ret = fstatvfs(fd, buf);
  425 #ifdef __FreeBSD__
  426     /* FreeBSD doesn't return the expected value in buf->f_bsize. It
  427      * contains the optimal I/O size instead of the file system block
  428      * size. Gluster expects this field to contain the block size.
  429      */
  430     if (ret == 0) {
  431         buf->f_bsize = buf->f_frsize;
  432     }
  433 #endif /* __FreeBSD__ */
  434 
  435     return FS_RET_CHECK0(ret, errno);
  436 }
  437 
  438 int
  439 sys_close(int fd)
  440 {
  441     int ret = -1;
  442 
  443     if (fd >= 0)
  444         ret = close(fd);
  445 
  446     return FS_RET_CHECK0(ret, errno);
  447 }
  448 
  449 int
  450 sys_fsync(int fd)
  451 {
  452     return FS_RET_CHECK0(fsync(fd), errno);
  453 }
  454 
  455 int
  456 sys_fdatasync(int fd)
  457 {
  458 #ifdef GF_DARWIN_HOST_OS
  459     return FS_RET_CHECK0(fcntl(fd, F_FULLFSYNC), errno);
  460 #elif __FreeBSD__
  461     return FS_RET_CHECK0(fsync(fd), errno);
  462 #else
  463     return FS_RET_CHECK0(fdatasync(fd), errno);
  464 #endif
  465 }
  466 
  467 void
  468 gf_add_prefix(const char *ns, const char *key, char **newkey)
  469 {
  470     /* if we don't have any namespace, append USER NS */
  471     if (strncmp(key, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
  472         strncmp(key, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
  473         strncmp(key, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
  474         strncmp(key, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) {
  475         int ns_length = strlen(ns);
  476         *newkey = GF_MALLOC(ns_length + strlen(key) + 10, gf_common_mt_char);
  477         if (!*newkey)
  478             return;
  479         strcpy(*newkey, ns);
  480         strcat(*newkey, key);
  481     } else {
  482         *newkey = gf_strdup(key);
  483     }
  484 }
  485 
  486 void
  487 gf_remove_prefix(const char *ns, const char *key, char **newkey)
  488 {
  489     int ns_length = strlen(ns);
  490     if (strncmp(key, ns, ns_length) == 0) {
  491         *newkey = GF_MALLOC(-ns_length + strlen(key) + 10, gf_common_mt_char);
  492         if (!*newkey)
  493             return;
  494         strcpy(*newkey, key + ns_length);
  495     } else {
  496         *newkey = gf_strdup(key);
  497     }
  498 }
  499 
  500 int
  501 sys_lsetxattr(const char *path, const char *name, const void *value,
  502               size_t size, int flags)
  503 {
  504 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  505     return FS_RET_CHECK0(lsetxattr(path, name, value, size, flags), errno);
  506 #endif
  507 
  508 #ifdef GF_BSD_HOST_OS
  509     return FS_RET_CHECK0(
  510         extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size),
  511         errno);
  512 #endif
  513 
  514 #ifdef GF_SOLARIS_HOST_OS
  515     return FS_RET_CHECK0(solaris_setxattr(path, name, value, size, flags),
  516                          errno);
  517 #endif
  518 
  519 #ifdef GF_DARWIN_HOST_OS
  520     /* OS X clients will carry other flags, which will be used on a
  521        OS X host, but masked out on others. GF assume NOFOLLOW on Linux,
  522        enforcing  */
  523     return FS_RET_CHECK0(setxattr(path, name, value, size, 0,
  524                                   (flags & ~XATTR_NOSECURITY) | XATTR_NOFOLLOW),
  525                          errno);
  526 #endif
  527 }
  528 
  529 ssize_t
  530 sys_llistxattr(const char *path, char *list, size_t size)
  531 {
  532 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  533     return FS_RET_CHECK(llistxattr(path, list, size), errno);
  534 #endif
  535 
  536 #ifdef GF_BSD_HOST_OS
  537     ssize_t ret = FS_RET_CHECK(
  538         extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size), errno);
  539     gf_extattr_list_reshape(list, ret);
  540     return ret;
  541 #endif
  542 
  543 #ifdef GF_SOLARIS_HOST_OS
  544     return FS_RET_CHECK(solaris_listxattr(path, list, size), errno);
  545 #endif
  546 
  547 #ifdef GF_DARWIN_HOST_OS
  548     return FS_RET_CHECK(listxattr(path, list, size, XATTR_NOFOLLOW), errno);
  549 #endif
  550 }
  551 
  552 ssize_t
  553 sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
  554 {
  555 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  556     return FS_RET_CHECK(lgetxattr(path, name, value, size), errno);
  557 #endif
  558 
  559 #ifdef GF_BSD_HOST_OS
  560     return FS_RET_CHECK(
  561         extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, value, size),
  562         errno);
  563 #endif
  564 
  565 #ifdef GF_SOLARIS_HOST_OS
  566     return FS_RET_CHECK(solaris_getxattr(path, name, value, size), errno);
  567 #endif
  568 
  569 #ifdef GF_DARWIN_HOST_OS
  570     return FS_RET_CHECK(getxattr(path, name, value, size, 0, XATTR_NOFOLLOW),
  571                         errno);
  572 #endif
  573 }
  574 
  575 ssize_t
  576 sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
  577 {
  578 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  579     return FS_RET_CHECK(fgetxattr(filedes, name, value, size), errno);
  580 #endif
  581 
  582 #ifdef GF_BSD_HOST_OS
  583     return FS_RET_CHECK(
  584         extattr_get_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size),
  585         errno);
  586 #endif
  587 
  588 #ifdef GF_SOLARIS_HOST_OS
  589     return FS_RET_CHECK(solaris_fgetxattr(filedes, name, value, size), errno);
  590 #endif
  591 
  592 #ifdef GF_DARWIN_HOST_OS
  593     return FS_RET_CHECK(fgetxattr(filedes, name, value, size, 0, 0), errno);
  594 #endif
  595 }
  596 
  597 int
  598 sys_fremovexattr(int filedes, const char *name)
  599 {
  600 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  601     return FS_RET_CHECK0(fremovexattr(filedes, name), errno);
  602 #endif
  603 
  604 #ifdef GF_BSD_HOST_OS
  605     return FS_RET_CHECK0(
  606         extattr_delete_fd(filedes, EXTATTR_NAMESPACE_USER, name), errno);
  607 #endif
  608 
  609 #ifdef GF_SOLARIS_HOST_OS
  610     return FS_RET_CHECK0(solaris_fremovexattr(filedes, name), errno);
  611 #endif
  612 
  613 #ifdef GF_DARWIN_HOST_OS
  614     return FS_RET_CHECK0(fremovexattr(filedes, name, 0), errno);
  615 #endif
  616 }
  617 
  618 int
  619 sys_fsetxattr(int filedes, const char *name, const void *value, size_t size,
  620               int flags)
  621 {
  622 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  623     return FS_RET_CHECK0(fsetxattr(filedes, name, value, size, flags), errno);
  624 #endif
  625 
  626 #ifdef GF_BSD_HOST_OS
  627     return FS_RET_CHECK0(
  628         extattr_set_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size),
  629         errno);
  630 #endif
  631 
  632 #ifdef GF_SOLARIS_HOST_OS
  633     return FS_RET_CHECK0(solaris_fsetxattr(filedes, name, value, size, flags),
  634                          errno);
  635 #endif
  636 
  637 #ifdef GF_DARWIN_HOST_OS
  638     return FS_RET_CHECK0(
  639         fsetxattr(filedes, name, value, size, 0, flags & ~XATTR_NOSECURITY),
  640         errno);
  641 #endif
  642 }
  643 
  644 ssize_t
  645 sys_flistxattr(int filedes, char *list, size_t size)
  646 {
  647 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  648     return FS_RET_CHECK(flistxattr(filedes, list, size), errno);
  649 #endif
  650 
  651 #ifdef GF_BSD_HOST_OS
  652     ssize_t ret = FS_RET_CHECK(
  653         extattr_list_fd(filedes, EXTATTR_NAMESPACE_USER, list, size), errno);
  654     gf_extattr_list_reshape(list, ret);
  655     return ret;
  656 #endif
  657 
  658 #ifdef GF_SOLARIS_HOST_OS
  659     return FS_RET_CHECK(solaris_flistxattr(filedes, list, size), errno);
  660 #endif
  661 
  662 #ifdef GF_DARWIN_HOST_OS
  663     return FS_RET_CHECK(flistxattr(filedes, list, size, XATTR_NOFOLLOW), errno);
  664 #endif
  665 }
  666 
  667 int
  668 sys_lremovexattr(const char *path, const char *name)
  669 {
  670 #if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
  671     return FS_RET_CHECK0(lremovexattr(path, name), errno);
  672 #endif
  673 
  674 #ifdef GF_BSD_HOST_OS
  675     return FS_RET_CHECK0(
  676         extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name), errno);
  677 #endif
  678 
  679 #ifdef GF_SOLARIS_HOST_OS
  680     return FS_RET_CHECK0(solaris_removexattr(path, name), errno);
  681 #endif
  682 
  683 #ifdef GF_DARWIN_HOST_OS
  684     return FS_RET_CHECK0(removexattr(path, name, XATTR_NOFOLLOW), errno);
  685 #endif
  686 }
  687 
  688 int
  689 sys_access(const char *pathname, int mode)
  690 {
  691     return FS_RET_CHECK0(access(pathname, mode), errno);
  692 }
  693 
  694 int
  695 sys_fallocate(int fd, int mode, off_t offset, off_t len)
  696 {
  697 #ifdef HAVE_FALLOCATE
  698     return FS_RET_CHECK0(fallocate(fd, mode, offset, len), errno);
  699 #endif
  700 
  701 #ifdef HAVE_POSIX_FALLOCATE
  702     if (mode) {
  703         /* keep size not supported */
  704         errno = EOPNOTSUPP;
  705         return -1;
  706     }
  707 
  708     return FS_RET_CHECK_ERRNO(posix_fallocate(fd, offset, len), errno);
  709 #endif
  710 
  711 #if defined(F_ALLOCATECONTIG) && defined(GF_DARWIN_HOST_OS)
  712     /* C conversion from C++ implementation for OSX by Mozilla Foundation */
  713     if (mode) {
  714         /* keep size not supported */
  715         errno = EOPNOTSUPP;
  716         return -1;
  717     }
  718     /*
  719      *   The F_PREALLOCATE command operates on the following structure:
  720      *
  721      *    typedef struct fstore {
  722      *    u_int32_t fst_flags;      // IN: flags word
  723      *    int       fst_posmode;    // IN: indicates offset field
  724      *    off_t     fst_offset;     // IN: start of the region
  725      *    off_t     fst_length;     // IN: size of the region
  726      *    off_t     fst_bytesalloc; // OUT: number of bytes allocated
  727      *    } fstore_t;
  728      *
  729      * The flags (fst_flags) for the F_PREALLOCATE command are as follows:
  730      *    F_ALLOCATECONTIG   Allocate contiguous space.
  731      *    F_ALLOCATEALL      Allocate all requested space or no space at all.
  732      *
  733      * The position modes (fst_posmode) for the F_PREALLOCATE command
  734      * indicate how to use the offset field.  The modes are as follows:
  735      *    F_PEOFPOSMODE   Allocate from the physical end of file.
  736      *    F_VOLPOSMODE    Allocate from the volume offset.
  737      *
  738      */
  739 
  740     int ret;
  741     fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, offset, len, 0};
  742     ret = fcntl(fd, F_PREALLOCATE, &store);
  743     if (ret == -1) {
  744         store.fst_flags = F_ALLOCATEALL;
  745         ret = fcntl(fd, F_PREALLOCATE, &store);
  746     }
  747     if (ret == -1)
  748         return ret;
  749     return FS_RET_CHECK0(ftruncate(fd, offset + len), errno);
  750 #endif
  751     errno = ENOSYS;
  752     return -1;
  753 }
  754 
  755 int
  756 sys_socket(int domain, int type, int protocol)
  757 {
  758 #ifdef SOCK_CLOEXEC
  759     return socket(domain, type | SOCK_CLOEXEC, protocol);
  760 #else
  761     int fd = -1;
  762 
  763     fd = socket(domain, type, protocol);
  764     if (fd >= 0)
  765         fcntl(fd, F_SETFD, FD_CLOEXEC);
  766     return fd;
  767 #endif
  768 }
  769 
  770 #if (defined(HAVE_ACCEPT4) || defined(HAVE_PACCEPT))
  771 static inline int
  772 prep_accept_flags(int flags)
  773 {
  774     if (flags & O_NONBLOCK) {
  775         flags &= ~O_NONBLOCK;
  776         flags |= SOCK_NONBLOCK;
  777     }
  778 
  779     flags |= SOCK_CLOEXEC;
  780 
  781     return flags;
  782 }
  783 #endif
  784 
  785 int
  786 sys_accept(int sock, struct sockaddr *sockaddr, socklen_t *socklen, int flags)
  787 {
  788     int newsock = -1;
  789 
  790 #ifdef HAVE_ACCEPT4
  791 
  792     flags = prep_accept_flags(flags);
  793     newsock = accept4(sock, sockaddr, socklen, flags);
  794 
  795 #elif HAVE_PACCEPT
  796     flags = prep_accept_flags(flags);
  797     newsock = paccept(sock, sockaddr, socklen, NULL, flags);
  798 
  799 #else
  800     int op_errno = 0;
  801     int curflag = 0;
  802     int ret = 0;
  803 
  804     newsock = accept(sock, sockaddr, socklen);
  805     if (newsock != -1) {
  806         curflag = fcntl(newsock, F_GETFL);
  807         if (fcntl(newsock, F_SETFL, curflag | flags) == -1) {
  808             op_errno = errno;
  809             goto err;
  810         }
  811 
  812         curflag = fcntl(newsock, F_GETFD);
  813         if (fcntl(newsock, F_SETFD, curflag | FD_CLOEXEC) == -1) {
  814             op_errno = errno;
  815             goto err;
  816         }
  817     }
  818 
  819 err:
  820     if (op_errno) {
  821         close(newsock);
  822         errno = op_errno;
  823         return -1;
  824     }
  825 
  826 #endif
  827     return newsock;
  828 }
  829 
  830 ssize_t
  831 sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out,
  832                     size_t len, unsigned int flags)
  833 {
  834     /*
  835      * TODO: Add check for other platofrms like freebsd etc if this syscall is
  836      *       not generic.
  837      * This is what the function does.
  838      *       1) Check whether copy_file_range API is present. If so call it.
  839      *       2) If copy_file_range API is not present, then check whether
  840      *          the system call is there. If so, then use syscall to invoke
  841      *          SYS_copy_file_range system call.
  842      *       3) If neither of the above is present, then return ENOSYS.
  843      */
  844 #ifdef HAVE_COPY_FILE_RANGE
  845     return FS_RET_CHECK(
  846         copy_file_range(fd_in, off_in, fd_out, off_out, len, flags), errno);
  847 #else
  848 #ifdef HAVE_COPY_FILE_RANGE_SYS
  849     return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len,
  850                    flags);
  851 #else
  852     errno = ENOSYS;
  853     return -1;
  854 #endif /* HAVE_COPY_FILE_RANGE_SYS */
  855 #endif /* HAVE_COPY_FILE_RANGE */
  856 }