Home | History | Annotate | Download | only in ext2fs
      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