1 /* 2 * io_manager.c --- the I/O manager abstraction 3 */ 4 5 #include "config.h" 6 #include <stdio.h> 7 #include <string.h> 8 #if HAVE_UNISTD_H 9 #include <unistd.h> 10 #endif 11 #include <fcntl.h> 12 #include <time.h> 13 #if HAVE_SYS_STAT_H 14 #include <sys/stat.h> 15 #endif 16 #if HAVE_SYS_TYPES_H 17 #include <sys/types.h> 18 #endif 19 20 #include "ext2_fs.h" 21 #include "ext2fs.h" 22 23 errcode_t io_channel_set_options(io_channel channel, const char *opts) 24 { 25 errcode_t retval = 0; 26 char *next, *ptr, *options, *arg; 27 28 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 29 30 if (!opts) 31 return 0; 32 33 if (!channel->manager->set_option) 34 return EXT2_ET_INVALID_ARGUMENT; 35 36 options = malloc(strlen(opts)+1); 37 if (!options) 38 return EXT2_ET_NO_MEMORY; 39 strcpy(options, opts); 40 ptr = options; 41 42 while (ptr && *ptr) { 43 next = strchr(ptr, '&'); 44 if (next) 45 *next++ = 0; 46 47 arg = strchr(ptr, '='); 48 if (arg) 49 *arg++ = 0; 50 51 retval = (channel->manager->set_option)(channel, ptr, arg); 52 if (retval) 53 break; 54 ptr = next; 55 } 56 free(options); 57 return retval; 58 } 59 60 errcode_t io_channel_write_byte(io_channel channel, unsigned long offset, 61 int count, const void *data) 62 { 63 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 64 65 if (channel->manager->write_byte) 66 return channel->manager->write_byte(channel, offset, 67 count, data); 68 69 return EXT2_ET_UNIMPLEMENTED; 70 } 71 72 errcode_t io_channel_read_blk64(io_channel channel, unsigned long long block, 73 int count, void *data) 74 { 75 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 76 77 if (channel->manager->read_blk64) 78 return (channel->manager->read_blk64)(channel, block, 79 count, data); 80 81 if ((block >> 32) != 0) 82 return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; 83 84 return (channel->manager->read_blk)(channel, (unsigned long) block, 85 count, data); 86 } 87 88 errcode_t io_channel_write_blk64(io_channel channel, unsigned long long block, 89 int count, const void *data) 90 { 91 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 92 93 if (channel->manager->write_blk64) 94 return (channel->manager->write_blk64)(channel, block, 95 count, data); 96 97 if ((block >> 32) != 0) 98 return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; 99 100 return (channel->manager->write_blk)(channel, (unsigned long) block, 101 count, data); 102 } 103 104 errcode_t io_channel_discard(io_channel channel, unsigned long long block, 105 unsigned long long count) 106 { 107 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 108 109 if (channel->manager->discard) 110 return (channel->manager->discard)(channel, block, count); 111 112 return EXT2_ET_UNIMPLEMENTED; 113 } 114 115 errcode_t io_channel_zeroout(io_channel channel, unsigned long long block, 116 unsigned long long count) 117 { 118 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 119 120 if (channel->manager->zeroout) 121 return (channel->manager->zeroout)(channel, block, count); 122 123 return EXT2_ET_UNIMPLEMENTED; 124 } 125 126 errcode_t io_channel_alloc_buf(io_channel io, int count, void *ptr) 127 { 128 size_t size; 129 130 if (count == 0) 131 size = io->block_size; 132 else if (count > 0) 133 size = io->block_size * count; 134 else 135 size = -count; 136 137 if (io->align) 138 return ext2fs_get_memalign(size, io->align, ptr); 139 else 140 return ext2fs_get_mem(size, ptr); 141 } 142 143 errcode_t io_channel_cache_readahead(io_channel io, unsigned long long block, 144 unsigned long long count) 145 { 146 if (!io->manager->cache_readahead) 147 return EXT2_ET_OP_NOT_SUPPORTED; 148 149 return io->manager->cache_readahead(io, block, count); 150 } 151