1f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o/* 2f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * inode_io.c --- This is allows an inode in an ext2 filesystem image 3f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * to be accessed via the I/O manager interface. 4f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * 5f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * Copyright (C) 2002 Theodore Ts'o. 6f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * 7f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * %Begin-Header% 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 9543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 10f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * %End-Header% 11f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o */ 12f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 13d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 14f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <stdio.h> 15f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <string.h> 16f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#if HAVE_UNISTD_H 17f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <unistd.h> 18f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#endif 19f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#if HAVE_ERRNO_H 20f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <errno.h> 21f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#endif 22f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <time.h> 23f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 24f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include "ext2_fs.h" 25f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include "ext2fs.h" 26f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 27f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o/* 28f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * For checking structure magic numbers... 29f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o */ 30f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 31f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#define EXT2_CHECK_MAGIC(struct, code) \ 32f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((struct)->magic != (code)) return (code) 33f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 34f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostruct inode_private_data { 35f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int magic; 36f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o char name[32]; 37f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_file_t file; 38f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_filsys fs; 39f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_ino_t ino; 40a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o struct ext2_inode inode; 41f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int flags; 42f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *next; 43f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o}; 44f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 45a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o#define CHANNEL_HAS_INODE 0x8000 46a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o 47f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic struct inode_private_data *top_intern; 48f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic int ino_unique = 0; 49f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 50f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_open(const char *name, int flags, io_channel *channel); 51f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_close(io_channel channel); 52f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_set_blksize(io_channel channel, int blksize); 53f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_read_blk(io_channel channel, unsigned long block, 54f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int count, void *data); 55f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_blk(io_channel channel, unsigned long block, 56f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int count, const void *data); 57f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_flush(io_channel channel); 58f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_byte(io_channel channel, unsigned long offset, 59f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int size, const void *data); 60efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_read_blk64(io_channel channel, 6151b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, void *data); 62efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_write_blk64(io_channel channel, 6351b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, const void *data); 64efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 65f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic struct struct_io_manager struct_inode_manager = { 66d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .magic = EXT2_ET_MAGIC_IO_MANAGER, 67d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .name = "Inode I/O Manager", 68d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .open = inode_open, 69d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .close = inode_close, 70d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .set_blksize = inode_set_blksize, 71d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .read_blk = inode_read_blk, 72d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .write_blk = inode_write_blk, 73d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .flush = inode_flush, 74d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .write_byte = inode_write_byte, 75d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .read_blk64 = inode_read_blk64, 76d4ecec45ab0d9d291bcac575988f68993ec98bd0Theodore Ts'o .write_blk64 = inode_write_blk64 77f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o}; 78f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 79f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'oio_manager inode_io_manager = &struct_inode_manager; 80f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 81a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'oerrcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino, 82a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o struct ext2_inode *inode, 83a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o char **name) 84f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 85f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 86f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 87f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 88f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data), 89c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &data))) 90f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 91f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL; 92546a1ff18cc912003883ff67ba3e87c69f700fc4Theodore Ts'o sprintf(data->name, "%u:%d", ino, ino_unique++); 93f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->file = 0; 94f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->fs = fs; 95f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->ino = ino; 96f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->flags = 0; 97a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o if (inode) { 98a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o memcpy(&data->inode, inode, sizeof(struct ext2_inode)); 99a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o data->flags |= CHANNEL_HAS_INODE; 100a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o } 101f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->next = top_intern; 102f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o top_intern = data; 103f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o *name = data->name; 104f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 105f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 106f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 107a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'oerrcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino, 108a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o char **name) 109a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o{ 110a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o return ext2fs_inode_io_intern2(fs, ino, NULL, name); 111a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o} 112a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o 113f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 114f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_open(const char *name, int flags, io_channel *channel) 115f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 116f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io_channel io = NULL; 117f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *prev, *data = NULL; 118f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 119f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int open_flags; 120f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 121f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (name == 0) 122f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return EXT2_ET_BAD_DEVICE_NAME; 123f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 124f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o for (data = top_intern, prev = NULL; data; 125f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o prev = data, data = data->next) 126f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (strcmp(name, data->name) == 0) 127f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o break; 128f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (!data) 129f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ENOENT; 130f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (prev) 131f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o prev->next = data->next; 132f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o else 133f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o top_intern = data->next; 134f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 135c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io); 136f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 137f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 138f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o memset(io, 0, sizeof(struct struct_io_channel)); 139f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 140f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->magic = EXT2_ET_MAGIC_IO_CHANNEL; 141f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->manager = inode_io_manager; 142c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(strlen(name)+1, &io->name); 143f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 144f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 145f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 146f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o strcpy(io->name, name); 147f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->private_data = data; 148f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->block_size = 1024; 149f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->read_error = 0; 150f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->write_error = 0; 151f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->refcount = 1; 152f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 153f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0; 154a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o retval = ext2fs_file_open2(data->fs, data->ino, 155a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o (data->flags & CHANNEL_HAS_INODE) ? 156a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o &data->inode : 0, open_flags, 157a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o &data->file); 158f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 159f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 160efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 161f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o *channel = io; 162f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 163f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 164f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ocleanup: 165624e8ebe3058bad9af6e719b7f9e7afab7d3fe30Eric Sandeen if (io && io->name) 16658caabc37d696363330c390f77a901bbc81cda1eTheodore Ts'o ext2fs_free_mem(&io->name); 16758caabc37d696363330c390f77a901bbc81cda1eTheodore Ts'o if (data) 168c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&data); 169f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (io) 170c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&io); 171f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 172f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 173f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 174f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_close(io_channel channel) 175f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 176f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 177f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval = 0; 178f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 179f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 180f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 181f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 182f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 183f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (--channel->refcount > 0) 184f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 185f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 186f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o retval = ext2fs_file_close(data->file); 187efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 188c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel->private_data); 189f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (channel->name) 190c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel->name); 191c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel); 192f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 193f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 194f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 195f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_set_blksize(io_channel channel, int blksize) 196f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 197f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 198f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 199f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 200f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 201f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 202f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 203f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o channel->block_size = blksize; 204f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 205f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 206f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 207f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 20851b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_read_blk64(io_channel channel, 20951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, void *buf) 210f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 211f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 212f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 213f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 214f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 215f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 216f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 217f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 218f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, 219f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o block * channel->block_size, 220f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 221f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 222f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 223f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o count = (count < 0) ? -count : (count * channel->block_size); 224f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 225f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_read(data->file, buf, count, 0); 226f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 227f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 22851b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_read_blk(io_channel channel, unsigned long block, 22951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos int count, void *buf) 23051b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos{ 23151b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos return inode_read_blk64(channel, block, count, buf); 23251b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos} 23351b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos 23451b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_write_blk64(io_channel channel, 23551b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, const void *buf) 236f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 237f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 238546a1ff18cc912003883ff67ba3e87c69f700fc4Theodore Ts'o errcode_t retval; 239f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 240f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 241f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 242f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 243f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 244f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, 245f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o block * channel->block_size, 246f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 247f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 248f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 249f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o count = (count < 0) ? -count : (count * channel->block_size); 250f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 251f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_write(data->file, buf, count, 0); 252f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 253f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 254efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_write_blk(io_channel channel, unsigned long block, 25551b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos int count, const void *buf) 25651b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos{ 25751b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos return inode_write_blk64(channel, block, count, buf); 25851b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos} 25951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos 260f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_byte(io_channel channel, unsigned long offset, 261f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int size, const void *buf) 262f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 263f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 264f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval = 0; 265f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 266f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 267f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 268f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 269f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 270f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, offset, 271f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 272f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 273f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 274f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_write(data->file, buf, size, 0); 275f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 276f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 277f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o/* 278efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * Flush data buffers to disk. 279f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o */ 280f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_flush(io_channel channel) 281f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 282f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 283efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 284f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 285f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 286f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 287f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 288f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_flush(data->file); 289f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 290f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 291