2 * inode_io.c --- This is allows an inode in an ext2 filesystem image
3 * to be accessed via the I/O manager interface.
5 * Copyright (C) 2002 Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Library
9 * General Public License, version 2.
27 * For checking structure magic numbers...
30 #define EXT2_CHECK_MAGIC(struct, code) \
31 if ((struct)->magic != (code)) return (code)
33 struct inode_private_data {
39 struct ext2_inode inode;
41 struct inode_private_data *next;
44 #define CHANNEL_HAS_INODE 0x8000
46 static struct inode_private_data *top_intern;
47 static int ino_unique = 0;
49 static errcode_t inode_open(const char *name, int flags, io_channel *channel);
50 static errcode_t inode_close(io_channel channel);
51 static errcode_t inode_set_blksize(io_channel channel, int blksize);
52 static errcode_t inode_read_blk(io_channel channel, unsigned long block,
53 int count, void *data);
54 static errcode_t inode_write_blk(io_channel channel, unsigned long block,
55 int count, const void *data);
56 static errcode_t inode_flush(io_channel channel);
57 static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
58 int size, const void *data);
59 static errcode_t inode_read_blk64(io_channel channel,
60 unsigned long long block, int count, void *data);
61 static errcode_t inode_write_blk64(io_channel channel,
62 unsigned long long block, int count, const void *data);
64 static struct struct_io_manager struct_inode_manager = {
65 EXT2_ET_MAGIC_IO_MANAGER,
80 io_manager inode_io_manager = &struct_inode_manager;
82 errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
83 struct ext2_inode *inode,
86 struct inode_private_data *data;
89 if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
92 data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
93 sprintf(data->name, "%u:%d", ino, ino_unique++);
99 memcpy(&data->inode, inode, sizeof(struct ext2_inode));
100 data->flags |= CHANNEL_HAS_INODE;
102 data->next = top_intern;
108 errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
111 return ext2fs_inode_io_intern2(fs, ino, NULL, name);
115 static errcode_t inode_open(const char *name, int flags, io_channel *channel)
117 io_channel io = NULL;
118 struct inode_private_data *prev, *data = NULL;
123 return EXT2_ET_BAD_DEVICE_NAME;
125 for (data = top_intern, prev = NULL; data;
126 prev = data, data = data->next)
127 if (strcmp(name, data->name) == 0)
132 prev->next = data->next;
134 top_intern = data->next;
136 retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
139 memset(io, 0, sizeof(struct struct_io_channel));
141 io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
142 io->manager = inode_io_manager;
143 retval = ext2fs_get_mem(strlen(name)+1, &io->name);
147 strcpy(io->name, name);
148 io->private_data = data;
149 io->block_size = 1024;
154 open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
155 retval = ext2fs_file_open2(data->fs, data->ino,
156 (data->flags & CHANNEL_HAS_INODE) ?
157 &data->inode : 0, open_flags,
167 ext2fs_free_mem(&io->name);
169 ext2fs_free_mem(&data);
171 ext2fs_free_mem(&io);
175 static errcode_t inode_close(io_channel channel)
177 struct inode_private_data *data;
178 errcode_t retval = 0;
180 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
181 data = (struct inode_private_data *) channel->private_data;
182 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
184 if (--channel->refcount > 0)
187 retval = ext2fs_file_close(data->file);
189 ext2fs_free_mem(&channel->private_data);
191 ext2fs_free_mem(&channel->name);
192 ext2fs_free_mem(&channel);
196 static errcode_t inode_set_blksize(io_channel channel, int blksize)
198 struct inode_private_data *data;
200 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
201 data = (struct inode_private_data *) channel->private_data;
202 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
204 channel->block_size = blksize;
209 static errcode_t inode_read_blk64(io_channel channel,
210 unsigned long long block, int count, void *buf)
212 struct inode_private_data *data;
215 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
216 data = (struct inode_private_data *) channel->private_data;
217 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
219 if ((retval = ext2fs_file_lseek(data->file,
220 block * channel->block_size,
224 count = (count < 0) ? -count : (count * channel->block_size);
226 return ext2fs_file_read(data->file, buf, count, 0);
229 static errcode_t inode_read_blk(io_channel channel, unsigned long block,
230 int count, void *buf)
232 return inode_read_blk64(channel, block, count, buf);
235 static errcode_t inode_write_blk64(io_channel channel,
236 unsigned long long block, int count, const void *buf)
238 struct inode_private_data *data;
241 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
242 data = (struct inode_private_data *) channel->private_data;
243 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
245 if ((retval = ext2fs_file_lseek(data->file,
246 block * channel->block_size,
250 count = (count < 0) ? -count : (count * channel->block_size);
252 return ext2fs_file_write(data->file, buf, count, 0);
255 static errcode_t inode_write_blk(io_channel channel, unsigned long block,
256 int count, const void *buf)
258 return inode_write_blk64(channel, block, count, buf);
261 static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
262 int size, const void *buf)
264 struct inode_private_data *data;
265 errcode_t retval = 0;
267 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
268 data = (struct inode_private_data *) channel->private_data;
269 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
271 if ((retval = ext2fs_file_lseek(data->file, offset,
275 return ext2fs_file_write(data->file, buf, size, 0);
279 * Flush data buffers to disk.
281 static errcode_t inode_flush(io_channel channel)
283 struct inode_private_data *data;
285 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
286 data = (struct inode_private_data *) channel->private_data;
287 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
289 return ext2fs_file_flush(data->file);