/src/e2fsprogs/lib/ext2fs/io_manager.c
Line | Count | Source |
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 | | |
23 | | errcode_t io_channel_set_options(io_channel channel, const char *opts) |
24 | 0 | { |
25 | 0 | errcode_t retval = 0; |
26 | 0 | char *next, *ptr, *options, *arg; |
27 | |
|
28 | 0 | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
29 | | |
30 | 0 | if (!opts) |
31 | 0 | return 0; |
32 | | |
33 | 0 | if (!channel->manager->set_option) |
34 | 0 | return EXT2_ET_INVALID_ARGUMENT; |
35 | | |
36 | 0 | options = malloc(strlen(opts)+1); |
37 | 0 | if (!options) |
38 | 0 | return EXT2_ET_NO_MEMORY; |
39 | 0 | strcpy(options, opts); |
40 | 0 | ptr = options; |
41 | |
|
42 | 0 | while (ptr && *ptr) { |
43 | 0 | next = strchr(ptr, '&'); |
44 | 0 | if (next) |
45 | 0 | *next++ = 0; |
46 | |
|
47 | 0 | arg = strchr(ptr, '='); |
48 | 0 | if (arg) |
49 | 0 | *arg++ = 0; |
50 | |
|
51 | 0 | retval = (channel->manager->set_option)(channel, ptr, arg); |
52 | 0 | if (retval) |
53 | 0 | break; |
54 | 0 | ptr = next; |
55 | 0 | } |
56 | 0 | free(options); |
57 | 0 | return retval; |
58 | 0 | } |
59 | | |
60 | | errcode_t io_channel_write_byte(io_channel channel, unsigned long offset, |
61 | | int count, const void *data) |
62 | 0 | { |
63 | 0 | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
64 | | |
65 | 0 | if (channel->manager->write_byte) |
66 | 0 | return channel->manager->write_byte(channel, offset, |
67 | 0 | count, data); |
68 | | |
69 | 0 | return EXT2_ET_UNIMPLEMENTED; |
70 | 0 | } |
71 | | |
72 | | errcode_t io_channel_read_blk64(io_channel channel, unsigned long long block, |
73 | | int count, void *data) |
74 | 12.7k | { |
75 | 12.7k | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
76 | | |
77 | 12.7k | if (channel->manager->read_blk64) |
78 | 12.7k | return (channel->manager->read_blk64)(channel, block, |
79 | 12.7k | count, data); |
80 | | |
81 | 0 | if ((block >> 32) != 0) |
82 | 0 | return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; |
83 | | |
84 | 0 | return (channel->manager->read_blk)(channel, (unsigned long) block, |
85 | 0 | count, data); |
86 | 0 | } |
87 | | |
88 | | errcode_t io_channel_write_blk64(io_channel channel, unsigned long long block, |
89 | | int count, const void *data) |
90 | 0 | { |
91 | 0 | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
92 | | |
93 | 0 | if (channel->manager->write_blk64) |
94 | 0 | return (channel->manager->write_blk64)(channel, block, |
95 | 0 | count, data); |
96 | | |
97 | 0 | if ((block >> 32) != 0) |
98 | 0 | return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64; |
99 | | |
100 | 0 | return (channel->manager->write_blk)(channel, (unsigned long) block, |
101 | 0 | count, data); |
102 | 0 | } |
103 | | |
104 | | errcode_t io_channel_discard(io_channel channel, unsigned long long block, |
105 | | unsigned long long count) |
106 | 0 | { |
107 | 0 | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
108 | | |
109 | 0 | if (channel->manager->discard) |
110 | 0 | return (channel->manager->discard)(channel, block, count); |
111 | | |
112 | 0 | return EXT2_ET_UNIMPLEMENTED; |
113 | 0 | } |
114 | | |
115 | | errcode_t io_channel_zeroout(io_channel channel, unsigned long long block, |
116 | | unsigned long long count) |
117 | 0 | { |
118 | 0 | EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); |
119 | | |
120 | 0 | if (channel->manager->zeroout) |
121 | 0 | return (channel->manager->zeroout)(channel, block, count); |
122 | | |
123 | 0 | return EXT2_ET_UNIMPLEMENTED; |
124 | 0 | } |
125 | | |
126 | | errcode_t io_channel_alloc_buf(io_channel io, int count, void *ptr) |
127 | 4.05k | { |
128 | 4.05k | size_t size; |
129 | | |
130 | 4.05k | if (count == 0) |
131 | 3.65k | size = io->block_size; |
132 | 400 | else if (count > 0) |
133 | 0 | size = io->block_size * count; |
134 | 400 | else |
135 | 400 | size = -count; |
136 | | |
137 | 4.05k | if (io->align > 0) { |
138 | 0 | if ((unsigned) io->align > size) |
139 | 0 | size = io->align; |
140 | 0 | return ext2fs_get_memalign(size, io->align, ptr); |
141 | 0 | } else |
142 | 4.05k | return ext2fs_get_mem(size, ptr); |
143 | 4.05k | } |
144 | | |
145 | | errcode_t io_channel_cache_readahead(io_channel io, unsigned long long block, |
146 | | unsigned long long count) |
147 | 13.4M | { |
148 | 13.4M | if (!io->manager->cache_readahead) |
149 | 0 | return EXT2_ET_OP_NOT_SUPPORTED; |
150 | | |
151 | 13.4M | return io->manager->cache_readahead(io, block, count); |
152 | 13.4M | } |