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 13f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <stdio.h> 14f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <string.h> 15f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#if HAVE_UNISTD_H 16f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <unistd.h> 17f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#endif 18f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#if HAVE_ERRNO_H 19f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <errno.h> 20f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#endif 21f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include <time.h> 22f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 23f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include "ext2_fs.h" 24f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#include "ext2fs.h" 25f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 26f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o/* 27f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o * For checking structure magic numbers... 28f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o */ 29f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 30f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o#define EXT2_CHECK_MAGIC(struct, code) \ 31f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((struct)->magic != (code)) return (code) 32f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 33f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostruct inode_private_data { 34f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int magic; 35f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o char name[32]; 36f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_file_t file; 37f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_filsys fs; 38f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o ext2_ino_t ino; 39a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o struct ext2_inode inode; 40f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int flags; 41f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *next; 42f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o}; 43f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 44a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o#define CHANNEL_HAS_INODE 0x8000 45a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o 46f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic struct inode_private_data *top_intern; 47f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic int ino_unique = 0; 48f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 49f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_open(const char *name, int flags, io_channel *channel); 50f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_close(io_channel channel); 51f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_set_blksize(io_channel channel, int blksize); 52f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_read_blk(io_channel channel, unsigned long block, 53f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int count, void *data); 54f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_blk(io_channel channel, unsigned long block, 55f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int count, const void *data); 56f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_flush(io_channel channel); 57f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_byte(io_channel channel, unsigned long offset, 58f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int size, const void *data); 59efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_read_blk64(io_channel channel, 6051b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, void *data); 61efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_write_blk64(io_channel channel, 6251b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, const void *data); 63efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 64f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic struct struct_io_manager struct_inode_manager = { 65f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_ET_MAGIC_IO_MANAGER, 66f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o "Inode I/O Manager", 67f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_open, 68f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_close, 69f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_set_blksize, 70f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_read_blk, 71f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_write_blk, 72f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o inode_flush, 7351b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos inode_write_byte, 7451b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos NULL, 7551b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos NULL, 7651b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos inode_read_blk64, 7751b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos inode_write_blk64 78f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o}; 79f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 80f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'oio_manager inode_io_manager = &struct_inode_manager; 81f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 82a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'oerrcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino, 83a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o struct ext2_inode *inode, 84a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o char **name) 85f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 86f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 87f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 88f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 89f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data), 90c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &data))) 91f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 92f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL; 93546a1ff18cc912003883ff67ba3e87c69f700fc4Theodore Ts'o sprintf(data->name, "%u:%d", ino, ino_unique++); 94f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->file = 0; 95f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->fs = fs; 96f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->ino = ino; 97f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->flags = 0; 98a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o if (inode) { 99a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o memcpy(&data->inode, inode, sizeof(struct ext2_inode)); 100a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o data->flags |= CHANNEL_HAS_INODE; 101a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o } 102f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data->next = top_intern; 103f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o top_intern = data; 104f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o *name = data->name; 105f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 106f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 107f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 108a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'oerrcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino, 109a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o char **name) 110a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o{ 111a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o return ext2fs_inode_io_intern2(fs, ino, NULL, name); 112a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o} 113a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o 114f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 115f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_open(const char *name, int flags, io_channel *channel) 116f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 117f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io_channel io = NULL; 118f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *prev, *data = NULL; 119f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 120f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int open_flags; 121f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 122f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (name == 0) 123f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return EXT2_ET_BAD_DEVICE_NAME; 124f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 125f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o for (data = top_intern, prev = NULL; data; 126f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o prev = data, data = data->next) 127f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (strcmp(name, data->name) == 0) 128f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o break; 129f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (!data) 130f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ENOENT; 131f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (prev) 132f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o prev->next = data->next; 133f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o else 134f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o top_intern = data->next; 135f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 136c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io); 137f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 138f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 139f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o memset(io, 0, sizeof(struct struct_io_channel)); 140f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 141f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->magic = EXT2_ET_MAGIC_IO_CHANNEL; 142f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->manager = inode_io_manager; 143c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(strlen(name)+1, &io->name); 144f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 145f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 146f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 147f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o strcpy(io->name, name); 148f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->private_data = data; 149f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->block_size = 1024; 150f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->read_error = 0; 151f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->write_error = 0; 152f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o io->refcount = 1; 153f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 154f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0; 155a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o retval = ext2fs_file_open2(data->fs, data->ino, 156a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o (data->flags & CHANNEL_HAS_INODE) ? 157a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o &data->inode : 0, open_flags, 158a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o &data->file); 159f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (retval) 160f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o goto cleanup; 161efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 162f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o *channel = io; 163f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 164f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 165f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ocleanup: 166e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (io && io->name) 167e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_free_mem(&io->name); 168e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (data) 169c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&data); 170f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (io) 171c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&io); 172f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 173f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 174f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 175f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_close(io_channel channel) 176f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 177f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 178f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval = 0; 179f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 180f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 181f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 182f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 183f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 184f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (--channel->refcount > 0) 185f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 186f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 187f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o retval = ext2fs_file_close(data->file); 188efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 189c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel->private_data); 190f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if (channel->name) 191c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel->name); 192c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&channel); 193f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 194f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 195f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 196f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_set_blksize(io_channel channel, int blksize) 197f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 198f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 199f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 200f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 201f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 202f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 203f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 204f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o channel->block_size = blksize; 205f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return 0; 206f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 207f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 208f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 20951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_read_blk64(io_channel channel, 21051b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, void *buf) 211f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 212f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 213f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval; 214f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 215f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 216f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 217f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 218f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 219f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, 220f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o block * channel->block_size, 221f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 222f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 223f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 224f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o count = (count < 0) ? -count : (count * channel->block_size); 225f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 226f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_read(data->file, buf, count, 0); 227f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 228f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 22951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_read_blk(io_channel channel, unsigned long block, 23051b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos int count, void *buf) 23151b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos{ 23251b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos return inode_read_blk64(channel, block, count, buf); 23351b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos} 23451b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos 23551b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santosstatic errcode_t inode_write_blk64(io_channel channel, 23651b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos unsigned long long block, int count, const void *buf) 237f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 238f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 239546a1ff18cc912003883ff67ba3e87c69f700fc4Theodore Ts'o errcode_t retval; 240f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 241f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 242f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 243f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 244f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 245f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, 246f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o block * channel->block_size, 247f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 248f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 249f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 250f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o count = (count < 0) ? -count : (count * channel->block_size); 251f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 252f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_write(data->file, buf, count, 0); 253f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 254f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 255efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t inode_write_blk(io_channel channel, unsigned long block, 25651b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos int count, const void *buf) 25751b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos{ 25851b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos return inode_write_blk64(channel, block, count, buf); 25951b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos} 26051b263e3690ba3136fe63e5c722e0593772620e2Jose R. Santos 261f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_write_byte(io_channel channel, unsigned long offset, 262f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o int size, const void *buf) 263f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 264f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 265f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o errcode_t retval = 0; 266f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 267f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 268f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 269f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 270f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 271f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o if ((retval = ext2fs_file_lseek(data->file, offset, 272f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_SEEK_SET, 0))) 273f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return retval; 274f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 275f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_write(data->file, buf, size, 0); 276f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 277f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 278f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o/* 279efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * Flush data buffers to disk. 280f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o */ 281f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'ostatic errcode_t inode_flush(io_channel channel) 282f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o{ 283f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o struct inode_private_data *data; 284efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 285f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 286f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o data = (struct inode_private_data *) channel->private_data; 287f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL); 288f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 289f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o return ext2fs_file_flush(data->file); 290f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o} 291f12e285ffd9ff0b37c4f91d5ab2b021ed1eb43beTheodore Ts'o 292