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