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