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:
parent
23e9b5cf3c
commit
e01c50c7b0
|
@ -506,6 +506,7 @@ fabsf NOSIGFE
|
|||
fabsl NOSIGFE
|
||||
faccessat SIGFE
|
||||
facl SIGFE
|
||||
fallocate SIGFE
|
||||
fchdir SIGFE
|
||||
fchmod SIGFE
|
||||
fchmodat SIGFE
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* 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. */
|
||||
if (mode == 0 && offset + length < fsi.EndOfFile.QuadPart)
|
||||
|
||||
/* 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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue