KCoreAddons

posix_fallocate_mac.h
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 
3  SPDX-FileCopyrightText: 2010 Mozilla Foundation
4  SPDX-FileContributor: Taras Glek <[email protected]>
5 
6  SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later
7 */
8 
9 #ifndef POSIX_FALLOCATE_MAC_H
10 #define POSIX_FALLOCATE_MAC_H
11 
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 
17 // created from the OSX-specific code from Mozilla's mozilla::fallocation() function
18 // of which the licensing information is copied above.
19 // Adaptation (C) 2015,2016 R.J.V. Bertin
20 
21 
22 // From Linux `man posix_fallocate`:
23 // DESCRIPTION
24 // The function posix_fallocate() ensures that disk space is allocated for
25 // the file referred to by the descriptor fd for the bytes in the range
26 // starting at offset and continuing for len bytes. After a successful
27 // call to posix_fallocate(), subsequent writes to bytes in the specified
28 // range are guaranteed not to fail because of lack of disk space.
29 //
30 // If the size of the file is less than offset+len, then the file is
31 // increased to this size; otherwise the file size is left unchanged.
32 
33 // From OS X man fcntl:
34 // F_PREALLOCATE Preallocate file storage space. Note: upon success, the space
35 // that is allocated can be the same size or larger than the space
36 // requested.
37 // The F_PREALLOCATE command operates on the following structure:
38 // typedef struct fstore {
39 // u_int32_t fst_flags; /* IN: flags word */
40 // int fst_posmode; /* IN: indicates offset field */
41 // off_t fst_offset; /* IN: start of the region */
42 // off_t fst_length; /* IN: size of the region */
43 // off_t fst_bytesalloc; /* OUT: number of bytes allocated */
44 // } fstore_t;
45 // The flags (fst_flags) for the F_PREALLOCATE command are as follows:
46 // F_ALLOCATECONTIG Allocate contiguous space.
47 // F_ALLOCATEALL Allocate all requested space or no space at all.
48 // The position modes (fst_posmode) for the F_PREALLOCATE command indicate how to use
49 // the offset field. The modes are as follows:
50 // F_PEOFPOSMODE Allocate from the physical end of file.
51 // F_VOLPOSMODE Allocate from the volume offset.
52 
53 // From OS X man ftruncate:
54 // DESCRIPTION
55 // ftruncate() and truncate() cause the file named by path, or referenced by fildes, to
56 // be truncated (or extended) to length bytes in size. If the file size exceeds length,
57 // any extra data is discarded. If the file size is smaller than length, the file
58 // extended and filled with zeros to the indicated length. The ftruncate() form requires
59 // the file to be open for writing.
60 // Note: ftruncate() and truncate() do not modify the current file offset for any open
61 // file descriptions associated with the file.
62 
63 
64 static int posix_fallocate(int fd, off_t offset, off_t len)
65 {
66  off_t c_test;
67  int ret;
68  if (!__builtin_saddll_overflow(offset, len, &c_test)) {
69  fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, offset + len};
70  // Try to get a continuous chunk of disk space
71  fcntl(fd, F_PREALLOCATE, &store);
72  if (ret < 0) {
73  // OK, perhaps we are too fragmented, allocate non-continuous
74  store.fst_flags = F_ALLOCATEALL;
75  ret = fcntl(fd, F_PREALLOCATE, &store);
76  if (ret < 0) {
77  return ret;
78  }
79  }
80  ret = ftruncate(fd, offset + len);
81  } else {
82  // offset+len would overflow.
83  ret = -1;
84  }
85  return ret;
86 }
87 
88 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jul 3 2020 23:01:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.