* Copyright (C) 2002 Theodore Ts'o.
*
* %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
* %End-Header%
*/
+#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
ext2_file_t file;
ext2_filsys fs;
ext2_ino_t ino;
+ struct ext2_inode inode;
int flags;
struct inode_private_data *next;
};
+#define CHANNEL_HAS_INODE 0x8000
+
static struct inode_private_data *top_intern;
static int ino_unique = 0;
static errcode_t inode_flush(io_channel channel);
static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
int size, const void *data);
+static errcode_t inode_read_blk64(io_channel channel,
+ unsigned long long block, int count, void *data);
+static errcode_t inode_write_blk64(io_channel channel,
+ unsigned long long block, int count, const void *data);
static struct struct_io_manager struct_inode_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
inode_read_blk,
inode_write_blk,
inode_flush,
- inode_write_byte
+ inode_write_byte,
+ NULL,
+ NULL,
+ inode_read_blk64,
+ inode_write_blk64
};
io_manager inode_io_manager = &struct_inode_manager;
-errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
- char **name)
+errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ char **name)
{
struct inode_private_data *data;
errcode_t retval;
if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
- (void **) &data)))
+ &data)))
return retval;
data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
sprintf(data->name, "%u:%d", ino, ino_unique++);
data->fs = fs;
data->ino = ino;
data->flags = 0;
+ if (inode) {
+ memcpy(&data->inode, inode, sizeof(struct ext2_inode));
+ data->flags |= CHANNEL_HAS_INODE;
+ }
data->next = top_intern;
top_intern = data;
*name = data->name;
return 0;
}
+errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
+ char **name)
+{
+ return ext2fs_inode_io_intern2(fs, ino, NULL, name);
+}
+
static errcode_t inode_open(const char *name, int flags, io_channel *channel)
{
else
top_intern = data->next;
- retval = ext2fs_get_mem(sizeof(struct struct_io_channel),
- (void **) &io);
+ retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
if (retval)
goto cleanup;
memset(io, 0, sizeof(struct struct_io_channel));
io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
io->manager = inode_io_manager;
- retval = ext2fs_get_mem(strlen(name)+1, (void **) &io->name);
+ retval = ext2fs_get_mem(strlen(name)+1, &io->name);
if (retval)
goto cleanup;
io->refcount = 1;
open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
- retval = ext2fs_file_open(data->fs, data->ino, open_flags,
- &data->file);
+ retval = ext2fs_file_open2(data->fs, data->ino,
+ (data->flags & CHANNEL_HAS_INODE) ?
+ &data->inode : 0, open_flags,
+ &data->file);
if (retval)
goto cleanup;
-
+
*channel = io;
return 0;
cleanup:
- if (data) {
- ext2fs_free_mem((void **) &data);
- }
+ if (io && io->name)
+ ext2fs_free_mem(&io->name);
+ if (data)
+ ext2fs_free_mem(&data);
if (io)
- ext2fs_free_mem((void **) &io);
+ ext2fs_free_mem(&io);
return retval;
}
return 0;
retval = ext2fs_file_close(data->file);
-
- ext2fs_free_mem((void **) &channel->private_data);
+
+ ext2fs_free_mem(&channel->private_data);
if (channel->name)
- ext2fs_free_mem((void **) &channel->name);
- ext2fs_free_mem((void **) &channel);
+ ext2fs_free_mem(&channel->name);
+ ext2fs_free_mem(&channel);
return retval;
}
}
-static errcode_t inode_read_blk(io_channel channel, unsigned long block,
- int count, void *buf)
+static errcode_t inode_read_blk64(io_channel channel,
+ unsigned long long block, int count, void *buf)
{
struct inode_private_data *data;
errcode_t retval;
return ext2fs_file_read(data->file, buf, count, 0);
}
-static errcode_t inode_write_blk(io_channel channel, unsigned long block,
- int count, const void *buf)
+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
+ int count, void *buf)
+{
+ return inode_read_blk64(channel, block, count, buf);
+}
+
+static errcode_t inode_write_blk64(io_channel channel,
+ unsigned long long block, int count, const void *buf)
{
struct inode_private_data *data;
errcode_t retval;
return ext2fs_file_write(data->file, buf, count, 0);
}
+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
+ int count, const void *buf)
+{
+ return inode_write_blk64(channel, block, count, buf);
+}
+
static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
int size, const void *buf)
{
}
/*
- * Flush data buffers to disk.
+ * Flush data buffers to disk.
*/
static errcode_t inode_flush(io_channel channel)
{
struct inode_private_data *data;
-
+
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
data = (struct inode_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);