Cygwin: introduce fallocate(2)

First cut of the new, Linux-specific fallocate(2) function.
Do not add any functionality yet, except of basic handling
of FALLOC_FL_KEEP_SIZE.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2023-11-26 21:05:07 +01:00
parent 23e9b5cf3c
commit e01c50c7b0
7 changed files with 92 additions and 7 deletions

View File

@ -506,6 +506,7 @@ fabsf NOSIGFE
fabsl NOSIGFE
faccessat SIGFE
facl SIGFE
fallocate SIGFE
fchdir SIGFE
fchmod SIGFE
fchmodat SIGFE

View File

@ -1153,15 +1153,46 @@ fhandler_disk_file::fallocate (int mode, off_t offset, off_t length)
if (!NT_SUCCESS (status))
return geterrno_from_nt_status (status);
/* If called through posix_fallocate, silently succeed if
offset + length is less than the file's actual length. */
if (mode == 0 && offset + length < fsi.EndOfFile.QuadPart)
return 0;
/* Never change file size if FALLOC_FL_KEEP_SIZE is specified. */
if ((mode & FALLOC_FL_KEEP_SIZE)
&& offset + length > fsi.EndOfFile.QuadPart)
{
if (offset > fsi.EndOfFile.QuadPart) /* no-op */
return 0;
length = fsi.EndOfFile.QuadPart - offset;
}
mode &= ~FALLOC_FL_KEEP_SIZE;
switch (mode)
{
case 0:
case __FALLOC_FL_TRUNCATE:
break;
case FALLOC_FL_PUNCH_HOLE: /* TODO */
return EOPNOTSUPP;
break;
case FALLOC_FL_ZERO_RANGE: /* TODO */
return EOPNOTSUPP;
break;
default:
return EINVAL;
}
if (mode == 0)
{
/* If called through posix_fallocate, silently succeed if
offset + length is less than the file's actual length. */
/* TODO: If the file is sparse, POSIX requires to allocate
the holes within offset and offset + length. */
if (offset + length < fsi.EndOfFile.QuadPart)
return 0;
}
feofi.EndOfFile.QuadPart = offset + length;
/* Create sparse files only when called through ftruncate, not when
called through posix_fallocate. */
if ((mode & __FALLOC_FL_TRUNCATE)
if (mode == __FALLOC_FL_TRUNCATE
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
&& pc.support_sparse ()
&& offset + length >= fsi.EndOfFile.QuadPart + (128 * 1024))

View File

@ -483,12 +483,13 @@ details. */
posix_spawn_file_actions_addfchdir_np.
347: Add c16rtomb, c32rtomb, mbrtoc16, mbrtoc32.
348: Add c8rtomb, mbrtoc.
349: Add fallocate.
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
sigaltstack, sethostname. */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 348
#define CYGWIN_VERSION_API_MINOR 349
/* There is also a compatibity version number associated with the shared memory
regions. It is incremented when incompatible changes are made to the shared

View File

@ -42,12 +42,24 @@ details. */
#define POSIX_FADV_DONTNEED 4
#define POSIX_FADV_NOREUSE 5
#define __FALLOC_FL_TRUNCATE 0x0001 /* internal */
#if __GNU_VISIBLE
#define FALLOC_FL_PUNCH_HOLE 0x0001
#define FALLOC_FL_ZERO_RANGE 0x0002
#define FALLOC_FL_UNSHARE_RANGE 0x0004
#define FALLOC_FL_COLLAPSE_RANGE 0x0008
#define FALLOC_FL_INSERT_RANGE 0x0010
#define FALLOC_FL_KEEP_SIZE 0x1000
/* Internal flags */
#define __FALLOC_FL_TRUNCATE 0x2000
#endif
__BEGIN_DECLS
extern int posix_fadvise (int, off_t, off_t, int);
extern int posix_fallocate (int, off_t, off_t);
#if __GNU_VISIBLE
extern int fallocate (int, int, off_t, off_t);
#endif
__END_DECLS

View File

@ -43,6 +43,8 @@ What's new:
- New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32.
- New API call: fallocate (Linux-specific).
- Implement OSS-based sound mixer device (/dev/mixer).
What changed:

View File

@ -2987,6 +2987,40 @@ posix_fadvise (int fd, off_t offset, off_t len, int advice)
return res;
}
extern "C" int
fallocate (int fd, int mode, off_t offset, off_t len)
{
int res = 0;
/* First check mask of allowed flags */
if (mode & ~(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE
| FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_COLLAPSE_RANGE
| FALLOC_FL_INSERT_RANGE | FALLOC_FL_KEEP_SIZE))
res = EOPNOTSUPP;
/* Either FALLOC_FL_PUNCH_HOLE or FALLOC_FL_ZERO_RANGE, never both */
else if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
== (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
res = EOPNOTSUPP;
/* FALLOC_FL_PUNCH_HOLE must be ORed with FALLOC_FL_KEEP_SIZE */
else if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE))
== FALLOC_FL_PUNCH_HOLE)
res = EOPNOTSUPP;
else if (offset < 0 || len == 0)
res = EINVAL;
else
{
cygheap_fdget cfd (fd);
if (cfd >= 0)
res = cfd->fallocate (mode, offset, len);
else
res = EBADF;
if (res == EISDIR)
res = ENODEV;
}
syscall_printf ("%R = posix_fallocate(%d, %D, %D)", res, fd, offset, len);
return 0;
}
extern "C" int
posix_fallocate (int fd, off_t offset, off_t len)
{

View File

@ -74,6 +74,10 @@ posix_spawn_file_actions_addfchdir_np.
New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32.
</para></listitem>
<listitem><para>
New API call: fallocate (Linux-specific).
</para></listitem>
<listitem><para>
FIFOs now also work over NFS.
</para></listitem>