From: Stéphane Bacri frisou76@yahoo.fr
--- dlls/ntdll/tests/file.c | 25 +++++++++++++++++++++++++ dlls/ntdll/unix/file.c | 12 ++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 8465ad4543a..553fc1eb160 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1334,6 +1334,30 @@ static void test_file_io_completion(void) pNtClose( h ); }
+static void test_file_setFileAllocationInformation(void) { + FILE_ALLOCATION_INFORMATION fas; + BY_HANDLE_FILE_INFORMATION info; + IO_STATUS_BLOCK io; + HANDLE handle; + int res; + + if( !(handle = create_temp_file(0)) ) return; + + memset( &fas, 0, sizeof(fas) ); + fas.AllocationSize.QuadPart = 1024 * 1024; + res = pNtSetInformationFile( handle, &io, &fas, sizeof fas, FileAllocationInformation ); + + ok ( res == STATUS_SUCCESS, "file allocation failed, NtSetInformationFile returned %x\n", res ); + ok ( io.Status == STATUS_SUCCESS, "file allocation failed, io.Status is %lx\n", io.Status ); + + memset( &info, 0x22, sizeof(info) ); + res = GetFileInformationByHandle( handle, &info ); + ok( res, "GetFileInformationByHandle failed\n" ); + ok( info.nFileSizeLow == fas.AllocationSize.QuadPart, "incorrect file size after allocation\n" ); + + CloseHandle( handle ); +} + static void test_file_full_size_information(void) { IO_STATUS_BLOCK io; @@ -6114,6 +6138,7 @@ START_TEST(file) test_file_access_information(); test_file_attribute_tag_information(); test_file_stat_information(); + test_file_setFileAllocationInformation(); test_dotfile_file_attributes(); test_file_mode(); test_file_readonly_access(); diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index af3052b92e3..177e343a311 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -4672,12 +4672,20 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, if (len >= sizeof(FILE_ALLOCATION_INFORMATION)) { const FILE_ALLOCATION_INFORMATION *info = ptr; + int err;
if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) return io->Status = status;
- if (ftruncate(fd, (off_t)info->AllocationSize.QuadPart) == -1) - status = errno_to_status( errno ); +#ifdef HAVE_POSIX_FALLOCATE + if ((err = posix_fallocate( fd, 0, (off_t)info->AllocationSize.QuadPart )) != 0) + { + if (err == EOPNOTSUPP) WARN( "posix_fallocate not supported on this filesystem\n" ); + else status = errno_to_status( err ); + } +#else + WARN( "setting file allocation information not supported\n" ); +#endif
if (needs_close) close( fd ); }