inode_io.c revision 543547a52a20cb7e69d74921b2f691078fd55d83
13447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/*
23447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * inode_io.c --- This is allows an inode in an ext2 filesystem image
33447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * 	to be accessed via the I/O manager interface.
43447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
53447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * Copyright (C) 2002 Theodore Ts'o.
63447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
73447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * %Begin-Header%
83447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * This file may be redistributed under the terms of the GNU Library
93447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * General Public License, version 2.
103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * %End-Header%
113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include <stdio.h>
143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include <string.h>
153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#if HAVE_UNISTD_H
163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include <unistd.h>
173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#endif
183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#if HAVE_ERRNO_H
193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include <errno.h>
203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#endif
213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include <time.h>
223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include "ext2_fs.h"
243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#include "ext2fs.h"
253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/*
273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein * For checking structure magic numbers...
283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#define EXT2_CHECK_MAGIC(struct, code) \
313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	  if ((struct)->magic != (code)) return (code)
323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstruct inode_private_data {
343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	int				magic;
353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	char				name[32];
363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ext2_file_t			file;
373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ext2_filsys			fs;
383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ext2_ino_t 			ino;
393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	struct ext2_inode		inode;
403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	int				flags;
413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	struct inode_private_data	*next;
423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein};
433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein#define CHANNEL_HAS_INODE	0x8000
453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic struct inode_private_data *top_intern;
473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic int ino_unique = 0;
483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_open(const char *name, int flags, io_channel *channel);
503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_close(io_channel channel);
513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_set_blksize(io_channel channel, int blksize);
523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_read_blk(io_channel channel, unsigned long block,
533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			       int count, void *data);
543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_write_blk(io_channel channel, unsigned long block,
553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				int count, const void *data);
563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_flush(io_channel channel);
573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_write_byte(io_channel channel, unsigned long offset,
583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				int size, const void *data);
593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_read_blk64(io_channel channel,
603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				unsigned long long block, int count, void *data);
613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_write_blk64(io_channel channel,
623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				unsigned long long block, int count, const void *data);
633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic struct struct_io_manager struct_inode_manager = {
653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	EXT2_ET_MAGIC_IO_MANAGER,
663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	"Inode I/O Manager",
673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_open,
683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_close,
693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_set_blksize,
703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_read_blk,
713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_write_blk,
723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_flush,
733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_write_byte,
743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	NULL,
753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	NULL,
763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_read_blk64,
773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	inode_write_blk64
783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein};
793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinio_manager inode_io_manager = &struct_inode_manager;
813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinerrcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				  struct ext2_inode *inode,
843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				  char **name)
853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein{
863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	struct inode_private_data 	*data;
873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	errcode_t			retval;
883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				     &data)))
913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return retval;
923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	sprintf(data->name, "%u:%d", ino, ino_unique++);
943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data->file = 0;
953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data->fs = fs;
963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data->ino = ino;
973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data->flags = 0;
983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (inode) {
993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		memcpy(&data->inode, inode, sizeof(struct ext2_inode));
1003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		data->flags |= CHANNEL_HAS_INODE;
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	data->next = top_intern;
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	top_intern = data;
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	*name = data->name;
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return 0;
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinerrcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
1093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				 char **name)
1103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein{
1113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	return ext2fs_inode_io_intern2(fs, ino, NULL, name);
1123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein}
1133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_open(const char *name, int flags, io_channel *channel)
1163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein{
1173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io_channel	io = NULL;
1183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	struct inode_private_data *prev, *data = NULL;
1193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	errcode_t	retval;
1203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	int		open_flags;
1213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (name == 0)
1233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return EXT2_ET_BAD_DEVICE_NAME;
1243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	for (data = top_intern, prev = NULL; data;
1263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	     prev = data, data = data->next)
1273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (strcmp(name, data->name) == 0)
1283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			break;
1293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (!data)
1303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return ENOENT;
1313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (prev)
1323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		prev->next = data->next;
1333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	else
1343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		top_intern = data->next;
1353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
1373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (retval)
1383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		goto cleanup;
1393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	memset(io, 0, sizeof(struct struct_io_channel));
1403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
1423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->manager = inode_io_manager;
1433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	retval = ext2fs_get_mem(strlen(name)+1, &io->name);
1443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (retval)
1453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		goto cleanup;
1463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	strcpy(io->name, name);
1483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->private_data = data;
1493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->block_size = 1024;
1503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->read_error = 0;
1513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->write_error = 0;
1523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	io->refcount = 1;
1533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
1553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	retval = ext2fs_file_open2(data->fs, data->ino,
1563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				   (data->flags & CHANNEL_HAS_INODE) ?
1573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				   &data->inode : 0, open_flags,
1583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				   &data->file);
1593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (retval)
1603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		goto cleanup;
1613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	*channel = io;
1633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	return 0;
1643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteincleanup:
1663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (data) {
1673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		ext2fs_free_mem(&data);
1683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (io)
1703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		ext2fs_free_mem(&io);
1713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	return retval;
1723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein}
1733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinstatic errcode_t inode_close(io_channel channel)
1753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein{
1763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	struct inode_private_data *data;
1773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	errcode_t	retval = 0;
1783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	data = (struct inode_private_data *) channel->private_data;
1813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
1823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (--channel->refcount > 0)
1843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return 0;
1853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	retval = ext2fs_file_close(data->file);
1873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ext2fs_free_mem(&channel->private_data);
1893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	if (channel->name)
1903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		ext2fs_free_mem(&channel->name);
1913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ext2fs_free_mem(&channel);
192	return retval;
193}
194
195static errcode_t inode_set_blksize(io_channel channel, int blksize)
196{
197	struct inode_private_data *data;
198
199	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
200	data = (struct inode_private_data *) channel->private_data;
201	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
202
203	channel->block_size = blksize;
204	return 0;
205}
206
207
208static errcode_t inode_read_blk64(io_channel channel,
209				unsigned long long block, int count, void *buf)
210{
211	struct inode_private_data *data;
212	errcode_t	retval;
213
214	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
215	data = (struct inode_private_data *) channel->private_data;
216	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
217
218	if ((retval = ext2fs_file_lseek(data->file,
219					block * channel->block_size,
220					EXT2_SEEK_SET, 0)))
221		return retval;
222
223	count = (count < 0) ? -count : (count * channel->block_size);
224
225	return ext2fs_file_read(data->file, buf, count, 0);
226}
227
228static errcode_t inode_read_blk(io_channel channel, unsigned long block,
229			       int count, void *buf)
230{
231	return inode_read_blk64(channel, block, count, buf);
232}
233
234static errcode_t inode_write_blk64(io_channel channel,
235				unsigned long long block, int count, const void *buf)
236{
237	struct inode_private_data *data;
238	errcode_t	retval;
239
240	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
241	data = (struct inode_private_data *) channel->private_data;
242	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
243
244	if ((retval = ext2fs_file_lseek(data->file,
245					block * channel->block_size,
246					EXT2_SEEK_SET, 0)))
247		return retval;
248
249	count = (count < 0) ? -count : (count * channel->block_size);
250
251	return ext2fs_file_write(data->file, buf, count, 0);
252}
253
254static errcode_t inode_write_blk(io_channel channel, unsigned long block,
255				int count, const void *buf)
256{
257	return inode_write_blk64(channel, block, count, buf);
258}
259
260static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
261				 int size, const void *buf)
262{
263	struct inode_private_data *data;
264	errcode_t	retval = 0;
265
266	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
267	data = (struct inode_private_data *) channel->private_data;
268	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
269
270	if ((retval = ext2fs_file_lseek(data->file, offset,
271					EXT2_SEEK_SET, 0)))
272		return retval;
273
274	return ext2fs_file_write(data->file, buf, size, 0);
275}
276
277/*
278 * Flush data buffers to disk.
279 */
280static errcode_t inode_flush(io_channel channel)
281{
282	struct inode_private_data *data;
283
284	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
285	data = (struct inode_private_data *) channel->private_data;
286	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
287
288	return ext2fs_file_flush(data->file);
289}
290
291