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