io_manager.c revision a6ce1349539f866334ef3d5758bc2ee44a454acd
146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)/* 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * io_manager.c --- the I/O manager abstraction 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) */ 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <stdio.h> 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string.h> 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_UNISTD_H 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <unistd.h> 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <fcntl.h> 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <time.h> 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_SYS_STAT_H 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <sys/stat.h> 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_SYS_TYPES_H 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <sys/types.h> 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ext2_fs.h" 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ext2fs.h" 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccierrcode_t io_channel_set_options(io_channel channel, const char *opts) 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){ 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) errcode_t retval = 0; 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) char *next, *ptr, *options, *arg; 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!opts) 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return 0; 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!channel->manager->set_option) 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return EXT2_ET_INVALID_ARGUMENT; 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) options = malloc(strlen(opts)+1); 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!options) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return EXT2_ET_NO_MEMORY; 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch strcpy(options, opts); 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ptr = options; 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) while (ptr && *ptr) { 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) next = strchr(ptr, '&'); 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (next) 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *next++ = 0; 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) arg = strchr(ptr, '='); 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (arg) 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *arg++ = 0; 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) retval = (channel->manager->set_option)(channel, ptr, arg); 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (retval) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ptr = next; 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) free(options); 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return retval; 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)errcode_t io_channel_write_byte(io_channel channel, unsigned long offset, 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int count, const void *data) 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){ 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (channel->manager->write_byte) 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return channel->manager->write_byte(channel, offset, 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) count, data); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return EXT2_ET_UNIMPLEMENTED; 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)errcode_t io_channel_read_blk64(io_channel channel, unsigned long long block, 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int count, void *data) 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){ 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (channel->manager->read_blk64) 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return (channel->manager->read_blk64)(channel, block, 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) count, data); 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((block >> 32) != 0) 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return (channel->manager->read_blk)(channel, (unsigned long) block, 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) count, data); 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)errcode_t io_channel_write_blk64(io_channel channel, unsigned long long block, 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int count, const void *data) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){ 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (channel->manager->write_blk64) 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return (channel->manager->write_blk64)(channel, block, 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) count, data); 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((block >> 32) != 0) 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return (channel->manager->write_blk)(channel, (unsigned long) block, 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) count, data); 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)