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 <tglek@mozilla.com>
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 <sys/stat.h>
14#include <sys/types.h>
15#include <unistd.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// From Linux `man posix_fallocate`:
22// DESCRIPTION
23// The function posix_fallocate() ensures that disk space is allocated for
24// the file referred to by the descriptor fd for the bytes in the range
25// starting at offset and continuing for len bytes. After a successful
26// call to posix_fallocate(), subsequent writes to bytes in the specified
27// range are guaranteed not to fail because of lack of disk space.
28//
29// If the size of the file is less than offset+len, then the file is
30// increased to this size; otherwise the file size is left unchanged.
31
32// From OS X man fcntl:
33// F_PREALLOCATE Preallocate file storage space. Note: upon success, the space
34// that is allocated can be the same size or larger than the space
35// requested.
36// The F_PREALLOCATE command operates on the following structure:
37// typedef struct fstore {
38// u_int32_t fst_flags; /* IN: flags word */
39// int fst_posmode; /* IN: indicates offset field */
40// off_t fst_offset; /* IN: start of the region */
41// off_t fst_length; /* IN: size of the region */
42// off_t fst_bytesalloc; /* OUT: number of bytes allocated */
43// } fstore_t;
44// The flags (fst_flags) for the F_PREALLOCATE command are as follows:
45// F_ALLOCATECONTIG Allocate contiguous space.
46// F_ALLOCATEALL Allocate all requested space or no space at all.
47// The position modes (fst_posmode) for the F_PREALLOCATE command indicate how to use
48// the offset field. The modes are as follows:
49// F_PEOFPOSMODE Allocate from the physical end of file.
50// F_VOLPOSMODE Allocate from the volume offset.
51
52// From OS X man ftruncate:
53// DESCRIPTION
54// ftruncate() and truncate() cause the file named by path, or referenced by fildes, to
55// be truncated (or extended) to length bytes in size. If the file size exceeds length,
56// any extra data is discarded. If the file size is smaller than length, the file
57// extended and filled with zeros to the indicated length. The ftruncate() form requires
58// the file to be open for writing.
59// Note: ftruncate() and truncate() do not modify the current file offset for any open
60// file descriptions associated with the file.
61
62static int posix_fallocate(int fd, off_t offset, off_t len)
63{
64 off_t c_test;
65 int ret;
66 if (!__builtin_saddll_overflow(offset, len, &c_test)) {
67 fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, offset + len, 0};
68 // Try to get a continuous chunk of disk space
69 ret = fcntl(fd, F_PREALLOCATE, &store);
70 if (ret < 0) {
71 // OK, perhaps we are too fragmented, allocate non-continuous
72 store.fst_flags = F_ALLOCATEALL;
73 ret = fcntl(fd, F_PREALLOCATE, &store);
74 if (ret < 0) {
75 return ret;
76 }
77 }
78 ret = ftruncate(fd, offset + len);
79 } else {
80 // offset+len would overflow.
81 ret = -1;
82 }
83 return ret;
84}
85
86#endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 7 2024 12:01:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.