-
-
Save ayende/5fdb898301b4240436f08d711374c667 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _GNU_SOURCE | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <sys/mman.h> | |
| #include <linux/falloc.h> | |
| #include <errno.h> | |
| #include <string.h> | |
| #include <sys/random.h> | |
| #define MB (1024 * 1024) | |
| void write_all(int fd, const void *buf, size_t count) | |
| { | |
| size_t bytes_written = 0; | |
| const char *ptr = (const char *)buf; | |
| while (bytes_written < count) | |
| { | |
| ssize_t result = write(fd, ptr + bytes_written, count - bytes_written); | |
| if (result < 0) | |
| { | |
| if (errno == EINTR) | |
| continue; | |
| fprintf(stderr, "Write error: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| if (result == 0) | |
| { | |
| fprintf(stderr, "Zero len write is bad: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| bytes_written += result; | |
| } | |
| } | |
| int main() | |
| { | |
| int fd; | |
| char buffer[MB]; | |
| unlink("/mnt/ramdisk/fullfile"); | |
| unlink("/mnt/ramdisk/anotherfile"); | |
| getrandom(buffer, MB, 0); | |
| ssize_t bytes_written; | |
| fd = open("/mnt/ramdisk/fullfile", O_RDWR | O_CREAT | O_TRUNC, 0644); | |
| if (fd == -1) | |
| { | |
| fprintf(stderr, "open full file: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| for (int i = 0; i < 32; i++) | |
| { | |
| write_all(fd, buffer, MB); | |
| } | |
| close(fd); | |
| fd = open("/mnt/ramdisk/fullfile", O_RDWR); | |
| if (fd == -1) | |
| { | |
| fprintf(stderr, "reopen full file: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 12 * MB, 8 * MB) == -1) | |
| { | |
| fprintf(stderr, "fallocate failure: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| close(fd); | |
| fd = open("/mnt/ramdisk/anotherfile", O_RDWR | O_CREAT | O_TRUNC, 0644); | |
| if (fd == -1) | |
| { | |
| fprintf(stderr, "open another file: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| for (int i = 0; i < 4; i++) | |
| { | |
| write_all(fd, buffer, MB); | |
| } | |
| close(fd); | |
| // Write 8 MB to the hole in the first file | |
| fd = open("/mnt/ramdisk/fullfile", O_RDWR); | |
| char *mapped_memory = mmap(NULL, 32 * MB, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
| if (mapped_memory == MAP_FAILED) | |
| { | |
| fprintf(stderr, "fail mmap: errno = %d (%s)\n", errno, strerror(errno)); | |
| exit(EXIT_FAILURE); | |
| } | |
| for (size_t i = (12 * MB); i < (20 * MB); i++) | |
| { | |
| mapped_memory[i] = 1; | |
| } | |
| munmap(mapped_memory, 32 * MB); | |
| close(fd); | |
| printf("Operations completed successfully.\n"); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <windows.h> | |
| #define MB (1024 * 1024) | |
| int main() { | |
| HANDLE hFile, hFile2; | |
| DWORD bytesWritten; | |
| LARGE_INTEGER fileSize, moveAmount; | |
| char* buffer = malloc(MB); | |
| int i; | |
| DeleteFileA("R:\\original_file.bin"); | |
| DeleteFileA("R:\\another_file.bin"); | |
| hFile = CreateFileA("R:/original_file.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
| if (hFile == INVALID_HANDLE_VALUE) { | |
| printf("Error creating file: %d\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| for (int i = 0; i < 20; i++) { | |
| if (!WriteFile(hFile, buffer, MB, &bytesWritten, NULL)) { | |
| fprintf(stderr, "WriteFile failed on iteration %d: %x\n", i, GetLastError()); | |
| exit(__LINE__); | |
| } | |
| if (bytesWritten != MB) { | |
| fprintf(stderr, "Failed to write full buffer on iteration %d\n", i); | |
| exit(__LINE__); | |
| } | |
| } | |
| if (!FlushFileBuffers(hFile)) { | |
| fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| FILE_ZERO_DATA_INFORMATION zeroDataInfo; | |
| zeroDataInfo.FileOffset.QuadPart = 6 * MB; | |
| zeroDataInfo.BeyondFinalZero.QuadPart = 18 * MB; | |
| if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, NULL, NULL) || | |
| !DeviceIoControl(hFile, FSCTL_SET_ZERO_DATA, &zeroDataInfo, sizeof(zeroDataInfo), NULL, 0, NULL, NULL)) { | |
| printf("Error setting zero data: %d\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| if (!FlushFileBuffers(hFile)) { | |
| fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| // Create another file of size 4 MB | |
| hFile2 = CreateFileA("R:/another_file.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
| if (hFile2 == INVALID_HANDLE_VALUE) { | |
| printf("Error creating second file: %d\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| for (int i = 0; i < 12; i++) { | |
| if (!WriteFile(hFile2, buffer, MB, &bytesWritten, NULL)) { | |
| fprintf(stderr, "WriteFile 2 failed on iteration %d: %x\n", i, GetLastError()); | |
| exit(__LINE__); | |
| } | |
| if (bytesWritten != MB) { | |
| fprintf(stderr, "Failed to write full buffer 2 on iteration %d\n", i); | |
| exit(__LINE__); | |
| } | |
| } | |
| HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); | |
| if (hMapFile == NULL) { | |
| fprintf(stderr, "Could not create file mapping object: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| char* lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0); | |
| if (lpMapAddress == NULL) { | |
| fprintf(stderr, "Could not map view of file: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| for (i = 6 * MB; i < 18 * MB; i++) { | |
| ((char*)lpMapAddress)[i]++; | |
| } | |
| if (!FlushViewOfFile(lpMapAddress, 0)) { | |
| fprintf(stderr, "Could not flush view of file: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| if (!FlushFileBuffers(hFile)) { | |
| fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError()); | |
| exit(__LINE__); | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment