Whamcloud - gitweb
Many files:
authorTheodore Ts'o <tytso@mit.edu>
Mon, 23 Mar 1998 02:06:52 +0000 (02:06 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 23 Mar 1998 02:06:52 +0000 (02:06 +0000)
  ext2fs.h: Add new superblock fields (s_algorithm_usage_bitmap,
   s_prealloc_blocks, s_prealloc_dir_blocks).  Added conditional defines
   of new features COMPAT_DIR_PREALLOC, RO_COMPAT_LARGE_FILE
   RO_COMPAT_BTREE_DIR, INCOMPAT_COMPRESSION, INCOMPAT_DIRNAME_SIZE.
   Changed the library to declare that we support COMPAT_DIR_PREALLOC,
   INCOMPAT_DIRNAME_SIZE, RO_COMPAT_LARGE_FILE.
  fileio.c: Rename function ext2fs_file_llseek to be ext2fs_file_lseek,
   which is more accurate.
  block.c: Add new function ext2fs_block_iterate3 which calls the
   iterator function with the blockcount argument of type blkcnt_t.  This
   version of the function is allowed to handle large files; the other
   fucntions are not.
  ext2fs.h: Add new type blkcnt_t
  ext2_err.et.in: Add error code EXT2_ET_FILE_TOO_BIG
  block.c (ext2fs_block_iterate2): Fix bug where the block count field
   wasn't getting correctly incremented for sparse files when the
   indirect or doubly-indirect block specified in the inode was zero.
  unlink.c (unlink_proc):
  lookup.c (lookup_proc):
  link.c (link_proc):
  get_pathname.c (get_pathname_proc):
  dir_iterate.c (ext2fs_process_dir_block): Mask off high 8 bits from
   dirent->name_len, so it can be used for other purposes.
  ext2fs.h: Add definition of EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE, and
   indicate that we have support for this incompatible option.

lib/ext2fs/ChangeLog
lib/ext2fs/block.c
lib/ext2fs/dir_iterate.c
lib/ext2fs/dll/jump.funcs
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h
lib/ext2fs/fileio.c
lib/ext2fs/get_pathname.c
lib/ext2fs/link.c
lib/ext2fs/lookup.c
lib/ext2fs/unlink.c

index aa5aa5f..99285ee 100644 (file)
@@ -1,3 +1,45 @@
+1998-03-21  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * ext2fs.h: Add new superblock fields (s_algorithm_usage_bitmap, 
+               s_prealloc_blocks, s_prealloc_dir_blocks).  Added
+               conditional defines of new features COMPAT_DIR_PREALLOC,
+               RO_COMPAT_LARGE_FILE RO_COMPAT_BTREE_DIR,
+               INCOMPAT_COMPRESSION, INCOMPAT_DIRNAME_SIZE.  Changed
+               the library to declare that we support COMPAT_DIR_PREALLOC, 
+               INCOMPAT_DIRNAME_SIZE, RO_COMPAT_LARGE_FILE.
+
+       * fileio.c: Rename function ext2fs_file_llseek to be
+               ext2fs_file_lseek, which is more accurate.
+
+       * block.c: Add new function ext2fs_block_iterate3 which calls
+               the iterator function with the blockcount argument of
+               type blkcnt_t.  This version of the function is
+               allowed to handle large files; the other fucntions are
+               not.
+
+       * ext2fs.h: Add new type blkcnt_t
+
+       * ext2_err.et.in: Add error code EXT2_ET_FILE_TOO_BIG
+
+       * block.c (ext2fs_block_iterate2): Fix bug where the block count
+               field wasn't getting correctly incremented for sparse
+               files when the indirect or doubly-indirect block
+               specified in the inode was zero.
+
+Sun Mar  8 22:42:47 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * unlink.c (unlink_proc): 
+       * lookup.c (lookup_proc): 
+       * link.c (link_proc): 
+       * get_pathname.c (get_pathname_proc): 
+       * dir_iterate.c (ext2fs_process_dir_block): Mask off high 8 bits
+               from dirent->name_len, so it can be used for other
+               purposes.
+
+       * ext2fs.h: Add definition of EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE,
+               and indicate that we have support for this incompatible
+               option.
+
 Mon Feb 23 08:46:33 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * ext2_err.et.in: Added new error code, EXT2_ET_CANCEL_REQUESTED.
index 1293403..455307b 100644 (file)
@@ -27,11 +27,11 @@ struct block_context {
        ext2_filsys     fs;
        int (*func)(ext2_filsys fs,
                    blk_t       *blocknr,
-                   int         bcount,
+                   blkcnt_t    bcount,
                    blk_t       ref_blk,
                    int         ref_offset,
                    void        *priv_data);
-       int             bcount;
+       blkcnt_t        bcount;
        int             bsize;
        int             flags;
        errcode_t       errcode;
@@ -301,13 +301,13 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
        return ret;
 }
        
-errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+errcode_t ext2fs_block_iterate3(ext2_filsys fs,
                                ino_t   ino,
                                int     flags,
                                char *block_buf,
                                int (*func)(ext2_filsys fs,
                                            blk_t       *blocknr,
-                                           int blockcnt,
+                                           blkcnt_t    blockcnt,
                                            blk_t       ref_blk,
                                            int         ref_offset,
                                            void        *priv_data),
@@ -320,13 +320,29 @@ errcode_t ext2fs_block_iterate2(ext2_filsys fs,
        struct ext2_inode inode;
        errcode_t       retval;
        struct block_context ctx;
+       int     limit;
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
+       /*
+        * Check to see if we need to limit large files
+        */
+       if (flags & BLOCK_FLAG_NO_LARGE) {
+               ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+               if (ctx.errcode)
+                       goto abort;
+               got_inode = 1;
+               if (!LINUX_S_ISDIR(inode.i_mode) &&
+                   (inode.i_size_high != 0))
+                       return EXT2_ET_FILE_TOO_BIG;
+       }
+
        retval = ext2fs_get_blocks(fs, ino, blocks);
        if (retval)
                return retval;
 
+       limit = fs->blocksize >> 2;
+
        ctx.fs = fs;
        ctx.func = func;
        ctx.priv_data = priv_data;
@@ -378,13 +394,15 @@ errcode_t ext2fs_block_iterate2(ext2_filsys fs,
                                         0, 0, &ctx);
                if (ret & BLOCK_ABORT)
                        goto abort;
-       }
+       } else
+               ctx.bcount += limit;
        if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
                ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
                                          0, 0, &ctx);
                if (ret & BLOCK_ABORT)
                        goto abort;
-       }
+       } else
+               ctx.bcount += limit * limit;
        if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
                ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
                                          0, 0, &ctx);
@@ -412,6 +430,10 @@ abort:
        return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
 }
 
+/*
+ * Emulate the old ext2fs_block_iterate function!
+ */
+
 struct xlate {
        int (*func)(ext2_filsys fs,
                    blk_t       *blocknr,
@@ -423,12 +445,12 @@ struct xlate {
 #ifdef __TURBOC__
 #pragma argsused
 #endif
-static int xlate_func(ext2_filsys fs, blk_t *blocknr, int blockcnt,
+static int xlate_func(ext2_filsys fs, blk_t *blocknr, blkcnt_t blockcnt,
                      blk_t ref_block, int ref_offset, void *priv_data)
 {
        struct xlate *xl = (struct xlate *) priv_data;
 
-       return (*xl->func)(fs, blocknr, blockcnt, xl->real_private);
+       return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private);
 }
 
 errcode_t ext2fs_block_iterate(ext2_filsys fs,
@@ -446,8 +468,54 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
        xl.real_private = priv_data;
        xl.func = func;
 
-       return ext2fs_block_iterate2(fs, ino, flags, block_buf,
-                                   xlate_func, &xl);
+       return ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
+                                    block_buf, xlate_func, &xl);
+}
+
+/*
+ * Emulate the old ext2fs_block_iterate2 function!
+ */
+
+struct xlate2 {
+       int (*func)(ext2_filsys fs,
+                   blk_t       *blocknr,
+                   int         blockcnt,
+                   blk_t       ref_blk,
+                   int         ref_offset,
+                   void        *priv_data);
+       void *real_private;
+};
+
+#ifdef __TURBOC__
+#pragma argsused
+#endif
+static int xlate_func2(ext2_filsys fs, blk_t *blocknr, blkcnt_t blockcnt,
+                     blk_t ref_block, int ref_offset, void *priv_data)
+{
+       struct xlate2 *xl = (struct xlate2 *) priv_data;
+
+       return (*xl->func)(fs, blocknr, (int) blockcnt, ref_block,
+                          ref_offset, xl->real_private);
 }
 
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+                               ino_t   ino,
+                               int     flags,
+                               char *block_buf,
+                               int (*func)(ext2_filsys fs,
+                                           blk_t       *blocknr,
+                                           int blockcnt,
+                                           blk_t       ref_blk,
+                                           int         ref_offset,
+                                           void        *priv_data),
+                               void *priv_data)
+{
+       struct xlate2 xl;
+       
+       xl.real_private = priv_data;
+       xl.func = func;
+
+       return ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
+                                    block_buf, xlate_func2, &xl);
+}
 
index 9d18570..2d254b7 100644 (file)
@@ -120,7 +120,7 @@ extern int ext2fs_process_dir_block(ext2_filsys     fs,
 next:          
                if (((offset + dirent->rec_len) > fs->blocksize) ||
                    (dirent->rec_len < 8) ||
-                   ((dirent->name_len+8) > dirent->rec_len)) {
+                   (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
                        ctx->errcode = EXT2_ET_DIR_CORRUPTED;
                        return BLOCK_ABORT;
                }
index 89cda86..63377ee 100644 (file)
 00000000 T _ext2fs_file_close                  libext2fs       fileio
 00000000 T _ext2fs_file_read                   libext2fs       fileio
 00000000 T _ext2fs_file_write                  libext2fs       fileio
-00000000 T _ext2fs_file_llseek                 libext2fs       fileio
+00000000 T _ext2fs_file_lseek                  libext2fs       fileio
 00000000 T _ext2fs_file_get_size               libext2fs       fileio
 00000000 T _ext2fs_file_set_size               libext2fs       fileio
 00000000 T _ext2fs_get_mem                     libext2fs       inline
 00000000 T _ext2fs_free_mem                    libext2fs       inline
 00000000 T _ext2fs_resize_mem                  libext2fs       inline
+00000000 T _ext2fs_block_iterate3              libext2fs       block
index 6479fee..e47e141 100644 (file)
@@ -254,5 +254,8 @@ ec  EXT2_ET_UNIMPLEMENTED,
 ec     EXT2_ET_CANCEL_REQUESTED,
        "User cancel requested"
 
+ec     EXT2_ET_FILE_TOO_BIG,
+       "Ext2 file too big"
+
        end
 
index 1292804..0180a43 100644 (file)
@@ -50,6 +50,7 @@
 typedef __u32          blk_t;
 typedef unsigned int   dgrp_t;
 typedef __u32          ext2_off_t;
+typedef __s64          blkcnt_t;
 
 #if EXT2_FLAT_INCLUDES
 #include "com_err.h"
@@ -225,12 +226,17 @@ struct struct_ext2_filsys {
  *
  * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
  * called for data blocks only.
+ *
+ * BLOCK_FLAG_NO_LARGE is for internal use only.  It informs
+ * ext2fs_block_iterate3 that large files won't be accepted.
  */
 #define BLOCK_FLAG_APPEND      1
 #define BLOCK_FLAG_HOLE                1
 #define BLOCK_FLAG_DEPTH_TRAVERSE      2
 #define BLOCK_FLAG_DATA_ONLY   4
 
+#define BLOCK_FLAG_NO_LARGE    0x1000
+
 /*
  * Magic "block count" return values for the block iterator function.
  */
@@ -396,21 +402,51 @@ struct ext2fs_sb {
        __u8    s_uuid[16];             /* 128-bit uuid for volume */
        char    s_volume_name[16];      /* volume name */
        char    s_last_mounted[64];     /* directory where last mounted */
-       __u32   s_reserved[206];        /* Padding to the end of the block */
+       __u32   s_algorithm_usage_bitmap; /* For compression */
+       /*
+        * Performance hints.  Directory preallocation should only
+        * happen if the EXT2_COMPAT_PREALLOC flag is on.
+        */
+       __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
+       __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
+       __u16   s_padding1;
+       __u32   s_reserved[204];        /* Padding to the end of the block */
 };
 
 /*
  * Feature set definitions (that might not be in ext2_fs.h
  * (was EXT2_COMPAT_SPARSE_SUPER)
  */
+
+#ifndef EXT2_FEATURE_COMPAT_DIR_PREALLOC
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#endif
+
 #ifndef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #endif
 
-#define EXT2_LIB_FEATURE_COMPAT_SUPP   0
-#define EXT2_LIB_FEATURE_INCOMPAT_SUPP 0
-#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+#ifndef EXT2_FEATURE_RO_COMPAT_LARGE_FILE
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define i_size_high i_dir_acl
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_BTREE_DIR
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#endif
+
+#ifndef EXT2_FEATURE_INCOMPAT_COMPRESSION
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#endif
 
+#ifndef EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE
+#define EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE     0x0002
+#endif
+
+#define EXT2_LIB_FEATURE_COMPAT_SUPP   EXT2_FEATURE_COMPAT_DIR_PREALLOC
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+                                        EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
 /*
  * function prototypes
  */
@@ -509,6 +545,17 @@ errcode_t ext2fs_block_iterate2(ext2_filsys fs,
                                            int         ref_offset,
                                            void        *priv_data),
                                void *priv_data);
+errcode_t ext2fs_block_iterate3(ext2_filsys fs,
+                               ino_t   ino,
+                               int     flags,
+                               char *block_buf,
+                               int (*func)(ext2_filsys fs,
+                                           blk_t       *blocknr,
+                                           blkcnt_t    blockcnt,
+                                           blk_t       ref_blk,
+                                           int         ref_offset,
+                                           void        *priv_data),
+                               void *priv_data);
 
 /* bmap.c */
 extern errcode_t ext2fs_bmap(ext2_filsys fs, ino_t ino,
@@ -605,8 +652,8 @@ 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,
                                   unsigned int nbytes, unsigned int *written);
-extern errcode_t ext2fs_file_llseek(ext2_file_t file, ext2_off_t offset,
-                                   int whence, ext2_off_t *ret_pos);
+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+                                  int whence, ext2_off_t *ret_pos);
 extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
 extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
 
index fbe10fb..51375b7 100644 (file)
@@ -275,8 +275,8 @@ fail:
 }
 
 
-errcode_t ext2fs_file_llseek(ext2_file_t file, ext2_off_t offset,
-                            int whence, ext2_off_t *ret_pos)
+errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+                           int whence, ext2_off_t *ret_pos)
 {
        EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
 
index b8a9f83..ddbc58a 100644 (file)
@@ -53,18 +53,18 @@ static int get_pathname_proc(struct ext2_dir_entry *dirent,
 
        gp = (struct get_pathname_struct *) priv_data;
 
-       if ((dirent->name_len == 2) &&
+       if (((dirent->name_len & 0xFF) == 2) &&
            !strncmp(dirent->name, "..", 2))
                gp->parent = dirent->inode;
        if (dirent->inode == gp->search_ino) {
-               retval = ext2fs_get_mem(dirent->name_len + 1,
+               retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1,
                                        (void **) &gp->name);
                if (!gp->name) {
                        gp->errcode = EXT2_ET_NO_MEMORY;
                        return DIRENT_ABORT;
                }
-               strncpy(gp->name, dirent->name, dirent->name_len);
-               gp->name[dirent->name_len] = '\0';
+               strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF));
+               gp->name[dirent->name_len & 0xFF] = '\0';
                return DIRENT_ABORT;
        }
        return 0;
index b1a1572..2bef3dc 100644 (file)
@@ -39,7 +39,7 @@ static int link_proc(struct ext2_dir_entry *dirent,
 {
        struct link_struct *ls = (struct link_struct *) priv_data;
        struct ext2_dir_entry *next;
-       int rec_len;
+       int rec_len, min_rec_len;
        int ret = 0;
 
        rec_len = EXT2_DIR_REC_LEN(ls->namelen);
@@ -62,11 +62,11 @@ static int link_proc(struct ext2_dir_entry *dirent,
         * truncate it and return.
         */
        if (dirent->inode) {
-               if (dirent->rec_len < (EXT2_DIR_REC_LEN(dirent->name_len) +
-                                      rec_len))
+               min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
+               if (dirent->rec_len < (min_rec_len + rec_len))
                        return ret;
-               rec_len = dirent->rec_len - EXT2_DIR_REC_LEN(dirent->name_len);
-               dirent->rec_len = EXT2_DIR_REC_LEN(dirent->name_len);
+               rec_len = dirent->rec_len - min_rec_len;
+               dirent->rec_len = min_rec_len;
                next = (struct ext2_dir_entry *) (buf + offset +
                                                  dirent->rec_len);
                next->inode = 0;
index 7996c16..282180c 100644 (file)
@@ -41,9 +41,9 @@ static int lookup_proc(struct ext2_dir_entry *dirent,
 {
        struct lookup_struct *ls = (struct lookup_struct *) priv_data;
 
-       if (ls->len != dirent->name_len)
+       if (ls->len != (dirent->name_len & 0xFF))
                return 0;
-       if (strncmp(ls->name, dirent->name, dirent->name_len))
+       if (strncmp(ls->name, dirent->name, (dirent->name_len & 0xFF)))
                return 0;
        *ls->inode = dirent->inode;
        ls->found++;
index fad9d63..ead5ec3 100644 (file)
@@ -42,9 +42,10 @@ static int unlink_proc(struct ext2_dir_entry *dirent,
 {
        struct link_struct *ls = (struct link_struct *) priv_data;
 
-       if (ls->name && (dirent->name_len != ls->namelen))
+       if (ls->name && ((dirent->name_len & 0xFF) != ls->namelen))
                return 0;
-       if (ls->name && strncmp(ls->name, dirent->name, dirent->name_len))
+       if (ls->name && strncmp(ls->name, dirent->name,
+                               dirent->name_len & 0xFF))
                return 0;
        if (ls->inode && (dirent->inode != ls->inode))
                return 0;