diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2023-11-26 21:05:07 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2023-11-28 10:52:05 +0100 |
commit | e01c50c7b0a6c5d2a25feb02958d57902c25c141 (patch) | |
tree | 43f2f7719e14e6a6fbabd8aa1bfbcef5e248bc16 /winsup/cygwin | |
parent | 23e9b5cf3c4ff4507eff8fb9fcf8d5cb15afc694 (diff) | |
download | newlib-e01c50c7b0a6c5d2a25feb02958d57902c25c141.zip newlib-e01c50c7b0a6c5d2a25feb02958d57902c25c141.tar.gz newlib-e01c50c7b0a6c5d2a25feb02958d57902c25c141.tar.bz2 |
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>
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/cygwin.din | 1 | ||||
-rw-r--r-- | winsup/cygwin/fhandler/disk_file.cc | 41 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/include/fcntl.h | 14 | ||||
-rw-r--r-- | winsup/cygwin/release/3.5.0 | 2 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 34 |
6 files changed, 88 insertions, 7 deletions
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index d5e8f8c..9b76ce6 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -506,6 +506,7 @@ fabsf NOSIGFE fabsl NOSIGFE faccessat SIGFE facl SIGFE +fallocate SIGFE fchdir SIGFE fchmod SIGFE fchmodat SIGFE diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc index 51602f3..b49b25c 100644 --- a/winsup/cygwin/fhandler/disk_file.cc +++ b/winsup/cygwin/fhandler/disk_file.cc @@ -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)) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 833de64..c8177c2 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -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 diff --git a/winsup/cygwin/include/fcntl.h b/winsup/cygwin/include/fcntl.h index 1ef51e5..b38dfa5 100644 --- a/winsup/cygwin/include/fcntl.h +++ b/winsup/cygwin/include/fcntl.h @@ -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 diff --git a/winsup/cygwin/release/3.5.0 b/winsup/cygwin/release/3.5.0 index aee21c9..3b6df95 100644 --- a/winsup/cygwin/release/3.5.0 +++ b/winsup/cygwin/release/3.5.0 @@ -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: diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b2e6ba1..0e4c54b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2988,6 +2988,40 @@ posix_fadvise (int fd, off_t offset, off_t len, int advice) } 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) { int res = 0; |