/* Formats the given file for use by dm-csum */ /* Needed to use pwrite() */ #define _XOPEN_SOURCE 500 #include /* printf() */ #include /* malloc() */ #include /* pwrite() and friends */ #include /* open() */ #include /* open() */ #include /* open() */ #include /* uint8_t and friends */ #include /* memset() */ /* simple definitions so we can copy-paste the structs from the kernel */ #define u8 uint8_t #define __be16 uint16_t #define __be32 uint32_t /* * Copied from the kernel definition, MUST match */ #define RESERVED_INITIAL_SECTORS_D 1 #define RESERVED_INITIAL_SECTORS_M 1 #define SECTORS_PER_IMD 62 struct imd_tuple { __be16 crc; __be16 flags; __be32 tag; } __attribute__ ((packed)); struct imd_sector_header { u8 last_updated; u8 unused1; __be16 crc; __be32 unused3; } __attribute__ ((packed)); /* Format function to use when imd and data are on the same device */ int format_same(int fd, off_t total_size) { int r; off_t off; unsigned char buf[1024]; struct imd_sector_header *m1, *m2; memset(buf, 0, sizeof(buf)); m1 = (struct imd_sector_header *) buf; m2 = (struct imd_sector_header *) (buf + 512); m1->last_updated = 2; m2->last_updated = 1; off = RESERVED_INITIAL_SECTORS_D * 512; while (off < total_size) { r = pwrite(fd, buf, 1024, off); if (r != 1024) return -1; off += 1024 + SECTORS_PER_IMD * 512; } return 0; } int format_diff(int data_fd, int imd_fd, off_t total_size) { printf("Not implemented yet\n"); return 0; } void usage() { printf("Use: mk-dm-csum same \n"); printf(" or: mk-dm-csum diff \n"); } int main(int argc, char **argv) { int fd, imd_fd; off_t total_size; int same; if (argc < 3) { usage(); return 1; } if (strcmp(argv[1], "same") == 0) { same = 1; } else if (strcmp(argv[1], "diff") == 0) { same = 0; } else { usage(); return 1; } fd = open(argv[2], O_WRONLY); if (fd < 0) { perror("Error opening device"); return 1; } /* TODO: diff */ total_size = lseek(fd, 0, SEEK_END); if (total_size == -1) { perror("Error finding out the size"); return 1; } /* round down to a multiple of SECTORS_PER_IMD */ total_size -= total_size % SECTORS_PER_IMD; if (same) { if (format_same(fd, total_size) != 0) { perror("Error formatting"); return 2; } } else { if (format_diff(fd, imd_fd, total_size) != 0) { perror("Error formatting"); return 2; } } if (fsync(fd) != 0) { perror("Error syncing data to disk"); return 3; } return 0; }