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