Whamcloud - gitweb
libext2fs: require cluster size == block_size when opening a !bigalloc fs
[tools/e2fsprogs.git] / lib / ext2fs / inode_io.c
index 5126bae..4faaa48 100644 (file)
@@ -5,8 +5,8 @@
  * 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%
  */
 
@@ -36,10 +36,13 @@ struct inode_private_data {
        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;
 
@@ -53,6 +56,10 @@ static errcode_t inode_write_blk(io_channel channel, unsigned long block,
 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,
@@ -63,13 +70,18 @@ static struct struct_io_manager struct_inode_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;
@@ -83,12 +95,22 @@ errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
        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)
 {
@@ -130,11 +152,13 @@ static errcode_t inode_open(const char *name, int flags, io_channel *channel)
        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;
 
@@ -160,7 +184,7 @@ static errcode_t inode_close(io_channel channel)
                return 0;
 
        retval = ext2fs_file_close(data->file);
-       
+
        ext2fs_free_mem(&channel->private_data);
        if (channel->name)
                ext2fs_free_mem(&channel->name);
@@ -181,8 +205,8 @@ static errcode_t inode_set_blksize(io_channel channel, int blksize)
 }
 
 
-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;
@@ -201,8 +225,14 @@ static errcode_t inode_read_blk(io_channel channel, unsigned long block,
        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;
@@ -221,6 +251,12 @@ static errcode_t inode_write_blk(io_channel channel, unsigned long block,
        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)
 {
@@ -239,12 +275,12 @@ static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
 }
 
 /*
- * 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);