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