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 
io_channel_set_options(io_channel channel,const char * opts)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 
io_channel_write_byte(io_channel channel,unsigned long offset,int count,const void * data)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 
io_channel_read_blk64(io_channel channel,unsigned long long block,int count,void * data)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 
io_channel_write_blk64(io_channel channel,unsigned long long block,int count,const void * data)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 
io_channel_discard(io_channel channel,unsigned long long block,unsigned long long count)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 
io_channel_alloc_buf(io_channel io,int count,void * ptr)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