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 fabsl NOSIGFE
faccessat SIGFE faccessat SIGFE
facl SIGFE facl SIGFE
fallocate SIGFE
fchdir SIGFE fchdir SIGFE
fchmod SIGFE fchmod SIGFE
fchmodat 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)) if (!NT_SUCCESS (status))
return geterrno_from_nt_status (status); return geterrno_from_nt_status (status);
/* If called through posix_fallocate, silently succeed if /* Never change file size if FALLOC_FL_KEEP_SIZE is specified. */
offset + length is less than the file's actual length. */ if ((mode & FALLOC_FL_KEEP_SIZE)
if (mode == 0 && offset + length < fsi.EndOfFile.QuadPart) && offset + length > fsi.EndOfFile.QuadPart)
return 0; {
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; feofi.EndOfFile.QuadPart = offset + length;
/* Create sparse files only when called through ftruncate, not when /* Create sparse files only when called through ftruncate, not when
called through posix_fallocate. */ called through posix_fallocate. */
if ((mode & __FALLOC_FL_TRUNCATE) if (mode == __FALLOC_FL_TRUNCATE
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE) && !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
&& pc.support_sparse () && pc.support_sparse ()
&& offset + length >= fsi.EndOfFile.QuadPart + (128 * 1024)) && offset + length >= fsi.EndOfFile.QuadPart + (128 * 1024))

View File

@ -483,12 +483,13 @@ details. */
posix_spawn_file_actions_addfchdir_np. posix_spawn_file_actions_addfchdir_np.
347: Add c16rtomb, c32rtomb, mbrtoc16, mbrtoc32. 347: Add c16rtomb, c32rtomb, mbrtoc16, mbrtoc32.
348: Add c8rtomb, mbrtoc. 348: Add c8rtomb, mbrtoc.
349: Add fallocate.
Note that we forgot to bump the api for ualarm, strtoll, strtoull, Note that we forgot to bump the api for ualarm, strtoll, strtoull,
sigaltstack, sethostname. */ sigaltstack, sethostname. */
#define CYGWIN_VERSION_API_MAJOR 0 #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 /* There is also a compatibity version number associated with the shared memory
regions. It is incremented when incompatible changes are made to the shared 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_DONTNEED 4
#define POSIX_FADV_NOREUSE 5 #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 __BEGIN_DECLS
extern int posix_fadvise (int, off_t, off_t, int); extern int posix_fadvise (int, off_t, off_t, int);
extern int posix_fallocate (int, off_t, off_t); extern int posix_fallocate (int, off_t, off_t);
#if __GNU_VISIBLE
extern int fallocate (int, int, off_t, off_t);
#endif
__END_DECLS __END_DECLS

View File

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

View File

@ -2987,6 +2987,40 @@ posix_fadvise (int fd, off_t offset, off_t len, int advice)
return res; 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 extern "C" int
posix_fallocate (int fd, off_t offset, off_t len) 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. New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32.
</para></listitem> </para></listitem>
<listitem><para>
New API call: fallocate (Linux-specific).
</para></listitem>
<listitem><para> <listitem><para>
FIFOs now also work over NFS. FIFOs now also work over NFS.
</para></listitem> </para></listitem>