xref: /aosp_15_r20/external/e2fsprogs/lib/ext2fs/io_manager.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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