Skip to content

Instantly share code, notes, and snippets.

@redixhumayun
Created February 17, 2026 22:05
Show Gist options
  • Select an option

  • Save redixhumayun/8f402d30ffc8437e043394b9c003698b to your computer and use it in GitHub Desktop.

Select an option

Save redixhumayun/8f402d30ffc8437e043394b9c003698b to your computer and use it in GitHub Desktop.
Comparison of two C files to verify the requirement for aligned structs for direct IO
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#define BUF_SIZE 4096
struct __attribute__((packed)) Header {
char tag; // 1 byte — forces misalignment of subsequent fields
unsigned long id; // 8 bytes, but at offset 1 due to packing
char data[BUF_SIZE - 9];
};
int main() {
// malloc returns ~16-byte aligned memory, NOT 4096-aligned
struct Header *buf = malloc(sizeof(struct Header));
if (!buf) { perror("malloc"); return 1; }
memset(buf, 0, sizeof(*buf));
buf->tag = 'X';
buf->id = 42;
strcpy(buf->data, "hello direct io");
printf("buffer address: %p\n", (void *)buf);
printf("buffer size: %zu\n", sizeof(*buf));
printf("aligned to 512? %s\n", ((uintptr_t)buf % 512 == 0) ? "yes" : "no");
printf("aligned to 4096? %s\n", ((uintptr_t)buf % 4096 == 0) ? "yes" : "no");
// open with O_DIRECT
int fd = open("/tmp/direct_io_test.dat", O_CREAT | O_WRONLY | O_DIRECT, 0644);
if (fd < 0) { perror("open"); free(buf); return 1; }
ssize_t written = write(fd, buf, BUF_SIZE);
if (written < 0) {
printf("write failed: %s (errno=%d)\n", strerror(errno), errno);
} else {
printf("write succeeded: %zd bytes\n", written);
}
close(fd);
free(buf);
return 0;
}
/**
* Second half of the program
*/
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#define BUF_SIZE 4096
#define ALIGNMENT 4096
struct __attribute__((packed)) Header {
char tag;
unsigned long id;
char data[BUF_SIZE - 9];
};
int main() {
struct Header *buf = NULL;
int ret = posix_memalign((void **)&buf, ALIGNMENT, sizeof(struct Header));
if (ret != 0) { fprintf(stderr, "posix_memalign failed: %s\n", strerror(ret)); return 1; }
memset(buf, 0, sizeof(*buf));
buf->tag = 'X';
buf->id = 42;
strcpy(buf->data, "hello direct io");
printf("buffer address: %p\n", (void *)buf);
printf("buffer size: %zu\n", sizeof(*buf));
printf("aligned to 512? %s\n", ((uintptr_t)buf % 512 == 0) ? "yes" : "no");
printf("aligned to 4096? %s\n", ((uintptr_t)buf % 4096 == 0) ? "yes" : "no");
int fd = open("/tmp/direct_io_test_aligned.dat", O_CREAT | O_WRONLY | O_DIRECT, 0644);
if (fd < 0) { perror("open"); free(buf); return 1; }
ssize_t written = write(fd, buf, BUF_SIZE);
if (written < 0) {
printf("write failed: %s (errno=%d)\n", strerror(errno), errno);
} else {
printf("write succeeded: %zd bytes\n", written);
}
close(fd);
free(buf);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment