Whamcloud - gitweb
Add new inode I/O abstraction interface which exports an inode as
authorTheodore Ts'o <tytso@mit.edu>
Wed, 20 Feb 2002 06:06:25 +0000 (01:06 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 20 Feb 2002 06:06:25 +0000 (01:06 -0500)
an I/O object.

Export ext2_file_flush as a public interface.

Also minor cleanups to tighten code in other I/O abstractions, and to
mark a void * pointer as const in the ext2_file_write interface.

lib/ext2fs/ChangeLog
lib/ext2fs/Makefile.in
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h
lib/ext2fs/fileio.c
lib/ext2fs/inode_io.c [new file with mode: 0644]
lib/ext2fs/test_io.c
lib/ext2fs/unix_io.c

index f229390..e32db2d 100644 (file)
@@ -1,3 +1,14 @@
+2002-02-20  Theodore Tso  <tytso@valinux.com>
+
+       * Makefile.in, inode_io.c, ext2fs.h, ext2_err.et.in: Add new io
+               abstraction interface which exports an ext2 inode.
+
+       * fileio.c (ext2fs_file_flush): Export ext2fs_file_flush as a
+               public interface.
+
+       * test_io.c (test_close), unix_io.c (unix_close): Remove unneeded
+               conditional; save a few bytes.
+       
 2002-02-12  Theodore Tso  <tytso@valinux.com>
 
        * Makefile.in (tst_badblocks): Add some extra .o files when
index 2c2c94c..54dc160 100644 (file)
@@ -43,6 +43,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
        initialize.o \
        inline.o \
        inode.o \
+       inode_io.o \
        ismounted.o \
        link.o \
        llseek.o \
@@ -94,6 +95,7 @@ SRCS= ext2_err.c \
        $(srcdir)/initialize.c \
        $(srcdir)/inline.c \
        $(srcdir)/inode.c \
+       $(srcdir)/inode_io.c \
        $(srcdir)/ismounted.c \
        $(srcdir)/link.c \
        $(srcdir)/llseek.c \
@@ -377,6 +379,10 @@ inode.o: $(srcdir)/inode.c $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
  $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+inode_io.o: $(srcdir)/inode_io.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
index 235f75d..ab36c9d 100644 (file)
@@ -59,8 +59,8 @@ ec    EXT2_ET_MAGIC_EXT2_FILE,
 ec     EXT2_ET_MAGIC_E2IMAGE,
        "Wrong magic number for Ext2 Image Header"
 
-ec     EXT2_ET_MAGIC_RESERVED_8,
-       "Wrong magic number --- RESERVED_8"
+ec     EXT2_ET_MAGIC_INODE_IO_CHANNEL,
+       "Wrong magic number for inode io_channel structure"
 
 ec     EXT2_ET_MAGIC_RESERVED_9,
        "Wrong magic number --- RESERVED_9"
@@ -272,5 +272,8 @@ ec  EXT2_ET_JOURNAL_UNSUPP_VERSION,
 ec     EXT2_ET_LOAD_EXT_JOURNAL,
        "Error loading external journal"
 
+ec     EXT2_ET_NO_JOURNAL,
+       "Journal not found"
+
        end
 
index 75512d1..e37b817 100644 (file)
@@ -638,9 +638,10 @@ extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
                                  int flags, ext2_file_t *ret);
 extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
 extern errcode_t ext2fs_file_close(ext2_file_t file);
+extern errcode_t ext2fs_file_flush(ext2_file_t file);
 extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
                                  unsigned int wanted, unsigned int *got);
-extern errcode_t ext2fs_file_write(ext2_file_t file, void *buf,
+extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
                                   unsigned int nbytes, unsigned int *written);
 extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
                                   int whence, ext2_off_t *ret_pos);
@@ -678,6 +679,23 @@ extern errcode_t ext2fs_initialize(const char *name, int flags,
                                   struct ext2_super_block *param,
                                   io_manager manager, ext2_filsys *ret_fs);
 
+/* icount.c */
+extern void ext2fs_free_icount(ext2_icount_t icount);
+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
+                                      ext2_icount_t hint, ext2_icount_t *ret);
+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
+                                     ext2_icount_t *ret);
+extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
+                                    __u16 *ret);
+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
+                                        __u16 *ret);
+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
+                                        __u16 *ret);
+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
+                                    __u16 count);
+extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
+
 /* inode.c */
 extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
 extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
@@ -703,23 +721,9 @@ extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
 extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
 extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
 
-/* icount.c */
-extern void ext2fs_free_icount(ext2_icount_t icount);
-extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
-                                      ext2_icount_t hint, ext2_icount_t *ret);
-extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
-                                     ext2_icount_t *ret);
-extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
-                                    __u16 *ret);
-extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-                                        __u16 *ret);
-extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-                                        __u16 *ret);
-extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-                                    __u16 count);
-extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
-errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
-
+/* inode_io.c */
+extern io_manager inode_io_manager;
+       
 /* ismounted.c */
 extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
 extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
index e2f4795..f0b216e 100644 (file)
@@ -88,7 +88,7 @@ ext2_filsys ext2fs_file_get_fs(ext2_file_t file)
  * This function flushes the dirty block buffer out to disk if
  * necessary.
  */
-static errcode_t ext2fs_file_flush(ext2_file_t file)
+errcode_t ext2fs_file_flush(ext2_file_t file)
 {
        errcode_t       retval;
        ext2_filsys fs;
@@ -235,7 +235,7 @@ fail:
 }
 
 
-errcode_t ext2fs_file_write(ext2_file_t file, void *buf,
+errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
                            unsigned int nbytes, unsigned int *written)
 {
        ext2_filsys     fs;
diff --git a/lib/ext2fs/inode_io.c b/lib/ext2fs/inode_io.c
new file mode 100644 (file)
index 0000000..bb72403
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * inode_io.c --- This is allows an inode in an ext2 filesystem image
+ *     to be accessed via the I/O manager interface.
+ *
+ * Copyright (C) 2002 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <time.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+         if ((struct)->magic != (code)) return (code)
+
+struct inode_private_data {
+       int                             magic;
+       char                            name[32];
+       ext2_file_t                     file;
+       ext2_filsys                     fs;
+       ext2_ino_t                      ino;
+       int                             flags;
+       struct inode_private_data       *next;
+};
+
+static struct inode_private_data *top_intern;
+static int ino_unique = 0;
+
+static errcode_t inode_open(const char *name, int flags, io_channel *channel);
+static errcode_t inode_close(io_channel channel);
+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 *data);
+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
+                               int count, const void *data);
+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 struct struct_io_manager struct_inode_manager = {
+       EXT2_ET_MAGIC_IO_MANAGER,
+       "Inode I/O Manager",
+       inode_open,
+       inode_close,
+       inode_set_blksize,
+       inode_read_blk,
+       inode_write_blk,
+       inode_flush,
+       inode_write_byte
+};
+
+io_manager inode_io_manager = &struct_inode_manager;
+
+errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
+                                char **name)
+{
+       struct inode_private_data       *data;
+       errcode_t                       retval;
+
+       if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
+                                    (void **) &data)))
+               return retval;
+       data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
+       sprintf(data->name, "%lu:%d", ino, ino_unique++);
+       data->file = 0;
+       data->fs = fs;
+       data->ino = ino;
+       data->flags = 0;
+       data->next = top_intern;
+       top_intern = data;
+       *name = data->name;
+       return 0;
+}
+
+
+static errcode_t inode_open(const char *name, int flags, io_channel *channel)
+{
+       io_channel      io = NULL;
+       struct inode_private_data *prev, *data = NULL;
+       errcode_t       retval;
+       int             open_flags;
+
+       if (name == 0)
+               return EXT2_ET_BAD_DEVICE_NAME;
+
+       for (data = top_intern, prev = NULL; data;
+            prev = data, data = data->next)
+               if (strcmp(name, data->name) == 0)
+                       break;
+       if (!data)
+               return ENOENT;
+       if (prev)
+               prev->next = data->next;
+       else
+               top_intern = data->next;
+
+       retval = ext2fs_get_mem(sizeof(struct struct_io_channel),
+                               (void **) &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);
+       if (retval)
+               goto cleanup;
+
+       strcpy(io->name, name);
+       io->private_data = data;
+       io->block_size = 1024;
+       io->read_error = 0;
+       io->write_error = 0;
+       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);
+       if (retval)
+               goto cleanup;
+               
+       *channel = io;
+       return 0;
+
+cleanup:
+       if (data) {
+               ext2fs_free_mem((void **) &data);
+       }
+       if (io)
+               ext2fs_free_mem((void **) &io);
+       return retval;
+}
+
+static errcode_t inode_close(io_channel channel)
+{
+       struct inode_private_data *data;
+       errcode_t       retval = 0;
+
+       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);
+
+       if (--channel->refcount > 0)
+               return 0;
+
+       retval = ext2fs_file_close(data->file);
+       
+       ext2fs_free_mem((void **) &channel->private_data);
+       if (channel->name)
+               ext2fs_free_mem((void **) &channel->name);
+       ext2fs_free_mem((void **) &channel);
+       return retval;
+}
+
+static errcode_t inode_set_blksize(io_channel channel, int blksize)
+{
+       struct inode_private_data *data;
+       errcode_t               retval;
+
+       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);
+
+       channel->block_size = blksize;
+       return 0;
+}
+
+
+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
+                              int count, void *buf)
+{
+       struct inode_private_data *data;
+       struct inode_cache *cache;
+       errcode_t       retval;
+       char            *cp;
+       int             i, j;
+
+       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);
+
+       if ((retval = ext2fs_file_lseek(data->file,
+                                       block * channel->block_size,
+                                       EXT2_SEEK_SET, 0)))
+               return retval;
+
+       count = (count < 0) ? -count : (count * channel->block_size);
+
+       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)
+{
+       struct inode_private_data *data;
+       struct inode_cache *cache;
+       errcode_t       retval = 0, retval2;
+       const char      *cp;
+       int             writethrough;
+
+       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);
+
+       if ((retval = ext2fs_file_lseek(data->file,
+                                       block * channel->block_size,
+                                       EXT2_SEEK_SET, 0)))
+               return retval;
+
+       count = (count < 0) ? -count : (count * channel->block_size);
+
+       return ext2fs_file_write(data->file, buf, count, 0);
+}
+
+static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
+                                int size, const void *buf)
+{
+       struct inode_private_data *data;
+       errcode_t       retval = 0;
+       size_t          actual;
+
+       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);
+
+       if ((retval = ext2fs_file_lseek(data->file, offset,
+                                       EXT2_SEEK_SET, 0)))
+               return retval;
+
+       return ext2fs_file_write(data->file, buf, size, 0);
+}
+
+/*
+ * Flush data buffers to disk.  
+ */
+static errcode_t inode_flush(io_channel channel)
+{
+       struct inode_private_data *data;
+       errcode_t retval = 0;
+       
+       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);
+
+       return ext2fs_file_flush(data->file);
+}
+
index b259d0f..baca786 100644 (file)
@@ -154,8 +154,7 @@ static errcode_t test_close(io_channel channel)
        if (data->real)
                retval = io_channel_close(data->real);
        
-       if (channel->private_data)
-               ext2fs_free_mem((void **) &channel->private_data);
+       ext2fs_free_mem((void **) &channel->private_data);
        if (channel->name)
                ext2fs_free_mem((void **) &channel->name);
        ext2fs_free_mem((void **) &channel);
index 7fa4b1a..0f993e4 100644 (file)
@@ -385,8 +385,8 @@ static errcode_t unix_close(io_channel channel)
        if (close(data->dev) < 0)
                retval = errno;
        free_cache(channel, data);
-       if (channel->private_data)
-               ext2fs_free_mem((void **) &channel->private_data);
+
+       ext2fs_free_mem((void **) &channel->private_data);
        if (channel->name)
                ext2fs_free_mem((void **) &channel->name);
        ext2fs_free_mem((void **) &channel);