Whamcloud - gitweb
libext2fs: document EXT2_FLAG_64BITS in ext2fs_open2()
[tools/e2fsprogs.git] / lib / ext2fs / inode_io.c
index 5126bae..8e0944e 100644 (file)
@@ -5,11 +5,12 @@
  * 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
@@ -36,10 +37,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 +57,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 +71,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 +96,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,18 +153,21 @@ 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;
 
 cleanup:
-       if (data) {
+       if (io && io->name)
+               ext2fs_free_mem(&io->name);
+       if (data)
                ext2fs_free_mem(&data);
-       }
        if (io)
                ext2fs_free_mem(&io);
        return retval;
@@ -160,7 +186,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 +207,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 +227,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 +253,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 +277,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);