summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>1997-04-29 16:17:09 +0000
committerTheodore Ts'o <tytso@mit.edu>1997-04-29 16:17:09 +0000
commit19c78dc07fce2d6f39b5e541562afc3ca1ea38ff (patch)
tree028d1af38c00e2cb267cb966cb68028b0a007b44 /lib
parent21c84b71e205b5ab13f14343da5645dcc985856d (diff)
downloade2fsprogs-19c78dc07fce2d6f39b5e541562afc3ca1ea38ff.tar.gz
Many files:
Checked in e2fsprogs-1.07
Diffstat (limited to 'lib')
-rw-r--r--lib/ext2fs/dll/jump.funcs47
-rw-r--r--lib/ext2fs/dll/jump.vars5
-rw-r--r--lib/ext2fs/expanddir.c8
-rw-r--r--lib/ext2fs/ext2_err.et.in29
-rw-r--r--lib/ext2fs/ext2fs.h273
-rw-r--r--lib/ext2fs/ext2fsP.h74
-rw-r--r--lib/ext2fs/freefs.c18
-rw-r--r--lib/ext2fs/get_pathname.c17
-rw-r--r--lib/ext2fs/getsize.c31
-rw-r--r--lib/ext2fs/icount.c411
-rw-r--r--lib/ext2fs/initialize.c2
-rw-r--r--lib/ext2fs/inline.c8
-rw-r--r--lib/ext2fs/inode.c272
-rw-r--r--lib/ext2fs/io.h22
-rw-r--r--lib/ext2fs/irel.h114
-rw-r--r--lib/ext2fs/irel_ma.c364
-rw-r--r--lib/ext2fs/ismounted.c10
-rw-r--r--lib/ext2fs/link.c55
-rw-r--r--lib/ext2fs/llseek.c12
-rw-r--r--lib/ext2fs/lookup.c69
-rw-r--r--lib/ext2fs/mkdir.c8
-rw-r--r--lib/ext2fs/namei.c165
-rw-r--r--lib/ext2fs/native.c2
-rw-r--r--lib/ext2fs/newdir.c8
-rw-r--r--lib/ext2fs/openfs.c27
-rw-r--r--lib/ext2fs/read_bb.c16
-rw-r--r--lib/ext2fs/read_bb_file.c14
-rw-r--r--lib/ext2fs/rs_bitmap.c92
-rw-r--r--lib/ext2fs/rw_bitmaps.c71
-rw-r--r--lib/ext2fs/swapfs.c20
-rw-r--r--lib/ext2fs/test_io.c227
-rw-r--r--lib/ext2fs/tst_badblocks.c162
-rw-r--r--lib/ext2fs/tst_iscan.c218
-rw-r--r--lib/ext2fs/unix_io.c12
-rw-r--r--lib/ext2fs/unlink.c72
-rw-r--r--lib/ext2fs/valid_blk.c49
-rw-r--r--lib/ss/ChangeLog17
-rw-r--r--lib/ss/Makefile.in3
-rw-r--r--lib/ss/help.c7
-rw-r--r--lib/ss/pager.c3
-rw-r--r--lib/ss/parse.c1
-rw-r--r--lib/ss/ss.h2
-rw-r--r--lib/ss/test_ss.c4
-rw-r--r--lib/uuid/ChangeLog31
-rw-r--r--lib/uuid/Makefile.in12
-rw-r--r--lib/uuid/clear.c9
-rw-r--r--lib/uuid/compare.c7
-rw-r--r--lib/uuid/copy.c7
-rw-r--r--lib/uuid/dll/jump.funcs9
-rw-r--r--lib/uuid/dll/jump.ignore0
-rw-r--r--lib/uuid/dll/jump.import0
-rw-r--r--lib/uuid/dll/jump.params6
-rw-r--r--lib/uuid/dll/jump.undefs1
-rw-r--r--lib/uuid/dll/jump.vars0
-rw-r--r--lib/uuid/gen_uuid.c16
-rw-r--r--lib/uuid/isnull.c7
-rw-r--r--lib/uuid/pack.c8
-rw-r--r--lib/uuid/parse.c9
-rw-r--r--lib/uuid/tst_uuid.c11
-rw-r--r--lib/uuid/unpack.c8
-rw-r--r--lib/uuid/unparse.c9
-rw-r--r--lib/uuid/uuid.h7
-rw-r--r--lib/uuid/uuidP.h7
63 files changed, 2769 insertions, 436 deletions
diff --git a/lib/ext2fs/dll/jump.funcs b/lib/ext2fs/dll/jump.funcs
index 489bd624..825844ca 100644
--- a/lib/ext2fs/dll/jump.funcs
+++ b/lib/ext2fs/dll/jump.funcs
@@ -71,7 +71,7 @@
00000000 T _ext2fs_update_bb_inode libext2fs bb_inode
00000000 T _ext2fs_read_bb_FILE libext2fs read_bb_file
00000000 T _initialize_ext2_error_table libext2fs ext2_err
-00000000 T _ext2_llseek libext2fs llseek
+00000000 T _ext2fs_llseek libext2fs llseek
00000000 T _ext2fs_set_inode_callback libext2fs inode
00000000 T _ext2fs_compare_block_bitmap libext2fs cmp_bitmaps
00000000 T _ext2fs_compare_inode_bitmap libext2fs cmp_bitmaps
@@ -93,3 +93,48 @@
00000000 T _ext2fs_swap_group_desc libext2fs swapfs
00000000 T _ext2fs_get_device_size libext2fs getsize
00000000 T _ext2fs_check_if_mounted libext2fs ismounted
+00000000 T _ext2fs_allocate_tables libext2fs alloc_tables
+00000000 T _ext2fs_allocate_generic_bitmap libext2fs bitmaps
+00000000 T _ext2fs_warn_bitmap2 libext2fs bitops
+00000000 T _ext2fs_free_generic_bitmap libext2fs freefs
+00000000 T _ext2fs_mark_generic_bitmap libext2fs inline
+00000000 T _ext2fs_unmark_generic_bitmap libext2fs inline
+00000000 T _ext2fs_test_generic_bitmap libext2fs inline
+00000000 T _ext2fs_namei_follow libext2fs namei
+00000000 T _ext2fs_follow_link libext2fs namei
+00000000 T _ext2fs_native_flag libext2fs native
+00000000 T _ext2fs_swap_inode libext2fs swapfs
+00000000 T _ext2fs_block_iterate2 libext2fs block
+00000000 T _ext2fs_inode_scan_goto_blockgroup libext2fs inode
+00000000 T _ext2fs_badblocks_list_create libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_add libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_test libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate_begin libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate_end libext2fs badblocks
+00000000 T _ext2fs_brel_memarray_create libext2fs brel_ma
+00000000 T _ext2fs_badblocks_list_free libext2fs closefs
+00000000 T _ext2fs_free_dblist libext2fs closefs
+00000000 T _ext2fs_get_num_dirs libext2fs dblist
+00000000 T _ext2fs_init_dblist libext2fs dblist
+00000000 T _ext2fs_add_dir_block libext2fs dblist
+00000000 T _ext2fs_dblist_iterate libext2fs dblist
+00000000 T _ext2fs_dblist_dir_iterate libext2fs dblist_dir
+00000000 T _ext2fs_process_dir_block libext2fs dir_iterate
+00000000 T _ext2fs_test_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_test_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_mark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_mark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_unmark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_unmark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_inode_scan_flags libext2fs inode
+00000000 T _ext2fs_irel_memarray_create libext2fs irel_ma
+00000000 T _ext2fs_resize_generic_bitmap libext2fs rs_bitmap
+00000000 T _ext2fs_inode_has_valid_blocks libext2fs valid_blk
+00000000 T _ext2fs_free_icount libext2fs icount
+00000000 T _ext2fs_create_icount libext2fs icount
+00000000 T _ext2fs_icount_fetch libext2fs icount
+00000000 T _ext2fs_icount_increment libext2fs icount
+00000000 T _ext2fs_icount_decrement libext2fs icount
+00000000 T _ext2fs_icount_store libext2fs icount
+00000000 T _ext2fs_get_icount_size libext2fs icount
diff --git a/lib/ext2fs/dll/jump.vars b/lib/ext2fs/dll/jump.vars
index edbbf7c7..5f219d39 100644
--- a/lib/ext2fs/dll/jump.vars
+++ b/lib/ext2fs/dll/jump.vars
@@ -1 +1,6 @@
00000004 D _unix_io_manager libext2fs unix_io
+00000004 D _test_io_manager libext2fs test_io
+00000004 D _test_io_backing_manager libext2fs test_io
+00000004 D _test_io_cb_read_blk libext2fs test_io
+00000004 D _test_io_cb_write_blk libext2fs test_io
+00000004 D _test_io_cb_set_blksize libext2fs test_io
diff --git a/lib/ext2fs/expanddir.c b/lib/ext2fs/expanddir.c
index b2597c9f..852b40f5 100644
--- a/lib/ext2fs/expanddir.c
+++ b/lib/ext2fs/expanddir.c
@@ -1,8 +1,12 @@
/*
* expand.c --- expand an ext2fs directory
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 81e0c1ee..075acee3 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -1,6 +1,10 @@
#
-# Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. This file may be
-# redistributed under the terms of the GNU Public License.
+# Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+#
+# %Begin-Header%
+# This file may be redistributed under the terms of the GNU Public
+# License.
+# %End-Header%
#
error_table ext2
@@ -37,14 +41,14 @@ ec EXT2_ET_MAGIC_INODE_BITMAP,
ec EXT2_ET_MAGIC_GENERIC_BITMAP,
"Wrong magic number for generic_bitmap structure"
-ec EXT2_ET_MAGIC_RESERVED_2,
- "Wrong magic number --- RESERVED_2"
+ec EXT2_ET_MAGIC_TEST_IO_CHANNEL,
+ "Wrong magic number for test io_channel structure"
-ec EXT2_ET_MAGIC_RESERVED_3,
- "Wrong magic number --- RESERVED_3"
+ec EXT2_ET_MAGIC_DBLIST,
+ "Wrong magic number for directory block list structure"
-ec EXT2_ET_MAGIC_RESERVED_4,
- "Wrong magic number --- RESERVED_4"
+ec EXT2_ET_MAGIC_ICOUNT,
+ "Wrong magic number for icount structure"
ec EXT2_ET_MAGIC_RESERVED_5,
"Wrong magic number --- RESERVED_5"
@@ -211,4 +215,13 @@ ec EXT2_ET_SYMLINK_LOOP,
ec EXT2_ET_CALLBACK_NOTHANDLED,
"The callback function will not handle this case"
+ec EXT2_ET_BAD_BLOCK_IN_INODE_TABLE,
+ "The inode is from a bad block in the inode table"
+
+ec EXT2_ET_UNSUPP_FEATURE,
+ "Filesystem has unsupported feature(s)"
+
+ec EXT2_ET_RO_UNSUPP_FEATURE,
+ "Filesystem has unsupported read-only feature(s)"
+
end
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index de746816..ce57e13b 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1,11 +1,22 @@
/*
* ext2fs.h --- ext2fs
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
/*
+ * Non-GNU C compilers won't necessarily understand inline
+ */
+#ifndef __GNUC__
+#define NO_INLINE_FUNCS
+#endif
+
+/*
* Where the master copy of the superblock is located, and how big
* superblocks are supposed to be. We define SUPERBLOCK_SIZE because
* the size of the superblock structure is not necessarily trustworthy
@@ -49,9 +60,7 @@ struct ext2fs_struct_generic_bitmap {
#define EXT2FS_TEST_ERROR 2
typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-
typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
-
typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
#ifdef EXT2_DYNAMIC_REV
@@ -62,19 +71,46 @@ typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
#endif
/*
+ * badblocks list definitions
+ */
+
+typedef struct ext2_struct_badblocks_list *ext2_badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *ext2_badblocks_iterate;
+
+/* old */
+typedef struct ext2_struct_badblocks_list *badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *badblocks_iterate;
+
+#define BADBLOCKS_FLAG_DIRTY 1
+
+/*
+ * ext2_dblist structure and abstractions (see dblist.c)
+ */
+struct ext2_db_entry {
+ ino_t ino;
+ blk_t blk;
+ int blockcnt;
+};
+
+typedef struct ext2_struct_dblist *ext2_dblist;
+
+#define DBLIST_ABORT 1
+
+/*
* Flags for the ext2_filsys structure
*/
-#define EXT2_FLAG_RW 0x01
-#define EXT2_FLAG_CHANGED 0x02
-#define EXT2_FLAG_DIRTY 0x04
-#define EXT2_FLAG_VALID 0x08
-#define EXT2_FLAG_IB_DIRTY 0x10
-#define EXT2_FLAG_BB_DIRTY 0x20
+#define EXT2_FLAG_RW 0x01
+#define EXT2_FLAG_CHANGED 0x02
+#define EXT2_FLAG_DIRTY 0x04
+#define EXT2_FLAG_VALID 0x08
+#define EXT2_FLAG_IB_DIRTY 0x10
+#define EXT2_FLAG_BB_DIRTY 0x20
#define EXT2_FLAG_SWAP_BYTES 0x40
#define EXT2_FLAG_SWAP_BYTES_READ 0x80
#define EXT2_FLAG_SWAP_BYTES_WRITE 0x100
#define EXT2_FLAG_MASTER_SB_ONLY 0x200
+#define EXT2_FLAG_FORCE 0x400
/*
* Special flag in the ext2 inode i_flag field that means that this is
@@ -103,7 +139,12 @@ struct struct_ext2_filsys {
struct ext2_inode *inode);
errcode_t (*write_inode)(ext2_filsys fs, ino_t ino,
struct ext2_inode *inode);
- __u32 reserved[14];
+ badblocks_list badblocks;
+ ext2_dblist dblist;
+ /*
+ * Reserved for future expansion
+ */
+ __u32 reserved[12];
/*
* Not used by ext2fs library; reserved for the use of the
@@ -112,32 +153,6 @@ struct struct_ext2_filsys {
void * private;
};
-/*
- * badblocks list definitions
- */
-
-typedef struct struct_badblocks_list *badblocks_list;
-
-struct struct_badblocks_list {
- int magic;
- int num;
- int size;
- blk_t *list;
- int badblocks_flags;
- int reserved[8];
-};
-
-#define BADBLOCKS_FLAG_DIRTY 1
-
-typedef struct struct_badblocks_iterate *badblocks_iterate;
-
-struct struct_badblocks_iterate {
- int magic;
- badblocks_list bb;
- int ptr;
- int reserved[8];
-};
-
#include "ext2fs/bitops.h"
/*
@@ -191,38 +206,30 @@ struct struct_badblocks_iterate {
#define DIRENT_FLAG_INCLUDE_EMPTY 1
+
+#define DIRENT_DOT_FILE 1
+#define DIRENT_DOT_DOT_FILE 2
+#define DIRENT_OTHER_FILE 3
+
/*
* Inode scan definitions
*/
typedef struct ext2_struct_inode_scan *ext2_inode_scan;
-struct ext2_struct_inode_scan {
- int magic;
- ext2_filsys fs;
- ino_t current_inode;
- blk_t current_block;
- dgrp_t current_group;
- int inodes_left, blocks_left, groups_left;
- int inode_buffer_blocks;
- char * inode_buffer;
- int inode_size;
- char * ptr;
- int bytes_left;
- char *temp_buffer;
- errcode_t (*done_group)(ext2_filsys fs,
- ext2_inode_scan scan,
- dgrp_t group,
- void * private);
- void * done_group_data;
- int reserved[8];
-};
+/*
+ * ext2fs_scan flags
+ */
+#define EXT2_SF_CHK_BADBLOCKS 0x0001
+#define EXT2_SF_BAD_INODE_BLK 0x0002
+#define EXT2_SF_BAD_EXTRA_BYTES 0x0004
+#define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
/*
* ext2fs_check_if_mounted flags
*/
#define EXT2_MF_MOUNTED 1
#define EXT2_MF_ISROOT 2
-#define EXT2_MF_READONLY 4
+#define EXT2_MF_READONLY 4
/*
* Ext2/linux mode flags. We define them here so that we don't need
@@ -265,6 +272,13 @@ struct ext2_struct_inode_scan {
#define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
/*
+ * ext2_icount_t abstraction
+ */
+#define EXT2_ICOUNT_OPT_INCREMENT 0x01
+
+typedef struct ext2_icount *ext2_icount_t;
+
+/*
* For checking structure magic numbers...
*/
@@ -342,7 +356,25 @@ extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
ext2fs_block_bitmap map,
blk_t *ret);
+/* allocate_tables.c */
+errcode_t ext2fs_allocate_tables(ext2_filsys fs);
+
/* badblocks.c */
+extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
+ int size);
+extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
+extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
+ blk_t blk);
+extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
+ blk_t blk);
+extern errcode_t
+ ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
+ ext2_badblocks_iterate *ret);
+extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
+ blk_t *blk);
+extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
+
+/* bb_compat */
extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
extern void badblocks_list_free(badblocks_list bb);
extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
@@ -354,7 +386,7 @@ extern void badblocks_list_iterate_end(badblocks_iterate iter);
/* bb_inode.c */
extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
- badblocks_list bb_list);
+ ext2_badblocks_list bb_list);
/* bitmaps.c */
extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
@@ -392,6 +424,18 @@ extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
void *private),
void *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 *private),
+ void *private);
+
/* check_desc.c */
extern errcode_t ext2fs_check_desc(ext2_filsys fs);
@@ -405,6 +449,32 @@ extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
ext2fs_inode_bitmap bm2);
+/* dblist.c */
+
+errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ino_t *ret_num_dirs);
+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
+void ext2fs_free_dblist(ext2_dblist dblist);
+errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ino_t ino, blk_t blk,
+ int blockcnt);
+errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+ int (*func)(ext2_filsys fs,
+ struct ext2_db_entry *db_info,
+ void *private),
+ void *private);
+
+/* dblist_dir.c */
+extern errcode_t
+ ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+ int flags,
+ char *block_buf,
+ int (*func)(ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private),
+ void *private);
/* dirblock.c */
extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
@@ -412,6 +482,24 @@ extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
void *buf);
+/* dir_iterate.c */
+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
+ ino_t dir,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private),
+ void *private);
+ /* private to library */
+extern int ext2fs_process_dir_block(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *private);
+
+
/* expanddir.c */
extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
@@ -436,39 +524,42 @@ extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
struct ext2_inode *inode);
-void ext2fs_set_inode_callback(ext2_inode_scan scan,
- errcode_t (*done_group)(ext2_filsys fs,
- ext2_inode_scan scan,
- dgrp_t group,
- void * private),
- void *done_group_data);
-void ext2fs_set_inode_callback(ext2_inode_scan scan,
- errcode_t (*done_group)(ext2_filsys fs,
- ext2_inode_scan scan,
- dgrp_t group,
- void * private),
- void *done_group_data);
-extern errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
+extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
+ int group);
+extern void ext2fs_set_inode_callback
+ (ext2_inode_scan scan,
+ errcode_t (*done_group)(ext2_filsys fs,
+ ext2_inode_scan scan,
+ dgrp_t group,
+ void * private),
+ void *done_group_data);
+extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
+ int clear_flags);
+extern errcode_t ext2fs_read_inode (ext2_filsys fs, ino_t ino,
struct ext2_inode * inode);
-extern errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
+extern errcode_t ext2fs_write_inode(ext2_filsys fs, ino_t ino,
struct ext2_inode * inode);
extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
extern errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino);
+/* icount.c */
+extern void ext2fs_free_icount(ext2_icount_t icount);
+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, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ino_t ino,
+ __u16 count);
+extern ino_t ext2fs_get_icount_size(ext2_icount_t icount);
+
/* ismounted.c */
extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
/* namei.c */
-extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
- ino_t dir,
- int flags,
- char *block_buf,
- int (*func)(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *private),
- void *private);
extern errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
int namelen, char *buf, ino_t *inode);
extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
@@ -505,20 +596,32 @@ errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name,
ino_t ino, int flags);
/* read_bb.c */
-extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs, badblocks_list *bb_list);
+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
+ ext2_badblocks_list *bb_list);
/* read_bb_file.c */
extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
- badblocks_list *bb_list,
+ ext2_badblocks_list *bb_list,
void (*invalid)(ext2_filsys fs,
blk_t blk));
+/* rs_bitmap.c */
+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
+ __u32 new_real_end,
+ ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_inode_bitmap bmap);
+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_block_bitmap bmap);
+
/* swapfs.c */
extern void ext2fs_swap_super(struct ext2_super_block * super);
extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
struct ext2_inode *f, int hostorder);
+/* valid_blk.c */
+int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
/* inline functions */
extern void ext2fs_mark_super_dirty(ext2_filsys fs);
diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h
new file mode 100644
index 00000000..5cf83b5e
--- /dev/null
+++ b/lib/ext2fs/ext2fsP.h
@@ -0,0 +1,74 @@
+/*
+ * ext2fsP.h --- private header file for ext2 library
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "ext2fs.h"
+
+/*
+ * Badblocks list
+ */
+struct ext2_struct_badblocks_list {
+ int magic;
+ int num;
+ int size;
+ blk_t *list;
+ int badblocks_flags;
+};
+
+struct ext2_struct_badblocks_iterate {
+ int magic;
+ badblocks_list bb;
+ int ptr;
+};
+
+
+/*
+ * Directory block iterator definition
+ */
+struct ext2_struct_dblist {
+ int magic;
+ ext2_filsys fs;
+ ino_t size;
+ ino_t count;
+ int sorted;
+ struct ext2_db_entry * list;
+};
+
+/*
+ * For directory iterators
+ */
+struct dir_context {
+ ino_t dir;
+ int flags;
+ char *buf;
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private);
+ int (*func2)(ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private);
+ void *private;
+ errcode_t errcode;
+};
+
+
+/* Function prototypes */
+
+extern int ext2_process_dir_block(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *private);
+
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 5c709833..215d1fbc 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -1,8 +1,12 @@
/*
* freefs.c --- free an ext2 filesystem
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -30,6 +34,16 @@ void ext2fs_free(ext2_filsys fs)
ext2fs_free_block_bitmap(fs->block_map);
if (fs->inode_map)
ext2fs_free_inode_bitmap(fs->inode_map);
+
+ if (fs->badblocks)
+ badblocks_list_free(fs->badblocks);
+ fs->badblocks = 0;
+
+ if (fs->dblist)
+ ext2fs_free_dblist(fs->dblist);
+
+ fs->magic = 0;
+
free(fs);
}
diff --git a/lib/ext2fs/get_pathname.c b/lib/ext2fs/get_pathname.c
index da6b249a..8c94e932 100644
--- a/lib/ext2fs/get_pathname.c
+++ b/lib/ext2fs/get_pathname.c
@@ -1,8 +1,21 @@
/*
* get_pathname.c --- do directry/inode -> name translation
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * ext2fs_get_pathname(fs, dir, ino, name)
+ *
+ * This function translates takes two inode numbers into a
+ * string, placing the result in <name>. <dir> is the containing
+ * directory inode, and <ino> is the inode number itself. If
+ * <ino> is zero, then ext2fs_get_pathname will return pathname
+ * of the the directory <dir>.
+ *
*/
#include <stdio.h>
diff --git a/lib/ext2fs/getsize.c b/lib/ext2fs/getsize.c
index 86b12d1e..c9fc00ae 100644
--- a/lib/ext2fs/getsize.c
+++ b/lib/ext2fs/getsize.c
@@ -1,8 +1,12 @@
/*
* getsize.c --- get the size of a partition.
*
- * Copyright (C) 1995 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
+ * Copyright (C) 1995, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -35,7 +39,7 @@ static int valid_offset (int fd, ext2_loff_t offset)
{
char ch;
- if (ext2_llseek (fd, offset, 0) < 0)
+ if (ext2fs_llseek (fd, offset, 0) < 0)
return 0;
if (read (fd, &ch, 1) < 1)
return 0;
@@ -49,12 +53,13 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
blk_t *retblocks)
{
int fd;
- int size;
+ long size;
ext2_loff_t high, low;
#ifdef FDGETPRM
struct floppy_struct this_floppy;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
+ int part;
struct disklabel lab;
struct partition *pp;
char ch;
@@ -79,18 +84,18 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
}
#endif
#ifdef HAVE_SYS_DISKLABEL_H
- size = strlen(file) - 1;
- if (size >= 0) {
- ch = file[size];
+ part = strlen(file) - 1;
+ if (part >= 0) {
+ ch = file[part];
if (isdigit(ch))
- size = 0;
+ part = 0;
else if (ch >= 'a' && ch <= 'h')
- size = ch - 'a';
+ part = ch - 'a';
else
- size = -1;
+ part = -1;
}
- if (size >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
- pp = &lab.d_partitions[size];
+ if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
+ pp = &lab.d_partitions[part];
if (pp->p_size) {
close(fd);
*retblocks = pp->p_size / (blocksize / 512);
@@ -101,7 +106,7 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
/*
* OK, we couldn't figure it out by using a specialized ioctl,
- * which is generally the besy way. So do binary search to
+ * which is generally the best way. So do binary search to
* find the size of the partition.
*/
low = 0;
diff --git a/lib/ext2fs/icount.c b/lib/ext2fs/icount.c
new file mode 100644
index 00000000..b9070a93
--- /dev/null
+++ b/lib/ext2fs/icount.c
@@ -0,0 +1,411 @@
+/*
+ * icount.c --- an efficient inode count abstraction
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <et/com_err.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+#include "ext2fs.h"
+
+/*
+ * The data storage strategy used by icount relies on the observation
+ * that most inode counts are either zero (for non-allocated inodes),
+ * one (for most files), and only a few that are two or more
+ * (directories and files that are linked to more than one directory).
+ *
+ * Also, e2fsck tends to load the icount data sequentially.
+ *
+ * So, we use an inode bitmap to indicate which inodes have a count of
+ * one, and then use a sorted list to store the counts for inodes
+ * which are greater than one.
+ *
+ * We also use an optional bitmap to indicate which inodes are already
+ * in the sorted list, to speed up the use of this abstraction by
+ * e2fsck's pass 2. Pass 2 increments inode counts as it finds them,
+ * so this extra bitmap avoids searching the sorted list to see if a
+ * particular inode is on the sorted list already.
+ */
+
+struct ext2_icount_el {
+ ino_t ino;
+ __u16 count;
+};
+
+struct ext2_icount {
+ int magic;
+ ext2fs_inode_bitmap single;
+ ext2fs_inode_bitmap multiple;
+ ino_t count;
+ ino_t size;
+ ino_t num_inodes;
+ int cursor;
+ struct ext2_icount_el *list;
+};
+
+void ext2fs_free_icount(ext2_icount_t icount)
+{
+ if (!icount)
+ return;
+
+ icount->magic = 0;
+ if (icount->list)
+ free(icount->list);
+ if (icount->single)
+ ext2fs_free_inode_bitmap(icount->single);
+ if (icount->multiple)
+ ext2fs_free_inode_bitmap(icount->multiple);
+ free(icount);
+}
+
+errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
+ ext2_icount_t *ret)
+{
+ ext2_icount_t icount;
+ errcode_t retval;
+ size_t bytes;
+
+ icount = malloc(sizeof(struct ext2_icount));
+ if (!icount)
+ return ENOMEM;
+ memset(icount, 0, sizeof(struct ext2_icount));
+
+ retval = ext2fs_allocate_inode_bitmap(fs, 0,
+ &icount->single);
+ if (retval)
+ goto errout;
+
+ if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
+ retval = ext2fs_allocate_inode_bitmap(fs, 0,
+ &icount->multiple);
+ if (retval)
+ goto errout;
+ } else
+ icount->multiple = 0;
+
+ if (size) {
+ icount->size = size;
+ } else {
+ /*
+ * Figure out how many special case inode counts we will
+ * have. We know we will need one for each directory;
+ * we also need to reserve some extra room for file links
+ */
+ retval = ext2fs_get_num_dirs(fs, &icount->size);
+ if (retval)
+ goto errout;
+ icount->size += fs->super->s_inodes_count / 50;
+ }
+
+ bytes = icount->size * sizeof(struct ext2_icount_el);
+#if 0
+ printf("Icount allocated %d entries, %d bytes.\n",
+ icount->size, bytes);
+#endif
+ icount->list = malloc(bytes);
+ if (!icount->list)
+ goto errout;
+ memset(icount->list, 0, bytes);
+
+ icount->magic = EXT2_ET_MAGIC_ICOUNT;
+ icount->count = 0;
+ icount->cursor = 0;
+ icount->num_inodes = fs->super->s_inodes_count;
+
+ *ret = icount;
+
+ return 0;
+
+errout:
+ ext2fs_free_icount(icount);
+ return(retval);
+}
+
+/*
+ * get_icount_el() --- given an inode number, try to find icount
+ * information in the sorted list. We use a binary search...
+ */
+static struct ext2_icount_el *get_icount_el(ext2_icount_t icount, ino_t ino)
+{
+ int low, high, mid;
+
+ if (!icount || !icount->list || !icount->count)
+ return 0;
+
+ if (icount->multiple &&
+ !ext2fs_test_inode_bitmap(icount->multiple, ino))
+ return 0;
+
+ low = 0;
+ high = icount->count-1;
+ if (ino == icount->list[low].ino) {
+ icount->cursor = low+1;
+ return &icount->list[low];
+ }
+ if (ino == icount->list[high].ino) {
+ icount->cursor = 0;
+ return &icount->list[high];
+ }
+ if (icount->cursor >= icount->count)
+ icount->cursor = 0;
+ if (ino == icount->list[icount->cursor].ino)
+ return &icount->list[icount->cursor++];
+#if 0
+ printf("Non-cursor get_icount_el: %u\n", ino);
+#endif
+
+ while (low < high) {
+ mid = (low+high)/2;
+ if (mid == low || mid == high)
+ break;
+ if (ino == icount->list[mid].ino) {
+ icount->cursor = mid;
+ return &icount->list[mid];
+ }
+ if (ino < icount->list[mid].ino)
+ high = mid;
+ else
+ low = mid;
+ }
+ return 0;
+}
+
+/*
+ * put_icount_el() --- given an inode number, create a new entry in
+ * the sorted list. This function is optimized for adding values
+ * in ascending order.
+ */
+static struct ext2_icount_el *put_icount_el(ext2_icount_t icount, ino_t ino)
+{
+ struct ext2_icount_el *el, *new_list;
+ ino_t new_size = 0;
+ int i, j;
+
+ if (icount->count >= icount->size) {
+ if (icount->count) {
+ new_size = icount->list[icount->count-1].ino;
+ new_size = icount->count *
+ ((float) new_size / icount->num_inodes);
+ }
+ if (new_size < (icount->size + 100))
+ new_size = icount->size + 100;
+#if 0
+ printf("Reallocating icount %d entries...\n", new_size);
+#endif
+ new_list = realloc(icount->list,
+ new_size * sizeof(struct ext2_icount_el));
+ if (!new_list)
+ return 0;
+ icount->size = new_size;
+ icount->list = new_list;
+ }
+
+ /*
+ * Normally, get_icount_el is called with each inode in
+ * sequential order; but once in a while (like when pass 3
+ * needs to recreate the root directory or lost+found
+ * directory) it is called out of order.
+ */
+ if (icount->count && icount->list[icount->count-1].ino >= ino) {
+ for (i = icount->count-1; i > 0; i--)
+ if (icount->list[i-1].ino < ino)
+ break;
+ el = &icount->list[i];
+ if (el->ino != ino) {
+ for (j = icount->count++; j > i; j--)
+ icount->list[j] = icount->list[j-1];
+ el->count = 0;
+ }
+ } else {
+ el = &icount->list[icount->count++];
+ el->count = 0;
+ }
+ el->ino = ino;
+ return el;
+}
+
+
+errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ino_t ino, __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ *ret = 1;
+ return 0;
+ }
+ el = get_icount_el(icount, ino);
+ if (!el) {
+ *ret = 0;
+ return 0;
+ }
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ino_t ino,
+ __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ /*
+ * If the existing count is 1, then we know there is
+ * no entry in the list, so use put_icount_el().
+ */
+ el = put_icount_el(icount, ino);
+ if (!el)
+ return ENOMEM;
+ } else if (icount->multiple) {
+ /*
+ * The count is either zero or greater than 1; if the
+ * inode is set in icount->multiple, then there should
+ * be an entry in the list, so find it using
+ * get_icount_el().
+ */
+ if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
+ el = get_icount_el(icount, ino);
+ if (!el) {
+ /* should never happen */
+ el = put_icount_el(icount, ino);
+ if (!el)
+ return ENOMEM;
+ }
+ } else {
+ /*
+ * The count was zero; mark the single bitmap
+ * and return.
+ */
+ zero_count:
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if (ret)
+ *ret = 1;
+ return 0;
+ }
+ } else {
+ /*
+ * The count is either zero or greater than 1; try to
+ * find an entry in the list to determine which.
+ */
+ el = get_icount_el(icount, ino);
+ if (!el) {
+ /* No entry means the count was zero */
+ goto zero_count;
+ }
+ el = put_icount_el(icount, ino);
+ if (!el)
+ return ENOMEM;
+ }
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ el->count = 2;
+ } else
+ el->count++;
+ if (icount->multiple)
+ ext2fs_mark_inode_bitmap(icount->multiple, ino);
+ if (ret)
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ino_t ino,
+ __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ else {
+ el = get_icount_el(icount, ino);
+ if (el)
+ el->count = 0;
+ }
+ if (ret)
+ *ret = 0;
+ return 0;
+ }
+
+ el = get_icount_el(icount, ino);
+ if (!el)
+ return EINVAL;
+
+ el->count--;
+ if (el->count == 1)
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if ((el->count == 0) && icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+
+ if (ret)
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_store(ext2_icount_t icount, ino_t ino,
+ __u16 count)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (count == 1) {
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ return 0;
+ }
+ if (count == 0) {
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple) {
+ /*
+ * If the icount->multiple bitmap is enabled,
+ * we can just clear both bitmaps and we're done
+ */
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ } else {
+ el = get_icount_el(icount, ino);
+ if (el)
+ el->count = 0;
+ }
+ return 0;
+ }
+
+ /*
+ * Get the icount element
+ */
+ el = put_icount_el(icount, ino);
+ if (!el)
+ return ENOMEM;
+ el->count = count;
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_mark_inode_bitmap(icount->multiple, ino);
+ return 0;
+}
+
+ino_t ext2fs_get_icount_size(ext2_icount_t icount)
+{
+ if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
+ return 0;
+
+ return icount->size;
+}
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 43492441..6db5a0cd 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -4,8 +4,10 @@
*
* Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
*
+ * %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/inline.c b/lib/ext2fs/inline.c
index 599fceb1..3451c353 100644
--- a/lib/ext2fs/inline.c
+++ b/lib/ext2fs/inline.c
@@ -3,8 +3,12 @@
* files as standalone functions, in case the application program
* is compiled with inlining turned off.
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 8743476a..8fd5e7e4 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -1,8 +1,12 @@
/*
* inode.c --- utility routines to read and write inodes
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -17,15 +21,51 @@
#include <linux/ext2_fs.h>
-#include "ext2fs.h"
+#include "ext2fsP.h"
+
+struct ext2_struct_inode_scan {
+ int magic;
+ ext2_filsys fs;
+ ino_t current_inode;
+ blk_t current_block;
+ dgrp_t current_group;
+ int inodes_left, blocks_left, groups_left;
+ int inode_buffer_blocks;
+ char * inode_buffer;
+ int inode_size;
+ char * ptr;
+ int bytes_left;
+ char *temp_buffer;
+ errcode_t (*done_group)(ext2_filsys fs,
+ ext2_inode_scan scan,
+ dgrp_t group,
+ void * private);
+ void * done_group_data;
+ int bad_block_ptr;
+ int scan_flags;
+ int reserved[6];
+};
errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
ext2_inode_scan *ret_scan)
{
ext2_inode_scan scan;
+ errcode_t retval;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ /*
+ * If fs->badblocks isn't set, then set it --- since the inode
+ * scanning functions require it.
+ */
+ if (fs->badblocks == 0) {
+ retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
+ if (retval && fs->badblocks) {
+ badblocks_list_free(fs->badblocks);
+ fs->badblocks = 0;
+ }
+ }
+
scan = (ext2_inode_scan) malloc(sizeof(struct ext2_struct_inode_scan));
if (!scan)
return ENOMEM;
@@ -41,6 +81,7 @@ errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
scan->inode_buffer = malloc(scan->inode_buffer_blocks * fs->blocksize);
scan->done_group = 0;
scan->done_group_data = 0;
+ scan->bad_block_ptr = 0;
if (!scan->inode_buffer) {
free(scan);
return ENOMEM;
@@ -51,6 +92,8 @@ errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
free(scan);
return ENOMEM;
}
+ if (scan->fs->badblocks && scan->fs->badblocks->num)
+ scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
*ret_scan = scan;
return 0;
}
@@ -82,11 +125,168 @@ void ext2fs_set_inode_callback(ext2_inode_scan scan,
scan->done_group_data = done_group_data;
}
+int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
+ int clear_flags)
+{
+ int old_flags;
+
+ if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
+ return 0;
+
+ old_flags = scan->scan_flags;
+ scan->scan_flags &= ~clear_flags;
+ scan->scan_flags |= set_flags;
+ return old_flags;
+}
+
+/*
+ * This function is called by ext2fs_get_next_inode when it needs to
+ * get ready to read in a new blockgroup.
+ */
+static errcode_t get_next_blockgroup(ext2_inode_scan scan)
+{
+ scan->current_group++;
+ scan->groups_left--;
+
+ scan->current_block = scan->fs->
+ group_desc[scan->current_group].bg_inode_table;
+
+ scan->bytes_left = 0;
+ scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
+ scan->blocks_left = scan->fs->inode_blocks_per_group;
+ return 0;
+}
+
+errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
+ int group)
+{
+ scan->current_group = group - 1;
+ scan->groups_left = scan->fs->group_desc_count - group;
+ return get_next_blockgroup(scan);
+}
+
+/*
+ * This function is called by get_next_blocks() to check for bad
+ * blocks in the inode table.
+ *
+ * This function assumes that badblocks_list->list is sorted in
+ * increasing order.
+ */
+static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
+ int *num_blocks)
+{
+ blk_t blk = scan->current_block;
+ badblocks_list bb = scan->fs->badblocks;
+
+ /*
+ * If the inode table is missing, then obviously there are no
+ * bad blocks. :-)
+ */
+ if (blk == 0)
+ return 0;
+
+ /*
+ * If the current block is greater than the bad block listed
+ * in the bad block list, then advance the pointer until this
+ * is no longer the case. If we run out of bad blocks, then
+ * we don't need to do any more checking!
+ */
+ while (blk > bb->list[scan->bad_block_ptr]) {
+ if (++scan->bad_block_ptr >= bb->num) {
+ scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
+ return 0;
+ }
+ }
+
+ /*
+ * If the current block is equal to the bad block listed in
+ * the bad block list, then handle that one block specially.
+ * (We could try to handle runs of bad blocks, but that
+ * only increases CPU efficiency by a small amount, at the
+ * expense of a huge expense of code complexity, and for an
+ * uncommon case at that.)
+ */
+ if (blk == bb->list[scan->bad_block_ptr]) {
+ scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
+ *num_blocks = 1;
+ if (++scan->bad_block_ptr >= bb->num)
+ scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
+ return 0;
+ }
+
+ /*
+ * If there is a bad block in the range that we're about to
+ * read in, adjust the number of blocks to read so that we we
+ * don't read in the bad block. (Then the next block to read
+ * will be the bad block, which is handled in the above case.)
+ */
+ if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
+ *num_blocks = bb->list[scan->bad_block_ptr] - blk;
+
+ return 0;
+}
+
+/*
+ * This function is called by ext2fs_get_next_inode when it needs to
+ * read in more blocks from the current blockgroup's inode table.
+ */
+static errcode_t get_next_blocks(ext2_inode_scan scan)
+{
+ int num_blocks;
+ errcode_t retval;
+
+ /*
+ * Figure out how many blocks to read; we read at most
+ * inode_buffer_blocks, and perhaps less if there aren't that
+ * many blocks left to read.
+ */
+ num_blocks = scan->inode_buffer_blocks;
+ if (num_blocks > scan->blocks_left)
+ num_blocks = scan->blocks_left;
+
+ /*
+ * If the past block "read" was a bad block, then mark the
+ * left-over extra bytes as also being bad.
+ */
+ if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
+ if (scan->bytes_left)
+ scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
+ scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
+ }
+
+ /*
+ * Do inode bad block processing, if necessary.
+ */
+ if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
+ retval = check_for_inode_bad_blocks(scan, &num_blocks);
+ if (retval)
+ return retval;
+ }
+
+ if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
+ (scan->current_block == 0)) {
+ memset(scan->inode_buffer, 0,
+ num_blocks * scan->fs->blocksize);
+ } else {
+ retval = io_channel_read_blk(scan->fs->io,
+ scan->current_block,
+ num_blocks, scan->inode_buffer);
+ if (retval)
+ return EXT2_ET_NEXT_INODE_READ;
+ }
+ scan->ptr = scan->inode_buffer;
+ scan->bytes_left = num_blocks * scan->fs->blocksize;
+
+ scan->blocks_left -= num_blocks;
+ if (scan->current_block)
+ scan->current_block += num_blocks;
+ return 0;
+}
+
errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
struct ext2_inode *inode)
{
errcode_t retval;
- int num_blocks;
int extra_bytes = 0;
EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
@@ -95,10 +295,10 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
* Do we need to start reading a new block group?
*/
if (scan->inodes_left <= 0) {
+ retry:
if (scan->done_group) {
retval = (scan->done_group)
- (scan->fs, scan,
- scan->current_group,
+ (scan->fs, scan, scan->current_group,
scan->done_group_data);
if (retval)
return retval;
@@ -107,17 +307,15 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
*ino = 0;
return 0;
}
- scan->current_group++;
- scan->groups_left--;
-
- scan->current_block = scan->fs->
- group_desc[scan->current_group].bg_inode_table;
-
- if (scan->current_block == 0)
- return EXT2_ET_MISSING_INODE_TABLE;
- scan->bytes_left = 0;
- scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
- scan->blocks_left = scan->fs->inode_blocks_per_group;
+ retval = get_next_blockgroup(scan);
+ if (retval)
+ return retval;
+ if (scan->current_block == 0) {
+ if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
+ goto retry;
+ } else
+ return EXT2_ET_MISSING_INODE_TABLE;
+ }
}
/*
@@ -127,22 +325,13 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
if (scan->bytes_left < scan->inode_size) {
memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
extra_bytes = scan->bytes_left;
-
- scan->blocks_left -= scan->inode_buffer_blocks;
- num_blocks = scan->inode_buffer_blocks;
- if (scan->blocks_left < 0)
- num_blocks += scan->blocks_left;
-
- retval = io_channel_read_blk(scan->fs->io, scan->current_block,
- num_blocks, scan->inode_buffer);
+
+ retval = get_next_blocks(scan);
if (retval)
- return EXT2_ET_NEXT_INODE_READ;
- scan->ptr = scan->inode_buffer;
- scan->bytes_left = num_blocks * scan->fs->blocksize;
-
- scan->current_block += scan->inode_buffer_blocks;
+ return retval;
}
+ retval = 0;
if (extra_bytes) {
memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
scan->inode_size - extra_bytes);
@@ -155,6 +344,9 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
(struct ext2_inode *) scan->temp_buffer, 0);
else
*inode = *((struct ext2_inode *) scan->temp_buffer);
+ if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
+ retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
+ scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
} else {
if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
(scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
@@ -164,12 +356,14 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
*inode = *((struct ext2_inode *) scan->ptr);
scan->ptr += scan->inode_size;
scan->bytes_left -= scan->inode_size;
+ if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
+ retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
}
scan->inodes_left--;
scan->current_inode++;
*ino = scan->current_inode;
- return 0;
+ return retval;
}
/*
@@ -188,7 +382,7 @@ static struct {
#endif
-errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
+errcode_t ext2fs_read_inode (ext2_filsys fs, ino_t ino,
struct ext2_inode * inode)
{
unsigned long group, block, block_nr, offset;
@@ -234,6 +428,8 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
EXT2_INODE_SIZE(fs->super);
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!fs->group_desc[group].bg_inode_table)
+ return EXT2_ET_MISSING_INODE_TABLE;
block_nr = fs->group_desc[group].bg_inode_table + block;
if (block_nr != inode_buffer_block) {
retval = io_channel_read_blk(fs->io, block_nr, 1,
@@ -280,8 +476,8 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
return 0;
}
-errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
- struct ext2_inode * inode)
+errcode_t ext2fs_write_inode(ext2_filsys fs, ino_t ino,
+ struct ext2_inode * inode)
{
unsigned long group, block, block_nr, offset;
errcode_t retval;
@@ -332,11 +528,14 @@ errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
EXT2_INODE_SIZE(fs->super);
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!fs->group_desc[group].bg_inode_table)
+ return EXT2_ET_MISSING_INODE_TABLE;
block_nr = fs->group_desc[group].bg_inode_table + block;
offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
ptr = (char *) inode_buffer + offset;
length = EXT2_INODE_SIZE(fs->super);
+ clen = length;
if (length > sizeof(struct ext2_inode))
length = sizeof(struct ext2_inode);
@@ -350,12 +549,11 @@ errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
clen = EXT2_BLOCK_SIZE(fs->super) - offset;
- memcpy(ptr, &temp_inode, clen);
length -= clen;
} else {
- memcpy(ptr, &temp_inode, length);
length = 0;
}
+ memcpy(ptr, &temp_inode, clen);
retval = io_channel_write_blk(fs->io, block_nr, 1, inode_buffer);
if (retval)
return retval;
@@ -419,7 +617,7 @@ errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino)
if (retval)
return retval;
if (!LINUX_S_ISDIR(inode.i_mode))
- return ENOTDIR;
+ return ENOTDIR;
return 0;
}
diff --git a/lib/ext2fs/io.h b/lib/ext2fs/io.h
index 7a44a115..6b28fee8 100644
--- a/lib/ext2fs/io.h
+++ b/lib/ext2fs/io.h
@@ -1,8 +1,12 @@
/*
* io.h --- the I/O manager abstraction
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
/*
@@ -15,7 +19,7 @@ typedef long ext2_loff_t;
#endif
/* llseek.c */
-ext2_loff_t ext2_llseek (unsigned int, ext2_loff_t, unsigned int);
+ext2_loff_t ext2fs_llseek (unsigned int, ext2_loff_t, unsigned int);
typedef struct struct_io_manager *io_manager;
typedef struct struct_io_channel *io_channel;
@@ -68,8 +72,14 @@ struct struct_io_manager {
#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
#define io_channel_flush(c) ((c)->manager->flush((c)))
+/* unix_io.c */
extern io_manager unix_io_manager;
-
-
-
+/* test_io.c */
+extern io_manager test_io_manager, test_io_backing_manager;
+extern void (*test_io_cb_read_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_write_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_set_blksize)
+ (int blksize, errcode_t err);
diff --git a/lib/ext2fs/irel.h b/lib/ext2fs/irel.h
new file mode 100644
index 00000000..9c7529ab
--- /dev/null
+++ b/lib/ext2fs/irel.h
@@ -0,0 +1,114 @@
+/*
+ * irel.h
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+struct ext2_inode_reference {
+ blk_t block;
+ __u16 offset;
+};
+
+struct ext2_inode_relocate_entry {
+ ino_t new;
+ ino_t orig;
+ __u16 flags;
+ __u16 max_refs;
+};
+
+typedef struct ext2_inode_relocation_table *ext2_irel;
+
+struct ext2_inode_relocation_table {
+ __u32 magic;
+ char *name;
+ ino_t current;
+ void *private;
+
+ /*
+ * Add an inode relocation entry.
+ */
+ errcode_t (*put)(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+ /*
+ * Get an inode relocation entry.
+ */
+ errcode_t (*get)(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Get an inode relocation entry by its original inode number
+ */
+ errcode_t (*get_by_orig)(ext2_irel irel, ino_t orig, ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Initialize for iterating over the inode relocation entries.
+ */
+ errcode_t (*start_iter)(ext2_irel irel);
+
+ /*
+ * The iterator function for the inode relocation entries.
+ * Returns an inode number of 0 when out of entries.
+ */
+ errcode_t (*next)(ext2_irel irel, ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Add an inode reference (i.e., note the fact that a
+ * particular block/offset contains a reference to an inode)
+ */
+ errcode_t (*add_ref)(ext2_irel irel, ino_t ino,
+ struct ext2_inode_reference *ref);
+
+ /*
+ * Initialize for iterating over the inode references for a
+ * particular inode.
+ */
+ errcode_t (*start_iter_ref)(ext2_irel irel, ino_t ino);
+
+ /*
+ * The iterator function for the inode references for an
+ * inode. The references for only one inode can be interator
+ * over at a time, as the iterator state is stored in ext2_irel.
+ */
+ errcode_t (*next_ref)(ext2_irel irel,
+ struct ext2_inode_reference *ref);
+
+ /*
+ * Move the inode relocation table from one inode number to
+ * another. Note that the inode references also must move.
+ */
+ errcode_t (*move)(ext2_irel irel, ino_t old, ino_t new);
+
+ /*
+ * Remove an inode relocation entry, along with all of the
+ * inode references.
+ */
+ errcode_t (*delete)(ext2_irel irel, ino_t old);
+
+ /*
+ * Free the inode relocation table.
+ */
+ errcode_t (*free)(ext2_irel irel);
+};
+
+errcode_t ext2fs_irel_memarray_create(char *name, ino_t max_inode,
+ ext2_irel *irel);
+
+#define ext2fs_irel_put(irel, old, ent) ((irel)->put((irel), old, ent))
+#define ext2fs_irel_get(irel, old, ent) ((irel)->get((irel), old, ent))
+#define ext2fs_irel_get_by_orig(irel, orig, old, ent) \
+ ((irel)->get_by_orig((irel), orig, old, ent))
+#define ext2fs_irel_start_iter(irel) ((irel)->start_iter((irel)))
+#define ext2fs_irel_next(irel, old, ent) ((irel)->next((irel), old, ent))
+#define ext2fs_irel_add_ref(irel, ino, ref) ((irel)->add_ref((irel), ino, ref))
+#define ext2fs_irel_start_iter_ref(irel, ino) ((irel)->start_iter_ref((irel), ino))
+#define ext2fs_irel_next_ref(irel, ref) ((irel)->next_ref((irel), ref))
+#define ext2fs_irel_move(irel, old, new) ((irel)->move((irel), old, new))
+#define ext2fs_irel_delete(irel, old) ((irel)->delete((irel), old))
+#define ext2fs_irel_free(irel) ((irel)->free((irel)))
diff --git a/lib/ext2fs/irel_ma.c b/lib/ext2fs/irel_ma.c
new file mode 100644
index 00000000..1bb3af6a
--- /dev/null
+++ b/lib/ext2fs/irel_ma.c
@@ -0,0 +1,364 @@
+/*
+ * irel_ma.c
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+#include "irel.h"
+
+static errcode_t ima_put(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_get(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_get_by_orig(ext2_irel irel, ino_t orig, ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_start_iter(ext2_irel irel);
+static errcode_t ima_next(ext2_irel irel, ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_add_ref(ext2_irel irel, ino_t ino,
+ struct ext2_inode_reference *ref);
+static errcode_t ima_start_iter_ref(ext2_irel irel, ino_t ino);
+static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref);
+static errcode_t ima_move(ext2_irel irel, ino_t old, ino_t new);
+static errcode_t ima_delete(ext2_irel irel, ino_t old);
+static errcode_t ima_free(ext2_irel irel);
+
+/*
+ * This data structure stores the array of inode references; there is
+ * a structure for each inode.
+ */
+struct inode_reference_entry {
+ __u16 num;
+ struct ext2_inode_reference *refs;
+};
+
+struct irel_ma {
+ __u32 magic;
+ ino_t max_inode;
+ ino_t ref_current;
+ int ref_iter;
+ ino_t *orig_map;
+ struct ext2_inode_relocate_entry *entries;
+ struct inode_reference_entry *ref_entries;
+};
+
+errcode_t ext2fs_irel_memarray_create(char *name, ino_t max_inode,
+ ext2_irel *new_irel)
+{
+ ext2_irel irel = 0;
+ errcode_t retval;
+ struct irel_ma *ma = 0;
+ size_t size;
+
+ *new_irel = 0;
+
+ /*
+ * Allocate memory structures
+ */
+ retval = ENOMEM;
+ irel = malloc(sizeof(struct ext2_inode_relocation_table));
+ if (!irel)
+ goto errout;
+ memset(irel, 0, sizeof(struct ext2_inode_relocation_table));
+
+ irel->name = malloc(strlen(name)+1);
+ if (!irel->name)
+ goto errout;
+ strcpy(irel->name, name);
+
+ ma = malloc(sizeof(struct irel_ma));
+ if (!ma)
+ goto errout;
+ memset(ma, 0, sizeof(struct irel_ma));
+ irel->private = ma;
+
+ size = sizeof(ino_t) * (max_inode+1);
+ ma->orig_map = malloc(size);
+ if (!ma->orig_map)
+ goto errout;
+ memset(ma->orig_map, 0, size);
+
+ size = sizeof(struct ext2_inode_relocate_entry) * (max_inode+1);
+ ma->entries = malloc(size);
+ if (!ma->entries)
+ goto errout;
+ memset(ma->entries, 0, size);
+
+ size = sizeof(struct inode_reference_entry) * (max_inode+1);
+ ma->ref_entries = malloc(size);
+ if (!ma->ref_entries)
+ goto errout;
+ memset(ma->ref_entries, 0, size);
+ ma->max_inode = max_inode;
+
+ /*
+ * Fill in the irel data structure
+ */
+ irel->put = ima_put;
+ irel->get = ima_get;
+ irel->get_by_orig = ima_get_by_orig;
+ irel->start_iter = ima_start_iter;
+ irel->next = ima_next;
+ irel->add_ref = ima_add_ref;
+ irel->start_iter_ref = ima_start_iter_ref;
+ irel->next_ref = ima_next_ref;
+ irel->move = ima_move;
+ irel->delete = ima_delete;
+ irel->free = ima_free;
+
+ *new_irel = irel;
+ return 0;
+
+errout:
+ ima_free(irel);
+ return retval;
+}
+
+static errcode_t ima_put(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+ struct inode_reference_entry *ref_ent;
+ struct ext2_inode_reference *new_refs;
+ int size;
+
+ ma = irel->private;
+ if (old > ma->max_inode)
+ return EINVAL;
+
+ /*
+ * Force the orig field to the correct value; the application
+ * program shouldn't be messing with this field.
+ */
+ if (ma->entries[old].new == 0)
+ ent->orig = old;
+ else
+ ent->orig = ma->entries[old].orig;
+
+ /*
+ * If max_refs has changed, reallocate the refs array
+ */
+ ref_ent = ma->ref_entries + old;
+ if (ref_ent->refs && ent->max_refs != ma->entries[old].max_refs) {
+ size = (sizeof(struct ext2_inode_reference) * ent->max_refs);
+ new_refs = realloc(ref_ent->refs, size);
+ if (!new_refs)
+ return ENOMEM;
+ ref_ent->refs = new_refs;
+ }
+
+ ma->entries[old] = *ent;
+ ma->orig_map[ent->orig] = old;
+ return 0;
+}
+
+static errcode_t ima_get(ext2_irel irel, ino_t old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+
+ ma = irel->private;
+ if (old > ma->max_inode)
+ return EINVAL;
+ if (ma->entries[old].new == 0)
+ return ENOENT;
+ *ent = ma->entries[old];
+ return 0;
+}
+
+static errcode_t ima_get_by_orig(ext2_irel irel, ino_t orig, ino_t *old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+ ino_t ino;
+
+ ma = irel->private;
+ if (orig > ma->max_inode)
+ return EINVAL;
+ ino = ma->orig_map[orig];
+ if (ino == 0)
+ return ENOENT;
+ *old = ino;
+ *ent = ma->entries[ino];
+ return 0;
+}
+
+static errcode_t ima_start_iter(ext2_irel irel)
+{
+ irel->current = 0;
+ return 0;
+}
+
+static errcode_t ima_next(ext2_irel irel, ino_t *old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+
+ ma = irel->private;
+ while (++irel->current < ma->max_inode) {
+ if (ma->entries[irel->current].new == 0)
+ continue;
+ *old = irel->current;
+ *ent = ma->entries[irel->current];
+ return 0;
+ }
+ *old = 0;
+ return 0;
+}
+
+static errcode_t ima_add_ref(ext2_irel irel, ino_t ino,
+ struct ext2_inode_reference *ref)
+{
+ struct irel_ma *ma;
+ size_t size;
+ struct inode_reference_entry *ref_ent;
+ struct ext2_inode_relocate_entry *ent;
+
+ ma = irel->private;
+ if (ino > ma->max_inode)
+ return EINVAL;
+
+ ref_ent = ma->ref_entries + ino;
+ ent = ma->entries + ino;
+
+ /*
+ * If the inode reference array doesn't exist, create it.
+ */
+ if (ref_ent->refs == 0) {
+ size = (sizeof(struct ext2_inode_reference) * ent->max_refs);
+ ref_ent->refs = malloc(size);
+ if (ref_ent->refs == 0)
+ return ENOMEM;
+ memset(ref_ent->refs, 0, size);
+ ref_ent->num = 0;
+ }
+
+ if (ref_ent->num >= ent->max_refs)
+ return ENOSPC;
+
+ ref_ent->refs[ref_ent->num++] = *ref;
+ return 0;
+}
+
+static errcode_t ima_start_iter_ref(ext2_irel irel, ino_t ino)
+{
+ struct irel_ma *ma;
+
+ ma = irel->private;
+ if (ino > ma->max_inode)
+ return EINVAL;
+ if (ma->entries[ino].new == 0)
+ return ENOENT;
+ ma->ref_current = ino;
+ ma->ref_iter = 0;
+ return 0;
+}
+
+static errcode_t ima_next_ref(ext2_irel irel,
+ struct ext2_inode_reference *ref)
+{
+ struct irel_ma *ma;
+ struct inode_reference_entry *ref_ent;
+
+ ma = irel->private;
+
+ ref_ent = ma->ref_entries + ma->ref_current;
+
+ if ((ref_ent->refs == NULL) ||
+ (ma->ref_iter >= ref_ent->num)) {
+ ref->block = 0;
+ ref->offset = 0;
+ return 0;
+ }
+ *ref = ref_ent->refs[ma->ref_iter++];
+ return 0;
+}
+
+
+static errcode_t ima_move(ext2_irel irel, ino_t old, ino_t new)
+{
+ struct irel_ma *ma;
+
+ ma = irel->private;
+ if ((old > ma->max_inode) || (new > ma->max_inode))
+ return EINVAL;
+ if (ma->entries[old].new == 0)
+ return ENOENT;
+
+ ma->entries[new] = ma->entries[old];
+ if (ma->ref_entries[new].refs)
+ free(ma->ref_entries[new].refs);
+ ma->ref_entries[new] = ma->ref_entries[old];
+
+ ma->entries[old].new = 0;
+ ma->ref_entries[old].num = 0;
+ ma->ref_entries[old].refs = 0;
+
+ ma->orig_map[ma->entries[new].orig] = new;
+ return 0;
+}
+
+static errcode_t ima_delete(ext2_irel irel, ino_t old)
+{
+ struct irel_ma *ma;
+
+ ma = irel->private;
+ if (old > ma->max_inode)
+ return EINVAL;
+ if (ma->entries[old].new == 0)
+ return ENOENT;
+
+ ma->entries[old].new = 0;
+ if (ma->ref_entries[old].refs)
+ free(ma->ref_entries[old].refs);
+ ma->orig_map[ma->entries[old].orig] = 0;
+
+ ma->ref_entries[old].num = 0;
+ ma->ref_entries[old].refs = 0;
+ return 0;
+}
+
+static errcode_t ima_free(ext2_irel irel)
+{
+ struct irel_ma *ma;
+ ino_t ino;
+
+ if (!irel)
+ return 0;
+
+ ma = irel->private;
+
+ if (ma) {
+ if (ma->orig_map)
+ free (ma->orig_map);
+ if (ma->entries)
+ free (ma->entries);
+ if (ma->ref_entries) {
+ for (ino = 0; ino <= ma->max_inode; ino++) {
+ if (ma->ref_entries[ino].refs)
+ free(ma->ref_entries[ino].refs);
+ }
+ free(ma->ref_entries);
+ }
+ free(ma);
+ }
+ if (irel->name)
+ free(irel->name);
+ free (irel);
+ return 0;
+}
diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
index 781bfdfc..9c2593cc 100644
--- a/lib/ext2fs/ismounted.c
+++ b/lib/ext2fs/ismounted.c
@@ -1,8 +1,12 @@
/*
- * getsize.c --- get the size of a partition.
+ * ismounted.c --- Check to see if the filesystem was mounted
*
- * Copyright (C) 1995 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
+ * Copyright (C) 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c
index 042183b9..933dfa83 100644
--- a/lib/ext2fs/link.c
+++ b/lib/ext2fs/link.c
@@ -1,8 +1,12 @@
/*
- * link.c --- create or delete links in a ext2fs directory
+ * link.c --- create links in a ext2fs directory
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -104,48 +108,3 @@ errcode_t ext2fs_link(ext2_filsys fs, ino_t dir, const char *name, ino_t ino,
return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
}
-
-static int unlink_proc(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *private)
-{
- struct link_struct *ls = (struct link_struct *) private;
-
- if (ls->name && (dirent->name_len != ls->namelen))
- return 0;
- if (ls->name && strncmp(ls->name, dirent->name, dirent->name_len))
- return 0;
- if (ls->inode && (dirent->inode != ls->inode))
- return 0;
-
- dirent->inode = 0;
- ls->done++;
- return DIRENT_ABORT|DIRENT_CHANGED;
-}
-
-errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name, ino_t ino,
- int flags)
-{
- errcode_t retval;
- struct link_struct ls;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- if (!(fs->flags & EXT2_FLAG_RW))
- return EXT2_ET_RO_FILSYS;
-
- ls.name = name;
- ls.namelen = name ? strlen(name) : 0;
- ls.inode = ino;
- ls.flags = 0;
- ls.done = 0;
-
- retval = ext2fs_dir_iterate(fs, dir, 0, 0, unlink_proc, &ls);
- if (retval)
- return retval;
-
- return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
-}
-
diff --git a/lib/ext2fs/llseek.c b/lib/ext2fs/llseek.c
index 02e0ede8..71a9d910 100644
--- a/lib/ext2fs/llseek.c
+++ b/lib/ext2fs/llseek.c
@@ -1,8 +1,12 @@
/*
* llseek.c -- stub calling the llseek system call
*
- * Copyright (C) 1994 Remy Card. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <sys/types.h>
@@ -55,7 +59,7 @@ static ext2_loff_t llseek (unsigned int fd, ext2_loff_t offset,
#endif /* __alpha__ */
-ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
+ext2_loff_t ext2fs_llseek (unsigned int fd, ext2_loff_t offset,
unsigned int origin)
{
ext2_loff_t result;
@@ -84,7 +88,7 @@ ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
#else /* !linux */
-ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
+ext2_loff_t ext2fs_llseek (unsigned int fd, ext2_loff_t offset,
unsigned int origin)
{
if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
diff --git a/lib/ext2fs/lookup.c b/lib/ext2fs/lookup.c
new file mode 100644
index 00000000..5cded5ff
--- /dev/null
+++ b/lib/ext2fs/lookup.c
@@ -0,0 +1,69 @@
+/*
+ * lookup.c --- ext2fs directory lookup operations
+ *
+ * Copyright (C) 1993, 1994, 1994, 1995 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>
+#include <unistd.h>
+#include <stdlib.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+struct lookup_struct {
+ const char *name;
+ int len;
+ ino_t *inode;
+ int found;
+};
+
+static int lookup_proc(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private)
+{
+ struct lookup_struct *ls = (struct lookup_struct *) private;
+
+ if (ls->len != dirent->name_len)
+ return 0;
+ if (strncmp(ls->name, dirent->name, dirent->name_len))
+ return 0;
+ *ls->inode = dirent->inode;
+ ls->found++;
+ return DIRENT_ABORT;
+}
+
+
+errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
+ int namelen, char *buf, ino_t *inode)
+{
+ errcode_t retval;
+ struct lookup_struct ls;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ ls.name = name;
+ ls.len = namelen;
+ ls.inode = inode;
+ ls.found = 0;
+
+ retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
+ if (retval)
+ return retval;
+
+ return (ls.found) ? 0 : ENOENT;
+}
+
+
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index af3b9b7b..67a2046d 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -1,8 +1,12 @@
/*
* mkdir.c --- make a directory in the filesystem
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/namei.c b/lib/ext2fs/namei.c
index 8fc71b08..ae39eecd 100644
--- a/lib/ext2fs/namei.c
+++ b/lib/ext2fs/namei.c
@@ -1,8 +1,12 @@
/*
* namei.c --- ext2fs directory lookup operations
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -19,163 +23,6 @@
#include "ext2fs.h"
-struct dir_context {
- ino_t dir;
- int flags;
- char *buf;
- int (*func)(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *private);
- void *private;
- errcode_t errcode;
-};
-
-static int process_dir_block(ext2_filsys fs,
- blk_t *blocknr,
- int blockcnt,
- void *private);
-
-errcode_t ext2fs_dir_iterate(ext2_filsys fs,
- ino_t dir,
- int flags,
- char *block_buf,
- int (*func)(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *private),
- void *private)
-{
- struct dir_context ctx;
- errcode_t retval;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- retval = ext2fs_check_directory(fs, dir);
- if (retval)
- return retval;
-
- ctx.dir = dir;
- ctx.flags = flags;
- if (block_buf)
- ctx.buf = block_buf;
- else {
- ctx.buf = malloc(fs->blocksize);
- if (!ctx.buf)
- return ENOMEM;
- }
- ctx.func = func;
- ctx.private = private;
- ctx.errcode = 0;
- retval = ext2fs_block_iterate(fs, dir, 0, 0, process_dir_block, &ctx);
- if (!block_buf)
- free(ctx.buf);
- if (retval)
- return retval;
- return ctx.errcode;
-}
-
-static int process_dir_block(ext2_filsys fs,
- blk_t *blocknr,
- int blockcnt,
- void *private)
-{
- struct dir_context *ctx = (struct dir_context *) private;
- int offset = 0;
- int ret;
- int changed = 0;
- int do_abort = 0;
- struct ext2_dir_entry *dirent;
-
- if (blockcnt < 0)
- return 0;
-
- ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf);
- if (ctx->errcode)
- return BLOCK_ABORT;
-
- while (offset < fs->blocksize) {
- dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
- if (!dirent->inode &&
- !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
- goto next;
-
- ret = (ctx->func)(dirent, offset, fs->blocksize,
- ctx->buf, ctx->private);
- if (ret & DIRENT_CHANGED)
- changed++;
- if (ret & DIRENT_ABORT) {
- do_abort++;
- break;
- }
-next:
- if (((offset + dirent->rec_len) > fs->blocksize) ||
- (dirent->rec_len < 8) ||
- ((dirent->name_len+8) > dirent->rec_len)) {
- ctx->errcode = EXT2_ET_DIR_CORRUPTED;
- return BLOCK_ABORT;
- }
- offset += dirent->rec_len;
- }
-
- if (changed) {
- ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf);
- if (ctx->errcode)
- return BLOCK_ABORT;
- }
- if (do_abort)
- return BLOCK_ABORT;
- return 0;
-}
-
-struct lookup_struct {
- const char *name;
- int len;
- ino_t *inode;
- int found;
-};
-
-static int lookup_proc(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *private)
-{
- struct lookup_struct *ls = (struct lookup_struct *) private;
-
- if (ls->len != dirent->name_len)
- return 0;
- if (strncmp(ls->name, dirent->name, dirent->name_len))
- return 0;
- *ls->inode = dirent->inode;
- ls->found++;
- return DIRENT_ABORT;
-}
-
-
-errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
- int namelen, char *buf, ino_t *inode)
-{
- errcode_t retval;
- struct lookup_struct ls;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- ls.name = name;
- ls.len = namelen;
- ls.inode = inode;
- ls.found = 0;
-
- retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
- if (retval)
- return retval;
-
- return (ls.found) ? 0 : ENOENT;
-}
-
-
static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
const char *pathname, int pathlen, int follow,
int link_count, char *buf, ino_t *res_inode);
diff --git a/lib/ext2fs/native.c b/lib/ext2fs/native.c
index 2f84bf7d..3fdc4a0f 100644
--- a/lib/ext2fs/native.c
+++ b/lib/ext2fs/native.c
@@ -3,8 +3,10 @@
*
* Copyright (C) 1996 Theodore Ts'o.
*
+ * %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/newdir.c b/lib/ext2fs/newdir.c
index 22547266..863960fa 100644
--- a/lib/ext2fs/newdir.c
+++ b/lib/ext2fs/newdir.c
@@ -1,8 +1,12 @@
/*
* newdir.c --- create a new directory block
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index 389bfc79..b2e2393a 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -1,10 +1,12 @@
/*
* openfs.c --- open an ext2 filesystem
*
- * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
*
+ * %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -30,6 +32,12 @@
/*
* Note: if superblock is non-zero, block-size must also be non-zero.
* Superblock and block_size can be zero to use the default size.
+ *
+ * Valid flags for ext2fs_open()
+ *
+ * EXT2_FLAG_RW - Open the filesystem for read/write.
+ * EXT2_FLAG_FORCE - Open the filesystem even if some of the
+ * features aren't supported.
*/
errcode_t ext2fs_open(const char *name, int flags, int superblock,
int block_size, io_manager manager, ext2_filsys *ret_fs)
@@ -39,6 +47,7 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
int i, j, group_block, groups_per_block;
char *dest;
struct ext2_group_desc *gdp;
+ struct ext2fs_sb *s;
EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
@@ -112,6 +121,22 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
}
#endif
#endif
+ /*
+ * Check for feature set incompatibility
+ */
+ if (!(flags & EXT2_FLAG_FORCE)) {
+ s = (struct ext2fs_sb *) fs->super;
+ if (s->s_feature_incompat) {
+ retval = EXT2_ET_UNSUPP_FEATURE;
+ goto cleanup;
+ }
+ if ((flags & EXT2_FLAG_RW) &&
+ s->s_feature_ro_compat) {
+ retval = EXT2_ET_RO_UNSUPP_FEATURE;
+ goto cleanup;
+ }
+ }
+
fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
if (fs->blocksize == 0) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
diff --git a/lib/ext2fs/read_bb.c b/lib/ext2fs/read_bb.c
index 1a9f7742..3fabddd2 100644
--- a/lib/ext2fs/read_bb.c
+++ b/lib/ext2fs/read_bb.c
@@ -1,8 +1,12 @@
/*
* read_bb --- read the bad blocks inode
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1994 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -19,7 +23,7 @@
#include "ext2fs.h"
struct read_bb_record {
- badblocks_list bb_list;
+ ext2_badblocks_list bb_list;
errcode_t err;
};
@@ -34,7 +38,7 @@ static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
if (blockcnt < 0)
return 0;
- rb->err = badblocks_list_add(rb->bb_list, *block_nr);
+ rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
if (rb->err)
return BLOCK_ABORT;
return 0;
@@ -43,7 +47,7 @@ static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
/*
* Reads the current bad blocks from the bad blocks inode.
*/
-errcode_t ext2fs_read_bb_inode(ext2_filsys fs, badblocks_list *bb_list)
+errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
{
errcode_t retval;
struct read_bb_record rb;
@@ -57,7 +61,7 @@ errcode_t ext2fs_read_bb_inode(ext2_filsys fs, badblocks_list *bb_list)
if (retval)
return retval;
numblocks = (inode.i_blocks / (fs->blocksize / 512)) + 20;
- retval = badblocks_list_create(bb_list, numblocks);
+ retval = ext2fs_badblocks_list_create(bb_list, numblocks);
if (retval)
return retval;
}
diff --git a/lib/ext2fs/read_bb_file.c b/lib/ext2fs/read_bb_file.c
index 04e15819..16c2e0b0 100644
--- a/lib/ext2fs/read_bb_file.c
+++ b/lib/ext2fs/read_bb_file.c
@@ -1,8 +1,12 @@
/*
* read_bb_file.c --- read a list of bad blocks for a FILE *
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -22,7 +26,7 @@
* Reads a list of bad blocks from a FILE *
*/
errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
- badblocks_list *bb_list,
+ ext2_badblocks_list *bb_list,
void (*invalid)(ext2_filsys fs, blk_t blk))
{
errcode_t retval;
@@ -33,7 +37,7 @@ errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!*bb_list) {
- retval = badblocks_list_create(bb_list, 10);
+ retval = ext2fs_badblocks_list_create(bb_list, 10);
if (retval)
return retval;
}
@@ -50,7 +54,7 @@ errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
(invalid)(fs, blockno);
continue;
}
- retval = badblocks_list_add(*bb_list, blockno);
+ retval = ext2fs_badblocks_list_add(*bb_list, blockno);
if (retval)
return retval;
}
diff --git a/lib/ext2fs/rs_bitmap.c b/lib/ext2fs/rs_bitmap.c
new file mode 100644
index 00000000..90178534
--- /dev/null
+++ b/lib/ext2fs/rs_bitmap.c
@@ -0,0 +1,92 @@
+/*
+ * rs_bitmap.c --- routine for changing the size of a bitmap
+ *
+ * Copyright (C) 1996, 1997 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+errcode_t ext2fs_resize_generic_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_generic_bitmap bmap)
+{
+ size_t size, new_size;
+ char *new_bitmap;
+
+ if (!bmap)
+ return EINVAL;
+
+ EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_GENERIC_BITMAP);
+
+ if (new_real_end == bmap->real_end) {
+ bmap->end = new_end;
+ return 0;
+ }
+
+ size = ((bmap->real_end - bmap->start) / 8) + 1;
+ new_size = ((new_real_end - bmap->start) / 8) + 1;
+
+ new_bitmap = realloc(bmap->bitmap, new_size);
+ if (!new_bitmap)
+ return ENOMEM;
+ if (new_size > size)
+ memset(new_bitmap + size, 0, new_size - size);
+
+ bmap->bitmap = new_bitmap;
+ bmap->end = new_end;
+ bmap->real_end = new_real_end;
+ return 0;
+}
+
+errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_inode_bitmap bmap)
+{
+ errcode_t retval;
+
+ if (!bmap)
+ return EINVAL;
+
+ EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_INODE_BITMAP);
+
+ bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
+ bmap);
+ bmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+ return retval;
+}
+
+errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_block_bitmap bmap)
+{
+ errcode_t retval;
+
+ if (!bmap)
+ return EINVAL;
+
+ EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+ bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
+ bmap);
+ bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
+ return retval;
+}
+
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index 3a3f51f1..e9bb58c4 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -1,8 +1,12 @@
/*
* rw_bitmaps.c --- routines to read and write the inode and block bitmaps.
*
- * Copyright (C) 1993,1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1994, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -28,6 +32,7 @@ errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
errcode_t retval;
char * inode_bitmap = fs->inode_map->bitmap;
char * bitmap_block = NULL;
+ blk_t blk;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -43,11 +48,13 @@ errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
memset(bitmap_block, 0xff, fs->blocksize);
for (i = 0; i < fs->group_desc_count; i++) {
memcpy(bitmap_block, inode_bitmap, nbytes);
- retval = io_channel_write_blk(fs->io,
- fs->group_desc[i].bg_inode_bitmap, 1,
- bitmap_block);
- if (retval)
- return EXT2_ET_INODE_BITMAP_WRITE;
+ blk = fs->group_desc[i].bg_inode_bitmap;
+ if (blk) {
+ retval = io_channel_write_blk(fs->io, blk, 1,
+ bitmap_block);
+ if (retval)
+ return EXT2_ET_INODE_BITMAP_WRITE;
+ }
inode_bitmap += nbytes;
}
fs->flags |= EXT2_FLAG_CHANGED;
@@ -65,6 +72,7 @@ errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
errcode_t retval;
char * block_bitmap = fs->block_map->bitmap;
char * bitmap_block = NULL;
+ blk_t blk;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -88,11 +96,13 @@ errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
for (j = nbits; j < fs->blocksize * 8; j++)
ext2fs_set_bit(j, bitmap_block);
}
- retval = io_channel_write_blk(fs->io,
- fs->group_desc[i].bg_block_bitmap, 1,
- bitmap_block);
- if (retval)
- return EXT2_ET_BLOCK_BITMAP_WRITE;
+ blk = fs->group_desc[i].bg_block_bitmap;
+ if (blk) {
+ retval = io_channel_write_blk(fs->io, blk, 1,
+ bitmap_block);
+ if (retval)
+ return EXT2_ET_BLOCK_BITMAP_WRITE;
+ }
block_bitmap += nbytes;
}
fs->flags |= EXT2_FLAG_CHANGED;
@@ -109,6 +119,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
errcode_t retval;
int block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+ blk_t blk;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -137,25 +148,29 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
for (i = 0; i < fs->group_desc_count; i++) {
if (block_bitmap) {
- retval = io_channel_read_blk
- (fs->io,
- fs->group_desc[i].bg_block_bitmap,
- -block_nbytes, block_bitmap);
- if (retval) {
- retval = EXT2_ET_BLOCK_BITMAP_READ;
- goto cleanup;
- }
+ blk = fs->group_desc[i].bg_block_bitmap;
+ if (blk) {
+ retval = io_channel_read_blk(fs->io, blk,
+ -block_nbytes, block_bitmap);
+ if (retval) {
+ retval = EXT2_ET_BLOCK_BITMAP_READ;
+ goto cleanup;
+ }
+ } else
+ memset(block_bitmap, 0, block_nbytes);
block_bitmap += block_nbytes;
}
if (inode_bitmap) {
- retval = io_channel_read_blk
- (fs->io,
- fs->group_desc[i].bg_inode_bitmap,
- -inode_nbytes, inode_bitmap);
- if (retval) {
- retval = EXT2_ET_INODE_BITMAP_READ;
- goto cleanup;
- }
+ blk = fs->group_desc[i].bg_inode_bitmap;
+ if (blk) {
+ retval = io_channel_read_blk(fs->io, blk,
+ -inode_nbytes, inode_bitmap);
+ if (retval) {
+ retval = EXT2_ET_INODE_BITMAP_READ;
+ goto cleanup;
+ }
+ } else
+ memset(inode_bitmap, 0, inode_nbytes);
inode_bitmap += inode_nbytes;
}
}
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 968f41c2..de347ac3 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -1,8 +1,12 @@
/*
* swapfs.c --- swap ext2 filesystem data structures
*
- * Copyright (C) 1995 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -98,9 +102,15 @@ void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
switch (fs->super->s_creator_os) {
case EXT2_OS_LINUX:
+ t->osd1.linux1.l_i_reserved1 =
+ ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
+ t->osd2.linux2.l_i_reserved2[0] =
+ ext2fs_swab32(f->osd2.linux2.l_i_reserved2[0]);
+ t->osd2.linux2.l_i_reserved2[1] =
+ ext2fs_swab32(f->osd2.linux2.l_i_reserved2[1]);
break;
case EXT2_OS_HURD:
t->osd1.hurd1.h_i_translator =
@@ -117,9 +127,15 @@ void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
ext2fs_swab32 (f->osd2.hurd2.h_i_author);
break;
case EXT2_OS_MASIX:
+ t->osd1.masix1.m_i_reserved1 =
+ ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
+ t->osd2.masix2.m_i_reserved2[0] =
+ ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
+ t->osd2.masix2.m_i_reserved2[1] =
+ ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
break;
}
}
diff --git a/lib/ext2fs/test_io.c b/lib/ext2fs/test_io.c
new file mode 100644
index 00000000..1bd09b1e
--- /dev/null
+++ b/lib/ext2fs/test_io.c
@@ -0,0 +1,227 @@
+/*
+ * test_io.c --- This is the Test I/O interface.
+ *
+ * Copyright (C) 1996 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "et/com_err.h"
+#include "ext2fs/ext2_err.h"
+#include "io.h"
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+ if ((struct)->magic != (code)) return (code)
+
+struct test_private_data {
+ int magic;
+ io_channel real;
+ void (*read_blk)(unsigned long block, int count, errcode_t err);
+ void (*write_blk)(unsigned long block, int count, errcode_t err);
+ void (*set_blksize)(int blksize, errcode_t err);
+};
+
+static errcode_t test_open(const char *name, int flags, io_channel *channel);
+static errcode_t test_close(io_channel channel);
+static errcode_t test_set_blksize(io_channel channel, int blksize);
+static errcode_t test_read_blk(io_channel channel, unsigned long block,
+ int count, void *data);
+static errcode_t test_write_blk(io_channel channel, unsigned long block,
+ int count, const void *data);
+static errcode_t test_flush(io_channel channel);
+
+static struct struct_io_manager struct_test_manager = {
+ EXT2_ET_MAGIC_IO_MANAGER,
+ "Test I/O Manager",
+ test_open,
+ test_close,
+ test_set_blksize,
+ test_read_blk,
+ test_write_blk,
+ test_flush
+};
+
+io_manager test_io_manager = &struct_test_manager;
+
+/*
+ * These global variable can be set by the test program as
+ * necessary *before* calling test_open
+ */
+io_manager test_io_backing_manager = 0;
+void (*test_io_cb_read_blk)
+ (unsigned long block, int count, errcode_t err) = 0;
+void (*test_io_cb_write_blk)
+ (unsigned long block, int count, errcode_t err) = 0;
+void (*test_io_cb_set_blksize)
+ (int blksize, errcode_t err) = 0;
+
+static errcode_t test_open(const char *name, int flags, io_channel *channel)
+{
+ io_channel io = NULL;
+ struct test_private_data *data = NULL;
+ errcode_t retval;
+
+ if (name == 0)
+ return EXT2_ET_BAD_DEVICE_NAME;
+ io = (io_channel) malloc(sizeof(struct struct_io_channel));
+ if (!io)
+ return ENOMEM;
+ memset(io, 0, sizeof(struct struct_io_channel));
+ io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+ data = (struct test_private_data *)
+ malloc(sizeof(struct test_private_data));
+ if (!data) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ io->manager = test_io_manager;
+ io->name = malloc(strlen(name)+1);
+ if (!io->name) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ strcpy(io->name, name);
+ io->private_data = data;
+ io->block_size = 1024;
+ io->read_error = 0;
+ io->write_error = 0;
+
+ memset(data, 0, sizeof(struct test_private_data));
+ data->magic = EXT2_ET_MAGIC_TEST_IO_CHANNEL;
+ if (test_io_backing_manager) {
+ retval = test_io_backing_manager->open(name, flags,
+ &data->real);
+ if (retval)
+ goto cleanup;
+ } else
+ data->real = 0;
+ data->read_blk = test_io_cb_read_blk;
+ data->write_blk = test_io_cb_write_blk;
+ data->set_blksize = test_io_cb_set_blksize;
+
+ *channel = io;
+ return 0;
+
+cleanup:
+ if (io)
+ free(io);
+ if (data)
+ free(data);
+ return retval;
+}
+
+static errcode_t test_close(io_channel channel)
+{
+ struct test_private_data *data;
+ errcode_t retval = 0;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ data = (struct test_private_data *) channel->private_data;
+ EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
+
+ if (data->real)
+ retval = io_channel_close(data->real);
+
+ if (channel->private_data)
+ free(channel->private_data);
+ if (channel->name)
+ free(channel->name);
+ free(channel);
+ return retval;
+}
+
+static errcode_t test_set_blksize(io_channel channel, int blksize)
+{
+ struct test_private_data *data;
+ errcode_t retval = 0;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ data = (struct test_private_data *) channel->private_data;
+ EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
+
+ if (data->real)
+ retval = io_channel_set_blksize(data->real, blksize);
+ if (data->set_blksize)
+ data->set_blksize(blksize, retval);
+ else
+ printf("Test_io: set_blksize(%d) returned %s\n",
+ blksize, retval ? error_message(retval) : "OK");
+ return retval;
+}
+
+
+static errcode_t test_read_blk(io_channel channel, unsigned long block,
+ int count, void *buf)
+{
+ struct test_private_data *data;
+ errcode_t retval = 0;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ data = (struct test_private_data *) channel->private_data;
+ EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
+
+ if (data->real)
+ retval = io_channel_read_blk(data->real, block, count, buf);
+ if (data->read_blk)
+ data->read_blk(block, count, retval);
+ else
+ printf("Test_io: read_blk(%lu, %d) returned %s\n",
+ block, count, retval ? error_message(retval) : "OK");
+ return retval;
+}
+
+static errcode_t test_write_blk(io_channel channel, unsigned long block,
+ int count, const void *buf)
+{
+ struct test_private_data *data;
+ errcode_t retval = 0;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ data = (struct test_private_data *) channel->private_data;
+ EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
+
+ if (data->real)
+ retval = io_channel_write_blk(data->real, block, count, buf);
+ if (data->write_blk)
+ data->write_blk(block, count, retval);
+ else
+ printf("Test_io: write_blk(%lu, %d) returned %s\n",
+ block, count, retval ? error_message(retval) : "OK");
+ return retval;
+}
+
+/*
+ * Flush data buffers to disk.
+ */
+static errcode_t test_flush(io_channel channel)
+{
+ struct test_private_data *data;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ data = (struct test_private_data *) channel->private_data;
+ EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
+
+ if (data->real)
+ return io_channel_flush(data->real);
+ return 0;
+}
+
diff --git a/lib/ext2fs/tst_badblocks.c b/lib/ext2fs/tst_badblocks.c
new file mode 100644
index 00000000..d071406a
--- /dev/null
+++ b/lib/ext2fs/tst_badblocks.c
@@ -0,0 +1,162 @@
+/*
+ * This testing program makes sure the badblocks implementation works.
+ *
+ * Copyright (C) 1996 by 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+blk_t test1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
+blk_t test2[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+blk_t test3[] = { 3, 1, 4, 5, 9, 2, 7, 10, 6, 8, 0 };
+blk_t test4[] = { 20, 50, 12, 17, 13, 2, 66, 23, 56, 0 };
+blk_t test4a[] = {
+ 20, 1,
+ 50, 1,
+ 3, 0,
+ 17, 1,
+ 18, 0,
+ 16, 0,
+ 11, 0,
+ 12, 1,
+ 13, 1,
+ 14, 0,
+ 80, 0,
+ 45, 0,
+ 66, 1,
+ 0 };
+
+static int test_fail = 0;
+
+static errcode_t create_test_list(blk_t *vec, badblocks_list *ret)
+{
+ errcode_t retval;
+ badblocks_list bb;
+ int i;
+
+ retval = badblocks_list_create(&bb, 5);
+ if (retval) {
+ com_err("create_test_list", retval, "while creating list");
+ return retval;
+ }
+ for (i=0; vec[i]; i++) {
+ retval = badblocks_list_add(bb, vec[i]);
+ if (retval) {
+ com_err("create_test_list", retval,
+ "while adding test vector %d", i);
+ badblocks_list_free(bb);
+ return retval;
+ }
+ }
+ *ret = bb;
+ return 0;
+}
+
+static void print_list(badblocks_list bb, int verify)
+{
+ errcode_t retval;
+ badblocks_iterate iter;
+ blk_t blk;
+ int i, ok;
+
+ retval = badblocks_list_iterate_begin(bb, &iter);
+ if (retval) {
+ com_err("print_list", retval, "while setting up iterator");
+ return;
+ }
+ ok = i = 1;
+ while (badblocks_list_iterate(iter, &blk)) {
+ printf("%d ", blk);
+ if (i++ != blk)
+ ok = 0;
+ }
+ badblocks_list_iterate_end(iter);
+ if (verify) {
+ if (ok)
+ printf("--- OK");
+ else {
+ printf("--- NOT OK");
+ test_fail++;
+ }
+ }
+}
+
+static void validate_test_seq(badblocks_list bb, blk_t *vec)
+{
+ int i, match, ok;
+
+ for (i = 0; vec[i]; i += 2) {
+ match = badblocks_list_test(bb, vec[i]);
+ if (match == vec[i+1])
+ ok = 1;
+ else {
+ ok = 0;
+ test_fail++;
+ }
+ printf("\tblock %d is %s --- %s\n", vec[i],
+ match ? "present" : "absent",
+ ok ? "OK" : "NOT OK");
+ }
+}
+
+int main(int argc, char *argv)
+{
+ badblocks_list bb;
+ errcode_t retval;
+
+ printf("test1: ");
+ retval = create_test_list(test1, &bb);
+ if (retval == 0) {
+ print_list(bb, 1);
+ badblocks_list_free(bb);
+ }
+ printf("\n");
+
+ printf("test2: ");
+ retval = create_test_list(test2, &bb);
+ if (retval == 0) {
+ print_list(bb, 1);
+ badblocks_list_free(bb);
+ }
+ printf("\n");
+
+ printf("test3: ");
+ retval = create_test_list(test3, &bb);
+ if (retval == 0) {
+ print_list(bb, 1);
+ badblocks_list_free(bb);
+ }
+ printf("\n");
+
+ printf("test4: ");
+ retval = create_test_list(test4, &bb);
+ if (retval == 0) {
+ print_list(bb, 0);
+ printf("\n");
+ validate_test_seq(bb, test4a);
+ badblocks_list_free(bb);
+ }
+ printf("\n");
+ if (test_fail == 0)
+ printf("ext2fs library badblocks tests checks out OK!\n");
+ return test_fail;
+}
diff --git a/lib/ext2fs/tst_iscan.c b/lib/ext2fs/tst_iscan.c
new file mode 100644
index 00000000..dbf0813a
--- /dev/null
+++ b/lib/ext2fs/tst_iscan.c
@@ -0,0 +1,218 @@
+/*
+ * tst_inode.c --- this function tests the inode scan function
+ *
+ * Copyright (C) 1996 by 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+blk_t test_vec[] = { 8, 12, 24, 34, 43, 44, 100, 0 };
+
+ext2_filsys test_fs;
+ext2fs_block_bitmap bad_block_map, touched_map;
+ext2fs_inode_bitmap bad_inode_map;
+badblocks_list test_badblocks;
+
+int first_no_comma = 1;
+int failed = 0;
+
+static void test_read_blk(unsigned long block, int count, errcode_t err)
+{
+ int i;
+
+ if (first_no_comma)
+ first_no_comma = 0;
+ else
+ printf(", ");
+
+ if (count > 1)
+ printf("%lu-%lu", block, block+count-1);
+ else
+ printf("%lu", block);
+
+ for (i=0; i < count; i++, block++) {
+ if (ext2fs_test_block_bitmap(touched_map, block)) {
+ printf("\nDuplicate block?!? --- %lu\n", block);
+ failed++;
+ first_no_comma = 1;
+ }
+ ext2fs_mark_block_bitmap(touched_map, block);
+ }
+}
+
+/*
+ * Setup the variables for doing the inode scan test.
+ */
+static void setup(void)
+{
+ errcode_t retval;
+ int i;
+ struct ext2_super_block param;
+
+ initialize_ext2_error_table();
+
+ memset(&param, 0, sizeof(param));
+ param.s_blocks_count = 12000;
+
+
+ test_io_cb_read_blk = test_read_blk;
+
+ retval = ext2fs_initialize("test fs", 0, &param,
+ test_io_manager, &test_fs);
+ if (retval) {
+ com_err("setup", retval,
+ "While initializing filesystem");
+ exit(1);
+ }
+ retval = ext2fs_allocate_tables(test_fs);
+ if (retval) {
+ com_err("setup", retval,
+ "While allocating tables for test filesystem");
+ exit(1);
+ }
+ retval = ext2fs_allocate_block_bitmap(test_fs, "bad block map",
+ &bad_block_map);
+ if (retval) {
+ com_err("setup", retval,
+ "While allocating bad_block bitmap");
+ exit(1);
+ }
+ retval = ext2fs_allocate_block_bitmap(test_fs, "touched map",
+ &touched_map);
+ if (retval) {
+ com_err("setup", retval,
+ "While allocating touched block bitmap");
+ exit(1);
+ }
+ retval = ext2fs_allocate_inode_bitmap(test_fs, "bad inode map",
+ &bad_inode_map);
+ if (retval) {
+ com_err("setup", retval,
+ "While allocating bad inode bitmap");
+ exit(1);
+ }
+
+ retval = badblocks_list_create(&test_badblocks, 5);
+ if (retval) {
+ com_err("setup", retval, "while creating badblocks list");
+ exit(1);
+ }
+ for (i=0; test_vec[i]; i++) {
+ retval = badblocks_list_add(test_badblocks, test_vec[i]);
+ if (retval) {
+ com_err("setup", retval,
+ "while adding test vector %d", i);
+ exit(1);
+ }
+ ext2fs_mark_block_bitmap(bad_block_map, test_vec[i]);
+ }
+ test_fs->badblocks = test_badblocks;
+}
+
+/*
+ * Iterate using inode_scan
+ */
+static void iterate(void)
+{
+ struct ext2_inode inode;
+ ext2_inode_scan scan;
+ errcode_t retval;
+ ino_t ino;
+
+ retval = ext2fs_open_inode_scan(test_fs, 8, &scan);
+ if (retval) {
+ com_err("iterate", retval, "While opening inode scan");
+ exit(1);
+ }
+ printf("Reading blocks: ");
+ retval = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (retval) {
+ com_err("iterate", retval, "while reading first inode");
+ exit(1);
+ }
+ while (ino) {
+ retval = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
+ ext2fs_mark_inode_bitmap(bad_inode_map, ino);
+ continue;
+ }
+ if (retval) {
+ com_err("iterate", retval,
+ "while getting next inode");
+ exit(1);
+ }
+ }
+ printf("\n");
+ ext2fs_close_inode_scan(scan);
+}
+
+/*
+ * Verify the touched map
+ */
+static void check_map(void)
+{
+ int i, j, first=1;
+ unsigned long blk;
+
+ for (i=0; test_vec[i]; i++) {
+ if (ext2fs_test_block_bitmap(touched_map, test_vec[i])) {
+ printf("Bad block was touched --- %d\n", test_vec[i]);
+ failed++;
+ first_no_comma = 1;
+ }
+ ext2fs_mark_block_bitmap(touched_map, test_vec[i]);
+ }
+ for (i = 0; i < test_fs->group_desc_count; i++) {
+ for (j=0, blk = test_fs->group_desc[i].bg_inode_table;
+ j < test_fs->inode_blocks_per_group;
+ j++, blk++) {
+ if (!ext2fs_test_block_bitmap(touched_map, blk) &&
+ !ext2fs_test_block_bitmap(bad_block_map, blk)) {
+ printf("Missing block --- %lu\n", blk);
+ failed++;
+ }
+ }
+ }
+ printf("Bad inodes: ");
+ for (i=1; i <= test_fs->super->s_inodes_count; i++) {
+ if (ext2fs_test_inode_bitmap(bad_inode_map, i)) {
+ if (first)
+ first = 0;
+ else
+ printf(", ");
+ printf("%d", i);
+ }
+ }
+ printf("\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ setup();
+ iterate();
+ check_map();
+ if (!failed)
+ printf("Inode scan tested OK!\n");
+ return failed;
+}
+
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c
index b9955150..5083771f 100644
--- a/lib/ext2fs/unix_io.c
+++ b/lib/ext2fs/unix_io.c
@@ -3,8 +3,12 @@
*
* Implements a one-block write-through cache.
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
@@ -184,7 +188,7 @@ static errcode_t unix_read_blk(io_channel channel, unsigned long block,
#endif
size = (count < 0) ? -count : count * channel->block_size;
location = (ext2_loff_t) block * channel->block_size;
- if (ext2_llseek(data->dev, location, SEEK_SET) != location) {
+ if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
retval = errno;
goto error_out;
}
@@ -233,7 +237,7 @@ static errcode_t unix_write_blk(io_channel channel, unsigned long block,
}
location = (ext2_loff_t) block * channel->block_size;
- if (ext2_llseek(data->dev, location, SEEK_SET) != location) {
+ if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
retval = errno;
goto error_out;
}
diff --git a/lib/ext2fs/unlink.c b/lib/ext2fs/unlink.c
new file mode 100644
index 00000000..e0309aa5
--- /dev/null
+++ b/lib/ext2fs/unlink.c
@@ -0,0 +1,72 @@
+/*
+ * unlink.c --- delete links in a ext2fs directory
+ *
+ * Copyright (C) 1993, 1994, 1997 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>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+struct link_struct {
+ const char *name;
+ int namelen;
+ ino_t inode;
+ int flags;
+ int done;
+};
+
+static int unlink_proc(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private)
+{
+ struct link_struct *ls = (struct link_struct *) private;
+
+ if (ls->name && (dirent->name_len != ls->namelen))
+ return 0;
+ if (ls->name && strncmp(ls->name, dirent->name, dirent->name_len))
+ return 0;
+ if (ls->inode && (dirent->inode != ls->inode))
+ return 0;
+
+ dirent->inode = 0;
+ ls->done++;
+ return DIRENT_ABORT|DIRENT_CHANGED;
+}
+
+errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name, ino_t ino,
+ int flags)
+{
+ errcode_t retval;
+ struct link_struct ls;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!(fs->flags & EXT2_FLAG_RW))
+ return EXT2_ET_RO_FILSYS;
+
+ ls.name = name;
+ ls.namelen = name ? strlen(name) : 0;
+ ls.inode = ino;
+ ls.flags = 0;
+ ls.done = 0;
+
+ retval = ext2fs_dir_iterate(fs, dir, 0, 0, unlink_proc, &ls);
+ if (retval)
+ return retval;
+
+ return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
+}
+
diff --git a/lib/ext2fs/valid_blk.c b/lib/ext2fs/valid_blk.c
new file mode 100644
index 00000000..3a0cb3eb
--- /dev/null
+++ b/lib/ext2fs/valid_blk.c
@@ -0,0 +1,49 @@
+/*
+ * valid_blk.c --- does the inode have valid blocks?
+ *
+ * Copyright 1997 by Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+/*
+ * This function returns 1 if the inode's block entries actually
+ * contain block entries.
+ */
+int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
+{
+ /*
+ * Only directories, regular files, and some symbolic links
+ * have valid block entries.
+ */
+ if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
+ !LINUX_S_ISLNK(inode->i_mode))
+ return 0;
+
+ /*
+ * If the symbolic link is a "fast symlink", then the symlink
+ * target is stored in the block entries.
+ */
+ if (LINUX_S_ISLNK (inode->i_mode) && inode->i_blocks == 0 &&
+ inode->i_size < EXT2_N_BLOCKS * sizeof (unsigned long))
+ return 0;
+
+ return 1;
+}
diff --git a/lib/ss/ChangeLog b/lib/ss/ChangeLog
index 2aca3d92..e5467a01 100644
--- a/lib/ss/ChangeLog
+++ b/lib/ss/ChangeLog
@@ -1,3 +1,20 @@
+Wed Mar 12 13:32:05 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * Release of E2fsprogs version 1.07
+
+Wed Mar 12 21:54:32 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * help.c, pager.c, ss.h: Don't use "extern int errno", but use
+ #include <errno.h> instead.
+
+Thu Jan 2 00:16:03 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * parse.c: Put in an include of string.h
+
+Tue Oct 8 02:02:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.06
+
Thu Sep 12 15:23:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.05
diff --git a/lib/ss/Makefile.in b/lib/ss/Makefile.in
index 777c34bb..d3b6bf4b 100644
--- a/lib/ss/Makefile.in
+++ b/lib/ss/Makefile.in
@@ -29,6 +29,7 @@ ELF_SO_VERSION = 2
ELF_IMAGE = libss
ELF_MYDIR = ss
ELF_INSTALL_DIR = $(libdir)
+ELF_OTHER_LIBS = -lc -L../.. -lcom_err
BSDLIB_VERSION = 1.0
BSDLIB_IMAGE = libss
@@ -46,7 +47,7 @@ XTRA_CFLAGS=-DPOSIX_SIGNALS -I$(srcdir)/../et
.c.o:
$(CC) $(ALL_CFLAGS) -c $<
-@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
@CHECKER_CMT@ $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
@DLL_CMT@ (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) \
@DLL_CMT@ $(ALL_CFLAGS) -o jump/$*.o -c $<)
diff --git a/lib/ss/help.c b/lib/ss/help.c
index 3f3c7f53..5a17164c 100644
--- a/lib/ss/help.c
+++ b/lib/ss/help.c
@@ -10,6 +10,11 @@
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
#include <fcntl.h>
#include <sys/param.h>
#include <sys/types.h>
@@ -22,8 +27,6 @@
#include "ss_internal.h"
#include "copyright.h"
-extern int errno;
-
void ss_help (argc, argv, sci_idx, info_ptr)
int argc;
char const * const *argv;
diff --git a/lib/ss/pager.c b/lib/ss/pager.c
index bc5c9b52..1a707738 100644
--- a/lib/ss/pager.c
+++ b/lib/ss/pager.c
@@ -12,6 +12,8 @@
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
+#else
+extern int errno;
#endif
#include "ss_internal.h"
@@ -24,7 +26,6 @@
static char MORE[] = "more";
extern char *_ss_pager_name;
extern char *getenv();
-extern int errno;
/*
* this needs a *lot* of work....
diff --git a/lib/ss/parse.c b/lib/ss/parse.c
index 38b8e5bd..80175d3a 100644
--- a/lib/ss/parse.c
+++ b/lib/ss/parse.c
@@ -7,6 +7,7 @@
#ifdef HAS_STDLIB_H
#include <stdlib.h>
#endif
+#include <string.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/lib/ss/ss.h b/lib/ss/ss.h
index 3b86f87f..104e0388 100644
--- a/lib/ss/ss.h
+++ b/lib/ss/ss.h
@@ -10,8 +10,6 @@
#include <ss/copyright.h>
#include <ss/ss_err.h>
-extern int errno;
-
#ifdef __STDC__
#define __SS_CONST const
#define __SS_PROTO (int, const char * const *, int, void *)
diff --git a/lib/ss/test_ss.c b/lib/ss/test_ss.c
index a4601f6e..64f0e2a1 100644
--- a/lib/ss/test_ss.c
+++ b/lib/ss/test_ss.c
@@ -9,8 +9,8 @@
* $Locker$
*
* $Log$
- * Revision 1.9 1997/04/29 15:29:28 tytso
- * Checked in e2fsprogs 1.06
+ * Revision 1.10 1997/04/29 16:15:48 tytso
+ * Checked in e2fsprogs-1.07
*
* Revision 1.1 1993/06/03 12:31:25 tytso
* Initial revision
diff --git a/lib/uuid/ChangeLog b/lib/uuid/ChangeLog
index b276ddbf..67395752 100644
--- a/lib/uuid/ChangeLog
+++ b/lib/uuid/ChangeLog
@@ -1,3 +1,34 @@
+Wed Mar 12 13:32:05 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * Release of E2fsprogs version 1.07
+
+Sun Mar 2 16:45:36 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in (ELF_VERSION): Change version to be 1.1
+
+Thu Feb 6 23:08:07 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * gen_uuid.c (uuid_generate): Set Multicast bit when picking a
+ random node_id, to prevent conflicts with IEEE 802
+ addresses obtained from network cards.
+
+Wed Jan 1 23:51:09 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * unpack.c, pack.c: Include string.h, since we use memcpy().
+
+Tue Dec 3 13:05:11 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * parse.c: Add #include of ctype.h and stdlib.h, to pull in the
+ required prototypes.
+
+Fri Oct 11 17:15:10 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in (DLL_ADDRESS): Updated DLL address for libuuid.
+
+Tue Oct 8 02:02:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.06
+
Thu Sep 12 15:23:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.05
diff --git a/lib/uuid/Makefile.in b/lib/uuid/Makefile.in
index c226197e..a186f2ab 100644
--- a/lib/uuid/Makefile.in
+++ b/lib/uuid/Makefile.in
@@ -39,20 +39,21 @@ SRCS= $(srcdir)/clear.c \
LIBRARY= libuuid
LIBDIR= uuid
-DLL_ADDRESS = 0x66980000
+DLL_ADDRESS = 0x67900000
DLL_JUMPSIZE = 0x1000
DLL_GOTSIZE = 0x1000
-DLL_VERSION = 1.0
+DLL_VERSION = 0.0
DLL_IMAGE = libuuid
DLL_STUB = libuuid
DLL_MYDIR = uuid
DLL_INSTALL_DIR = $(libdir)
-ELF_VERSION = 1.0
+ELF_VERSION = 1.1
ELF_SO_VERSION = 1
ELF_IMAGE = libuuid
ELF_MYDIR = uuid
ELF_INSTALL_DIR = $(libdir)
+ELF_OTHER_LIBS = -lc
BSDLIB_VERSION = 1.0
BSDLIB_IMAGE = libuuid
@@ -68,7 +69,7 @@ BSDLIB_INSTALL_DIR = $(libdir)
.c.o:
$(CC) $(ALL_CFLAGS) -c $< -o $@
-@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
@CHECKER_CMT@ $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
@DLL_CMT@ (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
@DLL_CMT@ -o jump/$*.o -c $<)
@@ -77,6 +78,9 @@ BSDLIB_INSTALL_DIR = $(libdir)
all:: tst_uuid
+tst_uuid.o: $(srcdir)/tst_uuid.c
+ $(CC) $(ALL_CFLAGS) -c $(srcdir)/tst_uuid.c -o tst_uuid.o
+
tst_uuid: tst_uuid.o $(LIBUUID)
$(CC) $(ALL_LDFLAGS) -o tst_uuid tst_uuid.o $(LIBUUID)
diff --git a/lib/uuid/clear.c b/lib/uuid/clear.c
index 5127e016..32e26d4f 100644
--- a/lib/uuid/clear.c
+++ b/lib/uuid/clear.c
@@ -1,7 +1,16 @@
/*
* clear.c -- Clear a UUID
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
+#include "string.h"
+
#include "uuidP.h"
void uuid_clear(uuid_t uu)
diff --git a/lib/uuid/compare.c b/lib/uuid/compare.c
index 44052c3e..7bca4fa4 100644
--- a/lib/uuid/compare.c
+++ b/lib/uuid/compare.c
@@ -2,6 +2,13 @@
* compare.c --- compare whether or not two UUID's are the same
*
* Returns 0 if the two UUID's are different, and 1 if they are the same.
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include "uuidP.h"
diff --git a/lib/uuid/copy.c b/lib/uuid/copy.c
index 739e2ddb..5d0efc4a 100644
--- a/lib/uuid/copy.c
+++ b/lib/uuid/copy.c
@@ -1,5 +1,12 @@
/*
* copy.c --- copy UUIDs
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include "uuidP.h"
diff --git a/lib/uuid/dll/jump.funcs b/lib/uuid/dll/jump.funcs
new file mode 100644
index 00000000..cd75bb8f
--- /dev/null
+++ b/lib/uuid/dll/jump.funcs
@@ -0,0 +1,9 @@
+00000000 T _uuid_clear libuuid clear
+00000000 T _uuid_compare libuuid compare
+00000000 T _uuid_copy libuuid copy
+00000000 T _uuid_generate libuuid gen_uuid
+00000000 T _uuid_is_null libuuid isnull
+00000000 T _uuid_pack libuuid pack
+00000000 T _uuid_parse libuuid parse
+00000000 T _uuid_unpack libuuid unpack
+00000000 T _uuid_unparse libuuid unparse
diff --git a/lib/uuid/dll/jump.ignore b/lib/uuid/dll/jump.ignore
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/lib/uuid/dll/jump.ignore
diff --git a/lib/uuid/dll/jump.import b/lib/uuid/dll/jump.import
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/lib/uuid/dll/jump.import
diff --git a/lib/uuid/dll/jump.params b/lib/uuid/dll/jump.params
new file mode 100644
index 00000000..efd35138
--- /dev/null
+++ b/lib/uuid/dll/jump.params
@@ -0,0 +1,6 @@
+Name=libuuid
+Text=0x67900000
+Data=0x00000000
+Jump=0x00001000
+GOT=0x00001000
+Version=0.0.0
diff --git a/lib/uuid/dll/jump.undefs b/lib/uuid/dll/jump.undefs
new file mode 100644
index 00000000..1fa6c91f
--- /dev/null
+++ b/lib/uuid/dll/jump.undefs
@@ -0,0 +1 @@
+67903014 D __NEEDS_SHRLIB_libc_4
diff --git a/lib/uuid/dll/jump.vars b/lib/uuid/dll/jump.vars
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/lib/uuid/dll/jump.vars
diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
index 8eaab4af..a0c815b6 100644
--- a/lib/uuid/gen_uuid.c
+++ b/lib/uuid/gen_uuid.c
@@ -1,5 +1,12 @@
/*
* gen_uuid.c --- generate a DCE-compatible uuid
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#ifdef HAVE_UNISTD_H
@@ -185,8 +192,15 @@ void uuid_generate(uuid_t out)
__u32 clock_mid;
if (!has_init) {
- if (get_node_id(node_id) <= 0)
+ if (get_node_id(node_id) <= 0) {
get_random_bytes(node_id, 6);
+ /*
+ * Set multicast bit, to prevent conflicts
+ * with IEEE 802 addresses obtained from
+ * network cards
+ */
+ node_id[0] |= 0x80;
+ }
has_init = 1;
}
get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
diff --git a/lib/uuid/isnull.c b/lib/uuid/isnull.c
index f72e8fba..43b81f87 100644
--- a/lib/uuid/isnull.c
+++ b/lib/uuid/isnull.c
@@ -1,5 +1,12 @@
/*
* isnull.c --- Check whether or not the UUID is null
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include "uuidP.h"
diff --git a/lib/uuid/pack.c b/lib/uuid/pack.c
index 476b7a17..c4d03c8c 100644
--- a/lib/uuid/pack.c
+++ b/lib/uuid/pack.c
@@ -1,7 +1,15 @@
/*
* Internal routine for packing UUID's
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
+#include <string.h>
#include "uuidP.h"
void uuid_pack(struct uuid *uu, uuid_t ptr)
diff --git a/lib/uuid/parse.c b/lib/uuid/parse.c
index ce3f88db..580c1fc2 100644
--- a/lib/uuid/parse.c
+++ b/lib/uuid/parse.c
@@ -1,8 +1,17 @@
/*
* parse.c --- UUID parsing
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
+#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include "uuidP.h"
diff --git a/lib/uuid/tst_uuid.c b/lib/uuid/tst_uuid.c
index 068eea8d..c60e9f81 100644
--- a/lib/uuid/tst_uuid.c
+++ b/lib/uuid/tst_uuid.c
@@ -1,3 +1,14 @@
+/*
+ * tst_uuid.c --- test program from the UUID library
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
#include <stdio.h>
#include <linux/ext2_fs.h>
diff --git a/lib/uuid/unpack.c b/lib/uuid/unpack.c
index 406587d5..97a9dd84 100644
--- a/lib/uuid/unpack.c
+++ b/lib/uuid/unpack.c
@@ -1,7 +1,15 @@
/*
* Internal routine for unpacking UUID
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
+#include <string.h>
#include "uuidP.h"
void uuid_unpack(uuid_t in, struct uuid *uu)
diff --git a/lib/uuid/unparse.c b/lib/uuid/unparse.c
index 32f79955..ab904bc1 100644
--- a/lib/uuid/unparse.c
+++ b/lib/uuid/unparse.c
@@ -1,5 +1,12 @@
/*
- * uuid_to_str.c -- convert a UUID to string
+ * unparse.c -- convert a UUID to string
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <stdio.h>
diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h
index 9568c03f..08f924c2 100644
--- a/lib/uuid/uuid.h
+++ b/lib/uuid/uuid.h
@@ -1,5 +1,12 @@
/*
* Public include file for the UUID library
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
typedef unsigned char uuid_t[16];
diff --git a/lib/uuid/uuidP.h b/lib/uuid/uuidP.h
index 0ef92614..69f9af99 100644
--- a/lib/uuid/uuidP.h
+++ b/lib/uuid/uuidP.h
@@ -1,5 +1,12 @@
/*
* uuid.h -- private header file for uuids
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
#include <sys/types.h>