Created
November 30, 2023 09:45
-
-
Save OjaswinM/e67accee3cbb7832bd3f1a9543c01da9 to your computer and use it in GitHub Desktop.
Performing atomic writes using pwritev2() syscall
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 <fcntl.h> | |
#include <unistd.h> | |
#include <sys/uio.h> | |
#include <errno.h> | |
#define RWF_ATOMIC (0x00000020) | |
int main(int argc, char *argv[]) { | |
int ret = 0; | |
char *random_data; | |
if (argc != 4) { | |
printf("Usage: %s <file> <off (KB)> <len (KB)>\n", argv[0]); | |
return 1; | |
} | |
char *filename = argv[1]; | |
// Convert user-supplied buffer size (in KB) to bytes | |
int off_in_KB = atoi(argv[2]); | |
size_t off = off_in_KB * 1024; | |
int len_in_KB = atoi(argv[3]); | |
size_t len = len_in_KB * 1024; | |
// Open a file for writing | |
int fd = open(filename, O_DIRECT | O_WRONLY | O_CREAT | O_DSYNC, 0666); | |
if (fd == -1) { | |
ret = errno; | |
perror("open"); | |
return ret; | |
} | |
// Allocate a buffer to read random data | |
posix_memalign(&random_data, 512, len); | |
if (random_data == NULL) { | |
ret = errno; | |
perror("malloc"); | |
close(fd); | |
return ret; | |
} | |
// Read random data from /dev/urandom | |
int urandom_fd = open("/dev/urandom", O_RDONLY); | |
if (urandom_fd == -1) { | |
ret = errno; | |
perror("open /dev/urandom"); | |
free(random_data); | |
close(fd); | |
return ret; | |
} | |
ssize_t bytes_read = read(urandom_fd, random_data, len); | |
if (bytes_read != len) { | |
ret = errno; | |
perror("read /dev/urandom"); | |
free(random_data); | |
close(urandom_fd); | |
close(fd); | |
return ret; | |
} | |
// Create an iovec structure for the random data | |
struct iovec iov; | |
iov.iov_base = random_data; | |
iov.iov_len = bytes_read; | |
printf("iov.iov_base: %p\n", iov.iov_base); | |
printf("iov.iov_len: %d\n", iov.iov_len); | |
// Write the random data using pwritev2 | |
int flags = RWF_ATOMIC; | |
ssize_t bytes_written = pwritev2(fd, &iov, 1, off, flags); | |
if (bytes_written == -1) { | |
ret = errno; | |
perror("pwritev2"); | |
free(random_data); | |
close(urandom_fd); | |
close(fd); | |
return ret; | |
} | |
printf("Wrote %zd bytes of random data to the file.\n", bytes_written); | |
// Close file and /dev/urandom | |
free(random_data); | |
close(urandom_fd); | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment