pang-io: rework api for memory-mapped io
On real hardwareit will use memory-mapped io. Rework pang-io so that it more closely aligns with this paradigm. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		| @@ -3,6 +3,7 @@ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct pang_io; | ||||
| struct fat12_partition; | ||||
| struct fat12_dirent { | ||||
|     char filename[256]; | ||||
| @@ -29,7 +30,7 @@ uint32_t fat12_read_u32(void *ptr); | ||||
| void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value); | ||||
| uint32_t fat12_get_cluster(void *fat, uint32_t cluster); | ||||
|  | ||||
| int fat12_defrag(int fd); | ||||
| int fat12_mkfs(int fd, uint32_t bytes); | ||||
| int fat12_defrag(struct pang_io *io); | ||||
| int fat12_mkfs(struct pang_io *io, uint32_t bytes); | ||||
|  | ||||
| #endif /* PANG_O_LIN_FAT12_H__ */ | ||||
							
								
								
									
										11
									
								
								include/io.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								include/io.h
									
									
									
									
									
								
							| @@ -11,10 +11,11 @@ | ||||
| #include <unistd.h> | ||||
| #endif | ||||
|  | ||||
| ssize_t pang_write(int fd, const void *buf, size_t count); | ||||
| ssize_t pang_read(int fd, void *buf, size_t count); | ||||
| off_t pang_seek(int fd, off_t offset, int whence); | ||||
| int pang_open(const char *pathname, int flags); | ||||
| int pang_close(int fd); | ||||
| struct pang_io; | ||||
|  | ||||
| ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count); | ||||
| ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count); | ||||
| struct pang_io *pang_open(const char *pathname); | ||||
| int pang_close(struct pang_io **io); | ||||
|  | ||||
| #endif /* PANG_O_LIN_IO_H__ */ | ||||
							
								
								
									
										25
									
								
								src/fat12.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								src/fat12.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
| #include <stdio.h> | ||||
|  | ||||
| struct fat12_partition { | ||||
|     int fd; | ||||
|     struct pang_io *io; | ||||
|  | ||||
|     // Number of bytes in a sector (512) | ||||
|     uint32_t sector_size; | ||||
| @@ -105,18 +105,15 @@ int fat12_open(struct fat12_partition *part, const char *filename) { | ||||
|     if (!part) | ||||
|         return -1; | ||||
|  | ||||
|     if (part->fd > 0) | ||||
|     if (part->io) | ||||
|         return -1; | ||||
|  | ||||
|     part->fd = pang_open(filename, O_RDWR); | ||||
|     if (part->fd == -1) { | ||||
|         part->fd = 0; | ||||
|     part->io = pang_open(filename); | ||||
|     if (!part->io) | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     if (pang_read(part->fd, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer)) { | ||||
|     if (pang_read(part->io, 0, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer)) | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     part->sector_size = fat12_read_u16(part->sector_buffer + 0x0b); | ||||
|  | ||||
| @@ -165,8 +162,7 @@ static int fat12_ls_foreach_sector(struct fat12_partition *part, uint32_t sector | ||||
|     struct fat12_dirent dirent; | ||||
|     uint8_t buf[part->sector_size]; | ||||
|     uint32_t offset; | ||||
|     pang_seek(part->fd, sector * part->sector_size, SEEK_SET); | ||||
|     pang_read(part->fd, buf, sizeof(buf)); | ||||
|     pang_read(part->io, sector * part->sector_size, buf, sizeof(buf)); | ||||
|  | ||||
|     for (offset = 0; offset < count; offset++) { | ||||
|         struct fat_directory_entry *entry = &((struct fat_directory_entry *)buf)[offset]; | ||||
| @@ -211,14 +207,10 @@ int fat12_close(struct fat12_partition *part) { | ||||
|     if (!part) | ||||
|         return -1; | ||||
|  | ||||
|     if (part->fd <= 0) | ||||
|         return -1; | ||||
|  | ||||
|     if (-1 == pang_close(part->fd)) { | ||||
|     if (-1 == pang_close(&part->io)) { | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     part->fd = 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -229,6 +221,9 @@ void fat12_free(struct fat12_partition **part) { | ||||
|     if (!*part) | ||||
|         return; | ||||
|  | ||||
|     if ((*part)->io) | ||||
|         fat12_close(*part); | ||||
|  | ||||
|     free(*part); | ||||
|     *part = NULL; | ||||
| } | ||||
							
								
								
									
										41
									
								
								src/io.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								src/io.c
									
									
									
									
									
								
							| @@ -4,24 +4,41 @@ | ||||
| #include "io.h" | ||||
|  | ||||
| #ifdef unix | ||||
| ssize_t pang_write(int fd, const void *buf, size_t count) { | ||||
|     return write(fd, buf, count); | ||||
|  | ||||
| struct pang_io { | ||||
|     int fd; | ||||
| }; | ||||
|  | ||||
| ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count) { | ||||
|     if (-1 == lseek(io->fd, offset, SEEK_SET)) | ||||
|         return -1; | ||||
|     return write(io->fd, buf, count); | ||||
| } | ||||
|  | ||||
| ssize_t pang_read(int fd, void *buf, size_t count) { | ||||
|     return read(fd, buf, count); | ||||
| ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count) { | ||||
|     if (-1 == lseek(io->fd, offset, SEEK_SET)) | ||||
|         return -1; | ||||
|     return read(io->fd, buf, count); | ||||
| } | ||||
|  | ||||
| off_t pang_seek(int fd, off_t offset, int whence) { | ||||
|     return lseek(fd, offset, whence); | ||||
| struct pang_io *pang_open(const char *pathname) { | ||||
|     int fd = open(pathname, O_RDWR | O_TRUNC | O_CREAT, 0777); | ||||
|     if (-1 == fd) | ||||
|         return NULL; | ||||
|     struct pang_io *io = malloc(sizeof(struct pang_io)); | ||||
|     io->fd = fd; | ||||
|     return io; | ||||
| } | ||||
|  | ||||
| int pang_open(const char *pathname, int flags) { | ||||
|     return open(pathname, flags); | ||||
| } | ||||
|  | ||||
| int pang_close(int fd) { | ||||
|     return close(fd); | ||||
| int pang_close(struct pang_io **io) { | ||||
|     if (!io) | ||||
|         return -1; | ||||
|     if (!*io) | ||||
|         return -1; | ||||
|     int ret = close((*io)->fd); | ||||
|     free(*io); | ||||
|     *io = NULL; | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										15
									
								
								src/mkfat.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/mkfat.c
									
									
									
									
									
								
							| @@ -12,8 +12,9 @@ | ||||
| // with length _bytes_. | ||||
| // It will define a root directory size and padding size so that the file sectors | ||||
| // end up on 4096-byte boundaries. | ||||
| int fat12_mkfs(int fd, uint32_t bytes) { | ||||
| int fat12_mkfs(struct pang_io *io, uint32_t bytes) { | ||||
|     uint8_t mbr[512]; | ||||
|     off_t offset = 0; | ||||
|     const uint32_t sector_size  = 512; | ||||
|     uint32_t cluster_size = 4096 / sector_size; // 4 kiB cluster sizes match flash erase block size | ||||
|     if (bytes > 16000000) { | ||||
| @@ -118,9 +119,10 @@ int fat12_mkfs(int fd, uint32_t bytes) { | ||||
|     fat12_write_u8(mbr + 0xff, 0xaa); | ||||
|  | ||||
|     // Write MBR to disk | ||||
|     if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|     if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|         return -1; | ||||
|     } | ||||
|     offset += sector_size; | ||||
|  | ||||
|     memset(mbr, 0, sizeof(mbr)); | ||||
|  | ||||
| @@ -131,25 +133,28 @@ int fat12_mkfs(int fd, uint32_t bytes) { | ||||
|     // Root directory is only one cluster | ||||
|     // fat12_set_cluster(mbr, 2, 0xfff); | ||||
|  | ||||
|     if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|     if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|         return -1; | ||||
|     } | ||||
|     offset += sector_size; | ||||
|  | ||||
|     // Fill in the rest of the FAT | ||||
|     uint32_t fat_sector; | ||||
|     memset(mbr, 0, sizeof(mbr)); | ||||
|     for (fat_sector = 1; fat_sector < fat_size_sectors; fat_sector++) { | ||||
|         if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|         if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|             return -1; | ||||
|         } | ||||
|         offset += sector_size; | ||||
|     } | ||||
|  | ||||
|     // Fill in the root directory | ||||
|     uint32_t root_directory_sector; | ||||
|     for (root_directory_sector = 0; root_directory_sector < cluster_size; root_directory_sector++) { | ||||
|         if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|         if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { | ||||
|             return -1; | ||||
|         } | ||||
|         offset += sector_size; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
| @@ -7,21 +7,22 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "fat12.h" | ||||
| #include "io.h" | ||||
|  | ||||
| static int make_image(const char *name, uint32_t size) { | ||||
|  | ||||
|     int fd = open(name, O_WRONLY | O_CREAT, 0777); | ||||
|     if (-1 == fd) { | ||||
|     struct pang_io *io = pang_open(name); | ||||
|     if (!io) { | ||||
|         fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno)); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     if (-1 == fat12_mkfs(fd, size)) { | ||||
|     if (-1 == fat12_mkfs(io, size)) { | ||||
|         fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno)); | ||||
|         close(fd); | ||||
|         pang_close(&io); | ||||
|         return 1; | ||||
|     } | ||||
|     close(fd); | ||||
|     pang_close(&io); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,21 +7,22 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "fat12.h" | ||||
| #include "io.h" | ||||
|  | ||||
| static int make_image(const char *name, uint32_t size) { | ||||
|  | ||||
|     int fd = open(name, O_WRONLY | O_CREAT, 0777); | ||||
|     if (-1 == fd) { | ||||
|     struct pang_io *io = pang_open(name); | ||||
|     if (!io) { | ||||
|         fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno)); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     if (-1 == fat12_mkfs(fd, size)) { | ||||
|     if (-1 == fat12_mkfs(io, size)) { | ||||
|         fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno)); | ||||
|         close(fd); | ||||
|         pang_close(&io); | ||||
|         return 1; | ||||
|     } | ||||
|     close(fd); | ||||
|     pang_close(&io); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user