mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Add fallocate in Windows and comment about its use
This commit is contained in:
parent
f564e9b91a
commit
2bebc5d953
3 changed files with 53 additions and 11 deletions
|
|
@ -904,6 +904,15 @@ int windows_ftruncate(int fd, off64_t off)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int windows_fallocate(int fd, int mode, off64_t off, off64_t len)
|
||||
{
|
||||
if (mode != 0)
|
||||
return -1;
|
||||
|
||||
/* no difference with ftruncate because Windows doesn't use sparse files */
|
||||
return windows_ftruncate(fd, off + len);
|
||||
}
|
||||
|
||||
int windows_fsync(int fd)
|
||||
{
|
||||
HANDLE h;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
#define HAVE_FTRUNCATE 1
|
||||
#undef ftruncate
|
||||
#define ftruncate windows_ftruncate
|
||||
#define HAVE_FALLOCATE 1
|
||||
#undef fallocate
|
||||
#define fallocate windows_fallocate
|
||||
#define HAVE_FSYNC 1
|
||||
#undef fsync
|
||||
#define fsync windows_fsync
|
||||
|
|
@ -207,6 +210,11 @@ int lstat_sync(const char* file, struct windows_stat* st, uint64_t* physical);
|
|||
*/
|
||||
int windows_ftruncate(int fd, off64_t off);
|
||||
|
||||
/**
|
||||
* Like the C fallocate().
|
||||
*/
|
||||
int windows_fallocate(int fd, int mode, off64_t off, off64_t len);
|
||||
|
||||
/**
|
||||
* Like the C fsync().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -258,16 +258,32 @@ static int parity_handle_grow(struct snapraid_split_handle* split, data_off_t si
|
|||
|
||||
#if HAVE_FALLOCATE
|
||||
if (!skip_fallocate) {
|
||||
/* allocate real space using the specific Linux fallocate() operation. */
|
||||
/* If the underline file-system doesn't support it, this operation fails, */
|
||||
/* instead posix_fallocate() fallbacks to write the whole file. */
|
||||
/*
|
||||
* Allocate real space using the specific Linux fallocate() operation.
|
||||
* If the underline file-system doesn't support it, this operation fails.
|
||||
*
|
||||
* Instead posix_fallocate() fallbacks to write the whole file,
|
||||
* and we cannot use it as we may need to initialize a multi terabyte
|
||||
* file.
|
||||
*
|
||||
* See: fallocate vs posix_fallocate
|
||||
* http://stackoverflow.com/questions/14063046/fallocate-vs-posix-fallocate
|
||||
*/
|
||||
ret = fallocate(split->f, 0, 0, size);
|
||||
|
||||
/* fallocate() returns the error number as positive integer, */
|
||||
/* and in this case it doesn't set errno, just like posix_fallocate() */
|
||||
/* Checking the glibc code (2.11.1 and 2.14.1) it seems that ENOSYS */
|
||||
/* may be returned in errno, so we support both the return way */
|
||||
if (ret > 0) { /* if a positive error is returned, convert it to errno */
|
||||
/*
|
||||
* In some legacy system fallocate() may return the error number
|
||||
* as positive integer, and in this case it doesn't set errno.
|
||||
*
|
||||
* Detect and handle this case.
|
||||
*
|
||||
* See: Fix fallocate error return on i386
|
||||
* https://sourceware.org/ml/libc-hacker/2010-04/msg00000.html
|
||||
*
|
||||
* See: [PATCH XFS] Fix error return for fallocate() on XFS
|
||||
* http://oss.sgi.com/archives/xfs/2009-11/msg00201.html
|
||||
*/
|
||||
if (ret > 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
errno = ret;
|
||||
ret = -1;
|
||||
|
|
@ -278,9 +294,18 @@ static int parity_handle_grow(struct snapraid_split_handle* split, data_off_t si
|
|||
ret = -1;
|
||||
}
|
||||
|
||||
/* we get EOPNOTSUPP if the operation is not supported, like in ext3/ext2 */
|
||||
/* or ENOSYS with kernel before 2.6.23 */
|
||||
if (errno == EOPNOTSUPP || errno == ENOSYS) {
|
||||
/*
|
||||
* Fallback to ftruncate() if the operation is not supported.
|
||||
*
|
||||
* We get EOPNOTSUPP if the operation is not supported, like in ext3/ext2
|
||||
* or ENOSYS with kernel before 2.6.23, because fallocate is not supported
|
||||
* at all.
|
||||
*
|
||||
* See: man fallocate
|
||||
* ENOSYS - This kernel does not implement fallocate().
|
||||
* EOPNOTSUPP - The file system containing the file referred to by fd does not support this operation
|
||||
*/
|
||||
if (ret != 0 && (errno == EOPNOTSUPP || errno == ENOSYS)) {
|
||||
/* fallback using ftruncate() */
|
||||
ret = ftruncate(split->f, size);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue