aboutsummaryrefslogtreecommitdiff
path: root/e2fsprogs/ext2fs
diff options
context:
space:
mode:
Diffstat (limited to 'e2fsprogs/ext2fs')
-rw-r--r--e2fsprogs/ext2fs/Kbuild23
-rw-r--r--e2fsprogs/ext2fs/alloc.c174
-rw-r--r--e2fsprogs/ext2fs/alloc_sb.c58
-rw-r--r--e2fsprogs/ext2fs/alloc_stats.c53
-rw-r--r--e2fsprogs/ext2fs/alloc_tables.c118
-rw-r--r--e2fsprogs/ext2fs/badblocks.c328
-rw-r--r--e2fsprogs/ext2fs/bb_compat.c64
-rw-r--r--e2fsprogs/ext2fs/bb_inode.c268
-rw-r--r--e2fsprogs/ext2fs/bitmaps.c213
-rw-r--r--e2fsprogs/ext2fs/bitops.c91
-rw-r--r--e2fsprogs/ext2fs/bitops.h107
-rw-r--r--e2fsprogs/ext2fs/block.c438
-rw-r--r--e2fsprogs/ext2fs/bmap.c264
-rw-r--r--e2fsprogs/ext2fs/bmove.c156
-rw-r--r--e2fsprogs/ext2fs/brel.h87
-rw-r--r--e2fsprogs/ext2fs/brel_ma.c196
-rw-r--r--e2fsprogs/ext2fs/check_desc.c69
-rw-r--r--e2fsprogs/ext2fs/closefs.c381
-rw-r--r--e2fsprogs/ext2fs/cmp_bitmaps.c73
-rw-r--r--e2fsprogs/ext2fs/dblist.c260
-rw-r--r--e2fsprogs/ext2fs/dblist_dir.c76
-rw-r--r--e2fsprogs/ext2fs/dir_iterate.c220
-rw-r--r--e2fsprogs/ext2fs/dirblock.c133
-rw-r--r--e2fsprogs/ext2fs/dirhash.c234
-rw-r--r--e2fsprogs/ext2fs/dupfs.c97
-rw-r--r--e2fsprogs/ext2fs/e2image.h52
-rw-r--r--e2fsprogs/ext2fs/expanddir.c127
-rw-r--r--e2fsprogs/ext2fs/ext2_err.h116
-rw-r--r--e2fsprogs/ext2fs/ext2_ext_attr.h53
-rw-r--r--e2fsprogs/ext2fs/ext2_fs.h570
-rw-r--r--e2fsprogs/ext2fs/ext2_io.h114
-rw-r--r--e2fsprogs/ext2fs/ext2_types.h2
-rw-r--r--e2fsprogs/ext2fs/ext2fs.h923
-rw-r--r--e2fsprogs/ext2fs/ext2fsP.h89
-rw-r--r--e2fsprogs/ext2fs/ext2fs_inline.c367
-rw-r--r--e2fsprogs/ext2fs/ext_attr.c101
-rw-r--r--e2fsprogs/ext2fs/fileio.c377
-rw-r--r--e2fsprogs/ext2fs/finddev.c199
-rw-r--r--e2fsprogs/ext2fs/flushb.c83
-rw-r--r--e2fsprogs/ext2fs/freefs.c128
-rw-r--r--e2fsprogs/ext2fs/gen_bitmap.c49
-rw-r--r--e2fsprogs/ext2fs/get_pathname.c157
-rw-r--r--e2fsprogs/ext2fs/getsectsize.c58
-rw-r--r--e2fsprogs/ext2fs/getsize.c291
-rw-r--r--e2fsprogs/ext2fs/icount.c467
-rw-r--r--e2fsprogs/ext2fs/imager.c377
-rw-r--r--e2fsprogs/ext2fs/ind_block.c71
-rw-r--r--e2fsprogs/ext2fs/initialize.c388
-rw-r--r--e2fsprogs/ext2fs/inline.c33
-rw-r--r--e2fsprogs/ext2fs/inode.c768
-rw-r--r--e2fsprogs/ext2fs/inode_io.c271
-rw-r--r--e2fsprogs/ext2fs/io_manager.c70
-rw-r--r--e2fsprogs/ext2fs/irel.h115
-rw-r--r--e2fsprogs/ext2fs/irel_ma.c367
-rw-r--r--e2fsprogs/ext2fs/ismounted.c357
-rw-r--r--e2fsprogs/ext2fs/jfs_dat.h65
-rw-r--r--e2fsprogs/ext2fs/kernel-jbd.h236
-rw-r--r--e2fsprogs/ext2fs/kernel-list.h113
-rw-r--r--e2fsprogs/ext2fs/link.c135
-rw-r--r--e2fsprogs/ext2fs/lookup.c70
-rw-r--r--e2fsprogs/ext2fs/mkdir.c142
-rw-r--r--e2fsprogs/ext2fs/mkjournal.c428
-rw-r--r--e2fsprogs/ext2fs/namei.c205
-rw-r--r--e2fsprogs/ext2fs/newdir.c73
-rw-r--r--e2fsprogs/ext2fs/openfs.c330
-rw-r--r--e2fsprogs/ext2fs/read_bb.c98
-rw-r--r--e2fsprogs/ext2fs/read_bb_file.c98
-rw-r--r--e2fsprogs/ext2fs/res_gdt.c221
-rw-r--r--e2fsprogs/ext2fs/rs_bitmap.c107
-rw-r--r--e2fsprogs/ext2fs/rw_bitmaps.c296
-rw-r--r--e2fsprogs/ext2fs/sparse.c79
-rw-r--r--e2fsprogs/ext2fs/swapfs.c236
-rw-r--r--e2fsprogs/ext2fs/test_io.c380
-rw-r--r--e2fsprogs/ext2fs/unix_io.c703
-rw-r--r--e2fsprogs/ext2fs/unlink.c100
-rw-r--r--e2fsprogs/ext2fs/valid_blk.c57
-rw-r--r--e2fsprogs/ext2fs/version.c51
-rw-r--r--e2fsprogs/ext2fs/write_bb_file.c35
78 files changed, 0 insertions, 15579 deletions
diff --git a/e2fsprogs/ext2fs/Kbuild b/e2fsprogs/ext2fs/Kbuild
deleted file mode 100644
index 185887a44..000000000
--- a/e2fsprogs/ext2fs/Kbuild
+++ /dev/null
@@ -1,23 +0,0 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
4#
5# Licensed under the GPL v2, see the file LICENSE in this tarball.
6
7NEEDED-$(CONFIG_E2FSCK) = y
8NEEDED-$(CONFIG_FSCK) = y
9NEEDED-$(CONFIG_MKE2FS) = y
10NEEDED-$(CONFIG_TUNE2FS) = y
11
12lib-y:=
13lib-$(NEEDED-y) += gen_bitmap.o bitops.o ismounted.o mkjournal.o unix_io.o \
14 rw_bitmaps.o initialize.o bitmaps.o block.o \
15 ind_block.o inode.o freefs.o alloc_stats.o closefs.o \
16 openfs.o io_manager.o finddev.o read_bb.o alloc.o badblocks.o \
17 getsize.o getsectsize.o alloc_tables.o read_bb_file.o mkdir.o \
18 bb_inode.o newdir.o alloc_sb.o lookup.o dirblock.o expanddir.o \
19 dir_iterate.o link.o res_gdt.o icount.o get_pathname.o dblist.o \
20 dirhash.o version.o flushb.o unlink.o check_desc.o valid_blk.o \
21 ext_attr.o bmap.o dblist_dir.o ext2fs_inline.o swapfs.o
22
23CFLAGS += -include $(srctree)/e2fsprogs/e2fsbb.h
diff --git a/e2fsprogs/ext2fs/alloc.c b/e2fsprogs/ext2fs/alloc.c
deleted file mode 100644
index 590f23a7e..000000000
--- a/e2fsprogs/ext2fs/alloc.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * alloc.c --- allocate new inodes, blocks for ext2fs
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 */
13
14#include <stdio.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <time.h>
19#include <string.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30/*
31 * Right now, just search forward from the parent directory's block
32 * group to find the next free inode.
33 *
34 * Should have a special policy for directories.
35 */
36errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir,
37 int mode EXT2FS_ATTR((unused)),
38 ext2fs_inode_bitmap map, ext2_ino_t *ret)
39{
40 ext2_ino_t dir_group = 0;
41 ext2_ino_t i;
42 ext2_ino_t start_inode;
43
44 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
45
46 if (!map)
47 map = fs->inode_map;
48 if (!map)
49 return EXT2_ET_NO_INODE_BITMAP;
50
51 if (dir > 0)
52 dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
53
54 start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
55 if (start_inode < EXT2_FIRST_INODE(fs->super))
56 start_inode = EXT2_FIRST_INODE(fs->super);
57 i = start_inode;
58
59 do {
60 if (!ext2fs_fast_test_inode_bitmap(map, i))
61 break;
62 i++;
63 if (i > fs->super->s_inodes_count)
64 i = EXT2_FIRST_INODE(fs->super);
65 } while (i != start_inode);
66
67 if (ext2fs_test_inode_bitmap(map, i))
68 return EXT2_ET_INODE_ALLOC_FAIL;
69 *ret = i;
70 return 0;
71}
72
73/*
74 * Stupid algorithm --- we now just search forward starting from the
75 * goal. Should put in a smarter one someday....
76 */
77errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
78 ext2fs_block_bitmap map, blk_t *ret)
79{
80 blk_t i;
81
82 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
83
84 if (!map)
85 map = fs->block_map;
86 if (!map)
87 return EXT2_ET_NO_BLOCK_BITMAP;
88 if (!goal || (goal >= fs->super->s_blocks_count))
89 goal = fs->super->s_first_data_block;
90 i = goal;
91 do {
92 if (!ext2fs_fast_test_block_bitmap(map, i)) {
93 *ret = i;
94 return 0;
95 }
96 i++;
97 if (i >= fs->super->s_blocks_count)
98 i = fs->super->s_first_data_block;
99 } while (i != goal);
100 return EXT2_ET_BLOCK_ALLOC_FAIL;
101}
102
103/*
104 * This function zeros out the allocated block, and updates all of the
105 * appropriate filesystem records.
106 */
107errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
108 char *block_buf, blk_t *ret)
109{
110 errcode_t retval;
111 blk_t block;
112 char *buf = 0;
113
114 if (!block_buf) {
115 retval = ext2fs_get_mem(fs->blocksize, &buf);
116 if (retval)
117 return retval;
118 block_buf = buf;
119 }
120 memset(block_buf, 0, fs->blocksize);
121
122 if (!fs->block_map) {
123 retval = ext2fs_read_block_bitmap(fs);
124 if (retval)
125 goto fail;
126 }
127
128 retval = ext2fs_new_block(fs, goal, 0, &block);
129 if (retval)
130 goto fail;
131
132 retval = io_channel_write_blk(fs->io, block, 1, block_buf);
133 if (retval)
134 goto fail;
135
136 ext2fs_block_alloc_stats(fs, block, +1);
137 *ret = block;
138 return 0;
139
140fail:
141 if (buf)
142 ext2fs_free_mem(&buf);
143 return retval;
144}
145
146errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
147 int num, ext2fs_block_bitmap map, blk_t *ret)
148{
149 blk_t b = start;
150
151 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
152
153 if (!map)
154 map = fs->block_map;
155 if (!map)
156 return EXT2_ET_NO_BLOCK_BITMAP;
157 if (!b)
158 b = fs->super->s_first_data_block;
159 if (!finish)
160 finish = start;
161 if (!num)
162 num = 1;
163 do {
164 if (b+num-1 > fs->super->s_blocks_count)
165 b = fs->super->s_first_data_block;
166 if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
167 *ret = b;
168 return 0;
169 }
170 b++;
171 } while (b != finish);
172 return EXT2_ET_BLOCK_ALLOC_FAIL;
173}
174
diff --git a/e2fsprogs/ext2fs/alloc_sb.c b/e2fsprogs/ext2fs/alloc_sb.c
deleted file mode 100644
index a7437c96f..000000000
--- a/e2fsprogs/ext2fs/alloc_sb.c
+++ /dev/null
@@ -1,58 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * alloc_sb.c --- Allocate the superblock and block group descriptors for a
4 * newly initialized filesystem. Used by mke2fs when initializing a filesystem
5 *
6 * Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <fcntl.h>
20#include <time.h>
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
32 dgrp_t group,
33 ext2fs_block_bitmap bmap)
34{
35 blk_t super_blk, old_desc_blk, new_desc_blk;
36 int j, old_desc_blocks, num_blocks;
37
38 num_blocks = ext2fs_super_and_bgd_loc(fs, group, &super_blk,
39 &old_desc_blk, &new_desc_blk, 0);
40
41 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
42 old_desc_blocks = fs->super->s_first_meta_bg;
43 else
44 old_desc_blocks =
45 fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
46
47 if (super_blk || (group == 0))
48 ext2fs_mark_block_bitmap(bmap, super_blk);
49
50 if (old_desc_blk) {
51 for (j=0; j < old_desc_blocks; j++)
52 ext2fs_mark_block_bitmap(bmap, old_desc_blk + j);
53 }
54 if (new_desc_blk)
55 ext2fs_mark_block_bitmap(bmap, new_desc_blk);
56
57 return num_blocks;
58}
diff --git a/e2fsprogs/ext2fs/alloc_stats.c b/e2fsprogs/ext2fs/alloc_stats.c
deleted file mode 100644
index f3ab06a23..000000000
--- a/e2fsprogs/ext2fs/alloc_stats.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * alloc_stats.c --- Update allocation statistics for ext2fs
4 *
5 * Copyright (C) 2001 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 */
13
14#include <stdio.h>
15
16#include "ext2_fs.h"
17#include "ext2fs.h"
18
19void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
20 int inuse, int isdir)
21{
22 int group = ext2fs_group_of_ino(fs, ino);
23
24 if (inuse > 0)
25 ext2fs_mark_inode_bitmap(fs->inode_map, ino);
26 else
27 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
28 fs->group_desc[group].bg_free_inodes_count -= inuse;
29 if (isdir)
30 fs->group_desc[group].bg_used_dirs_count += inuse;
31 fs->super->s_free_inodes_count -= inuse;
32 ext2fs_mark_super_dirty(fs);
33 ext2fs_mark_ib_dirty(fs);
34}
35
36void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse)
37{
38 ext2fs_inode_alloc_stats2(fs, ino, inuse, 0);
39}
40
41void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
42{
43 int group = ext2fs_group_of_blk(fs, blk);
44
45 if (inuse > 0)
46 ext2fs_mark_block_bitmap(fs->block_map, blk);
47 else
48 ext2fs_unmark_block_bitmap(fs->block_map, blk);
49 fs->group_desc[group].bg_free_blocks_count -= inuse;
50 fs->super->s_free_blocks_count -= inuse;
51 ext2fs_mark_super_dirty(fs);
52 ext2fs_mark_bb_dirty(fs);
53}
diff --git a/e2fsprogs/ext2fs/alloc_tables.c b/e2fsprogs/ext2fs/alloc_tables.c
deleted file mode 100644
index b2d786ed8..000000000
--- a/e2fsprogs/ext2fs/alloc_tables.c
+++ /dev/null
@@ -1,118 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * alloc_tables.c --- Allocate tables for a newly initialized
4 * filesystem. Used by mke2fs when initializing a filesystem
5 *
6 * Copyright (C) 1996 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <fcntl.h>
20#include <time.h>
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
32 ext2fs_block_bitmap bmap)
33{
34 errcode_t retval;
35 blk_t group_blk, start_blk, last_blk, new_blk, blk;
36 int j;
37
38 group_blk = fs->super->s_first_data_block +
39 (group * fs->super->s_blocks_per_group);
40
41 last_blk = group_blk + fs->super->s_blocks_per_group;
42 if (last_blk >= fs->super->s_blocks_count)
43 last_blk = fs->super->s_blocks_count - 1;
44
45 if (!bmap)
46 bmap = fs->block_map;
47
48 /*
49 * Allocate the block and inode bitmaps, if necessary
50 */
51 if (fs->stride) {
52 start_blk = group_blk + fs->inode_blocks_per_group;
53 start_blk += ((fs->stride * group) %
54 (last_blk - start_blk));
55 if (start_blk > last_blk)
56 start_blk = group_blk;
57 } else
58 start_blk = group_blk;
59
60 if (!fs->group_desc[group].bg_block_bitmap) {
61 retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
62 1, bmap, &new_blk);
63 if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
64 retval = ext2fs_get_free_blocks(fs, group_blk,
65 last_blk, 1, bmap, &new_blk);
66 if (retval)
67 return retval;
68 ext2fs_mark_block_bitmap(bmap, new_blk);
69 fs->group_desc[group].bg_block_bitmap = new_blk;
70 }
71
72 if (!fs->group_desc[group].bg_inode_bitmap) {
73 retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
74 1, bmap, &new_blk);
75 if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
76 retval = ext2fs_get_free_blocks(fs, group_blk,
77 last_blk, 1, bmap, &new_blk);
78 if (retval)
79 return retval;
80 ext2fs_mark_block_bitmap(bmap, new_blk);
81 fs->group_desc[group].bg_inode_bitmap = new_blk;
82 }
83
84 /*
85 * Allocate the inode table
86 */
87 if (!fs->group_desc[group].bg_inode_table) {
88 retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
89 fs->inode_blocks_per_group,
90 bmap, &new_blk);
91 if (retval)
92 return retval;
93 for (j=0, blk = new_blk;
94 j < fs->inode_blocks_per_group;
95 j++, blk++)
96 ext2fs_mark_block_bitmap(bmap, blk);
97 fs->group_desc[group].bg_inode_table = new_blk;
98 }
99
100
101 return 0;
102}
103
104
105
106errcode_t ext2fs_allocate_tables(ext2_filsys fs)
107{
108 errcode_t retval;
109 dgrp_t i;
110
111 for (i = 0; i < fs->group_desc_count; i++) {
112 retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
113 if (retval)
114 return retval;
115 }
116 return 0;
117}
118
diff --git a/e2fsprogs/ext2fs/badblocks.c b/e2fsprogs/ext2fs/badblocks.c
deleted file mode 100644
index 7804396d7..000000000
--- a/e2fsprogs/ext2fs/badblocks.c
+++ /dev/null
@@ -1,328 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * badblocks.c --- routines to manipulate the bad block structure
4 *
5 * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fsP.h"
29
30/*
31 * Helper function for making a badblocks list
32 */
33static errcode_t make_u32_list(int size, int num, __u32 *list,
34 ext2_u32_list *ret)
35{
36 ext2_u32_list bb;
37 errcode_t retval;
38
39 retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
40 if (retval)
41 return retval;
42 memset(bb, 0, sizeof(struct ext2_struct_u32_list));
43 bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
44 bb->size = size ? size : 10;
45 bb->num = num;
46 retval = ext2fs_get_mem(bb->size * sizeof(blk_t), &bb->list);
47 if (!bb->list) {
48 ext2fs_free_mem(&bb);
49 return retval;
50 }
51 if (list)
52 memcpy(bb->list, list, bb->size * sizeof(blk_t));
53 else
54 memset(bb->list, 0, bb->size * sizeof(blk_t));
55 *ret = bb;
56 return 0;
57}
58
59
60/*
61 * This procedure creates an empty u32 list.
62 */
63errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
64{
65 return make_u32_list(size, 0, 0, ret);
66}
67
68/*
69 * This procedure creates an empty badblocks list.
70 */
71errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
72{
73 return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
74}
75
76
77/*
78 * This procedure copies a badblocks list
79 */
80errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
81{
82 errcode_t retval;
83
84 retval = make_u32_list(src->size, src->num, src->list, dest);
85 if (retval)
86 return retval;
87 (*dest)->badblocks_flags = src->badblocks_flags;
88 return 0;
89}
90
91errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
92 ext2_badblocks_list *dest)
93{
94 return ext2fs_u32_copy((ext2_u32_list) src,
95 (ext2_u32_list *) dest);
96}
97
98/*
99 * This procedure frees a badblocks list.
100 *
101 * (note: moved to closefs.c)
102 */
103
104
105/*
106 * This procedure adds a block to a badblocks list.
107 */
108errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
109{
110 errcode_t retval;
111 int i, j;
112 unsigned long old_size;
113
114 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
115
116 if (bb->num >= bb->size) {
117 old_size = bb->size * sizeof(__u32);
118 bb->size += 100;
119 retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
120 &bb->list);
121 if (retval) {
122 bb->size -= 100;
123 return retval;
124 }
125 }
126
127 /*
128 * Add special case code for appending to the end of the list
129 */
130 i = bb->num-1;
131 if ((bb->num != 0) && (bb->list[i] == blk))
132 return 0;
133 if ((bb->num == 0) || (bb->list[i] < blk)) {
134 bb->list[bb->num++] = blk;
135 return 0;
136 }
137
138 j = bb->num;
139 for (i=0; i < bb->num; i++) {
140 if (bb->list[i] == blk)
141 return 0;
142 if (bb->list[i] > blk) {
143 j = i;
144 break;
145 }
146 }
147 for (i=bb->num; i > j; i--)
148 bb->list[i] = bb->list[i-1];
149 bb->list[j] = blk;
150 bb->num++;
151 return 0;
152}
153
154errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
155{
156 return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
157}
158
159/*
160 * This procedure finds a particular block is on a badblocks
161 * list.
162 */
163int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
164{
165 int low, high, mid;
166
167 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
168 return -1;
169
170 if (bb->num == 0)
171 return -1;
172
173 low = 0;
174 high = bb->num-1;
175 if (blk == bb->list[low])
176 return low;
177 if (blk == bb->list[high])
178 return high;
179
180 while (low < high) {
181 mid = (low+high)/2;
182 if (mid == low || mid == high)
183 break;
184 if (blk == bb->list[mid])
185 return mid;
186 if (blk < bb->list[mid])
187 high = mid;
188 else
189 low = mid;
190 }
191 return -1;
192}
193
194/*
195 * This procedure tests to see if a particular block is on a badblocks
196 * list.
197 */
198int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
199{
200 if (ext2fs_u32_list_find(bb, blk) < 0)
201 return 0;
202 else
203 return 1;
204}
205
206int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
207{
208 return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
209}
210
211
212/*
213 * Remove a block from the badblock list
214 */
215int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
216{
217 int remloc, i;
218
219 if (bb->num == 0)
220 return -1;
221
222 remloc = ext2fs_u32_list_find(bb, blk);
223 if (remloc < 0)
224 return -1;
225
226 for (i = remloc ; i < bb->num-1; i++)
227 bb->list[i] = bb->list[i+1];
228 bb->num--;
229 return 0;
230}
231
232void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
233{
234 ext2fs_u32_list_del(bb, blk);
235}
236
237errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
238 ext2_u32_iterate *ret)
239{
240 ext2_u32_iterate iter;
241 errcode_t retval;
242
243 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
244
245 retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
246 if (retval)
247 return retval;
248
249 iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
250 iter->bb = bb;
251 iter->ptr = 0;
252 *ret = iter;
253 return 0;
254}
255
256errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
257 ext2_badblocks_iterate *ret)
258{
259 return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
260 (ext2_u32_iterate *) ret);
261}
262
263
264int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
265{
266 ext2_u32_list bb;
267
268 if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
269 return 0;
270
271 bb = iter->bb;
272
273 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
274 return 0;
275
276 if (iter->ptr < bb->num) {
277 *blk = bb->list[iter->ptr++];
278 return 1;
279 }
280 *blk = 0;
281 return 0;
282}
283
284int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
285{
286 return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
287 (__u32 *) blk);
288}
289
290
291void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
292{
293 if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
294 return;
295
296 iter->bb = 0;
297 ext2fs_free_mem(&iter);
298}
299
300void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
301{
302 ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
303}
304
305
306int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
307{
308 EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
309 EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
310
311 if (bb1->num != bb2->num)
312 return 0;
313
314 if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
315 return 0;
316 return 1;
317}
318
319int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
320{
321 return ext2fs_u32_list_equal((ext2_u32_list) bb1,
322 (ext2_u32_list) bb2);
323}
324
325int ext2fs_u32_list_count(ext2_u32_list bb)
326{
327 return bb->num;
328}
diff --git a/e2fsprogs/ext2fs/bb_compat.c b/e2fsprogs/ext2fs/bb_compat.c
deleted file mode 100644
index 419ac7785..000000000
--- a/e2fsprogs/ext2fs/bb_compat.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bb_compat.c --- compatibility badblocks routines
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fsP.h"
29
30errcode_t badblocks_list_create(badblocks_list *ret, int size)
31{
32 return ext2fs_badblocks_list_create(ret, size);
33}
34
35void badblocks_list_free(badblocks_list bb)
36{
37 ext2fs_badblocks_list_free(bb);
38}
39
40errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
41{
42 return ext2fs_badblocks_list_add(bb, blk);
43}
44
45int badblocks_list_test(badblocks_list bb, blk_t blk)
46{
47 return ext2fs_badblocks_list_test(bb, blk);
48}
49
50errcode_t badblocks_list_iterate_begin(badblocks_list bb,
51 badblocks_iterate *ret)
52{
53 return ext2fs_badblocks_list_iterate_begin(bb, ret);
54}
55
56int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
57{
58 return ext2fs_badblocks_list_iterate(iter, blk);
59}
60
61void badblocks_list_iterate_end(badblocks_iterate iter)
62{
63 ext2fs_badblocks_list_iterate_end(iter);
64}
diff --git a/e2fsprogs/ext2fs/bb_inode.c b/e2fsprogs/ext2fs/bb_inode.c
deleted file mode 100644
index 855f86eac..000000000
--- a/e2fsprogs/ext2fs/bb_inode.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bb_inode.c --- routines to update the bad block inode.
4 *
5 * WARNING: This routine modifies a lot of state in the filesystem; if
6 * this routine returns an error, the bad block inode may be in an
7 * inconsistent state.
8 *
9 * Copyright (C) 1994, 1995 Theodore Ts'o.
10 *
11 * %Begin-Header%
12 * This file may be redistributed under the terms of the GNU Public
13 * License.
14 * %End-Header%
15 */
16
17#include <stdio.h>
18#include <string.h>
19#if HAVE_UNISTD_H
20#include <unistd.h>
21#endif
22#include <fcntl.h>
23#include <time.h>
24#if HAVE_SYS_STAT_H
25#include <sys/stat.h>
26#endif
27#if HAVE_SYS_TYPES_H
28#include <sys/types.h>
29#endif
30
31#include "ext2_fs.h"
32#include "ext2fs.h"
33
34struct set_badblock_record {
35 ext2_badblocks_iterate bb_iter;
36 int bad_block_count;
37 blk_t *ind_blocks;
38 int max_ind_blocks;
39 int ind_blocks_size;
40 int ind_blocks_ptr;
41 char *block_buf;
42 errcode_t err;
43};
44
45static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
46 e2_blkcnt_t blockcnt,
47 blk_t ref_block, int ref_offset,
48 void *priv_data);
49static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
50 e2_blkcnt_t blockcnt,
51 blk_t ref_block, int ref_offset,
52 void *priv_data);
53
54/*
55 * Given a bad blocks bitmap, update the bad blocks inode to reflect
56 * the map.
57 */
58errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
59{
60 errcode_t retval;
61 struct set_badblock_record rec;
62 struct ext2_inode inode;
63
64 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
65
66 if (!fs->block_map)
67 return EXT2_ET_NO_BLOCK_BITMAP;
68
69 rec.bad_block_count = 0;
70 rec.ind_blocks_size = rec.ind_blocks_ptr = 0;
71 rec.max_ind_blocks = 10;
72 retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t),
73 &rec.ind_blocks);
74 if (retval)
75 return retval;
76 memset(rec.ind_blocks, 0, rec.max_ind_blocks * sizeof(blk_t));
77 retval = ext2fs_get_mem(fs->blocksize, &rec.block_buf);
78 if (retval)
79 goto cleanup;
80 memset(rec.block_buf, 0, fs->blocksize);
81 rec.err = 0;
82
83 /*
84 * First clear the old bad blocks (while saving the indirect blocks)
85 */
86 retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
87 BLOCK_FLAG_DEPTH_TRAVERSE, 0,
88 clear_bad_block_proc, &rec);
89 if (retval)
90 goto cleanup;
91 if (rec.err) {
92 retval = rec.err;
93 goto cleanup;
94 }
95
96 /*
97 * Now set the bad blocks!
98 *
99 * First, mark the bad blocks as used. This prevents a bad
100 * block from being used as an indirecto block for the bad
101 * block inode (!).
102 */
103 if (bb_list) {
104 retval = ext2fs_badblocks_list_iterate_begin(bb_list,
105 &rec.bb_iter);
106 if (retval)
107 goto cleanup;
108 retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
109 BLOCK_FLAG_APPEND, 0,
110 set_bad_block_proc, &rec);
111 ext2fs_badblocks_list_iterate_end(rec.bb_iter);
112 if (retval)
113 goto cleanup;
114 if (rec.err) {
115 retval = rec.err;
116 goto cleanup;
117 }
118 }
119
120 /*
121 * Update the bad block inode's mod time and block count
122 * field.
123 */
124 retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
125 if (retval)
126 goto cleanup;
127
128 inode.i_atime = inode.i_mtime = time(0);
129 if (!inode.i_ctime)
130 inode.i_ctime = time(0);
131 inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
132 inode.i_size = rec.bad_block_count * fs->blocksize;
133
134 retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
135 if (retval)
136 goto cleanup;
137
138cleanup:
139 ext2fs_free_mem(&rec.ind_blocks);
140 ext2fs_free_mem(&rec.block_buf);
141 return retval;
142}
143
144/*
145 * Helper function for update_bb_inode()
146 *
147 * Clear the bad blocks in the bad block inode, while saving the
148 * indirect blocks.
149 */
150#ifdef __TURBOC__
151# pragma argsused
152#endif
153static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
154 e2_blkcnt_t blockcnt,
155 blk_t ref_block EXT2FS_ATTR((unused)),
156 int ref_offset EXT2FS_ATTR((unused)),
157 void *priv_data)
158{
159 struct set_badblock_record *rec = (struct set_badblock_record *)
160 priv_data;
161 errcode_t retval;
162 unsigned long old_size;
163
164 if (!*block_nr)
165 return 0;
166
167 /*
168 * If the block number is outrageous, clear it and ignore it.
169 */
170 if (*block_nr >= fs->super->s_blocks_count ||
171 *block_nr < fs->super->s_first_data_block) {
172 *block_nr = 0;
173 return BLOCK_CHANGED;
174 }
175
176 if (blockcnt < 0) {
177 if (rec->ind_blocks_size >= rec->max_ind_blocks) {
178 old_size = rec->max_ind_blocks * sizeof(blk_t);
179 rec->max_ind_blocks += 10;
180 retval = ext2fs_resize_mem(old_size,
181 rec->max_ind_blocks * sizeof(blk_t),
182 &rec->ind_blocks);
183 if (retval) {
184 rec->max_ind_blocks -= 10;
185 rec->err = retval;
186 return BLOCK_ABORT;
187 }
188 }
189 rec->ind_blocks[rec->ind_blocks_size++] = *block_nr;
190 }
191
192 /*
193 * Mark the block as unused, and update accounting information
194 */
195 ext2fs_block_alloc_stats(fs, *block_nr, -1);
196
197 *block_nr = 0;
198 return BLOCK_CHANGED;
199}
200
201
202/*
203 * Helper function for update_bb_inode()
204 *
205 * Set the block list in the bad block inode, using the supplied bitmap.
206 */
207#ifdef __TURBOC__
208 #pragma argsused
209#endif
210static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
211 e2_blkcnt_t blockcnt,
212 blk_t ref_block EXT2FS_ATTR((unused)),
213 int ref_offset EXT2FS_ATTR((unused)),
214 void *priv_data)
215{
216 struct set_badblock_record *rec = (struct set_badblock_record *)
217 priv_data;
218 errcode_t retval;
219 blk_t blk;
220
221 if (blockcnt >= 0) {
222 /*
223 * Get the next bad block.
224 */
225 if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk))
226 return BLOCK_ABORT;
227 rec->bad_block_count++;
228 } else {
229 /*
230 * An indirect block; fetch a block from the
231 * previously used indirect block list. The block
232 * most be not marked as used; if so, get another one.
233 * If we run out of reserved indirect blocks, allocate
234 * a new one.
235 */
236 retry:
237 if (rec->ind_blocks_ptr < rec->ind_blocks_size) {
238 blk = rec->ind_blocks[rec->ind_blocks_ptr++];
239 if (ext2fs_test_block_bitmap(fs->block_map, blk))
240 goto retry;
241 } else {
242 retval = ext2fs_new_block(fs, 0, 0, &blk);
243 if (retval) {
244 rec->err = retval;
245 return BLOCK_ABORT;
246 }
247 }
248 retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf);
249 if (retval) {
250 rec->err = retval;
251 return BLOCK_ABORT;
252 }
253 }
254
255 /*
256 * Update block counts
257 */
258 ext2fs_block_alloc_stats(fs, blk, +1);
259
260 *block_nr = blk;
261 return BLOCK_CHANGED;
262}
263
264
265
266
267
268
diff --git a/e2fsprogs/ext2fs/bitmaps.c b/e2fsprogs/ext2fs/bitmaps.c
deleted file mode 100644
index 712a4a9b1..000000000
--- a/e2fsprogs/ext2fs/bitmaps.c
+++ /dev/null
@@ -1,213 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bitmaps.c --- routines to read, write, and manipulate the inode and
4 * block bitmaps.
5 *
6 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <fcntl.h>
20#include <time.h>
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
32 const char *descr, char *init_map,
33 ext2fs_generic_bitmap *ret)
34{
35 ext2fs_generic_bitmap bitmap;
36 errcode_t retval;
37 size_t size;
38
39 retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
40 &bitmap);
41 if (retval)
42 return retval;
43
44 bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
45 bitmap->fs = NULL;
46 bitmap->start = start;
47 bitmap->end = end;
48 bitmap->real_end = real_end;
49 bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
50 if (descr) {
51 retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
52 if (retval) {
53 ext2fs_free_mem(&bitmap);
54 return retval;
55 }
56 strcpy(bitmap->description, descr);
57 } else
58 bitmap->description = 0;
59
60 size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
61 retval = ext2fs_get_mem(size, &bitmap->bitmap);
62 if (retval) {
63 ext2fs_free_mem(&bitmap->description);
64 ext2fs_free_mem(&bitmap);
65 return retval;
66 }
67
68 if (init_map)
69 memcpy(bitmap->bitmap, init_map, size);
70 else
71 memset(bitmap->bitmap, 0, size);
72 *ret = bitmap;
73 return 0;
74}
75
76errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
77 __u32 end,
78 __u32 real_end,
79 const char *descr,
80 ext2fs_generic_bitmap *ret)
81{
82 return make_bitmap(start, end, real_end, descr, 0, ret);
83}
84
85errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
86 ext2fs_generic_bitmap *dest)
87{
88 errcode_t retval;
89 ext2fs_generic_bitmap new_map;
90
91 retval = make_bitmap(src->start, src->end, src->real_end,
92 src->description, src->bitmap, &new_map);
93 if (retval)
94 return retval;
95 new_map->magic = src->magic;
96 new_map->fs = src->fs;
97 new_map->base_error_code = src->base_error_code;
98 *dest = new_map;
99 return 0;
100}
101
102void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
103{
104 __u32 i, j;
105
106 for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
107 ext2fs_set_bit(j, map->bitmap);
108
109 return;
110}
111
112errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
113 const char *descr,
114 ext2fs_inode_bitmap *ret)
115{
116 ext2fs_inode_bitmap bitmap;
117 errcode_t retval;
118 __u32 start, end, real_end;
119
120 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
121
122 fs->write_bitmaps = ext2fs_write_bitmaps;
123
124 start = 1;
125 end = fs->super->s_inodes_count;
126 real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
127
128 retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
129 descr, &bitmap);
130 if (retval)
131 return retval;
132
133 bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
134 bitmap->fs = fs;
135 bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
136
137 *ret = bitmap;
138 return 0;
139}
140
141errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
142 const char *descr,
143 ext2fs_block_bitmap *ret)
144{
145 ext2fs_block_bitmap bitmap;
146 errcode_t retval;
147 __u32 start, end, real_end;
148
149 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
150
151 fs->write_bitmaps = ext2fs_write_bitmaps;
152
153 start = fs->super->s_first_data_block;
154 end = fs->super->s_blocks_count-1;
155 real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
156 * fs->group_desc_count)-1 + start;
157
158 retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
159 descr, &bitmap);
160 if (retval)
161 return retval;
162
163 bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
164 bitmap->fs = fs;
165 bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
166
167 *ret = bitmap;
168 return 0;
169}
170
171errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
172 ext2_ino_t end, ext2_ino_t *oend)
173{
174 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
175
176 if (end > bitmap->real_end)
177 return EXT2_ET_FUDGE_INODE_BITMAP_END;
178 if (oend)
179 *oend = bitmap->end;
180 bitmap->end = end;
181 return 0;
182}
183
184errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
185 blk_t end, blk_t *oend)
186{
187 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
188
189 if (end > bitmap->real_end)
190 return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
191 if (oend)
192 *oend = bitmap->end;
193 bitmap->end = end;
194 return 0;
195}
196
197void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
198{
199 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
200 return;
201
202 memset(bitmap->bitmap, 0,
203 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
204}
205
206void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
207{
208 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
209 return;
210
211 memset(bitmap->bitmap, 0,
212 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
213}
diff --git a/e2fsprogs/ext2fs/bitops.c b/e2fsprogs/ext2fs/bitops.c
deleted file mode 100644
index 987061130..000000000
--- a/e2fsprogs/ext2fs/bitops.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bitops.c --- Bitmap frobbing code. See bitops.h for the inlined
4 * routines.
5 *
6 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#if HAVE_SYS_TYPES_H
16#include <sys/types.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22#ifndef _EXT2_HAVE_ASM_BITOPS_
23
24/*
25 * For the benefit of those who are trying to port Linux to another
26 * architecture, here are some C-language equivalents. You should
27 * recode these in the native assmebly language, if at all possible.
28 *
29 * C language equivalents written by Theodore Ts'o, 9/26/92.
30 * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
31 * systems, as well as non-32 bit systems.
32 */
33
34int ext2fs_set_bit(unsigned int nr,void * addr)
35{
36 int mask, retval;
37 unsigned char *ADDR = (unsigned char *) addr;
38
39 ADDR += nr >> 3;
40 mask = 1 << (nr & 0x07);
41 retval = mask & *ADDR;
42 *ADDR |= mask;
43 return retval;
44}
45
46int ext2fs_clear_bit(unsigned int nr, void * addr)
47{
48 int mask, retval;
49 unsigned char *ADDR = (unsigned char *) addr;
50
51 ADDR += nr >> 3;
52 mask = 1 << (nr & 0x07);
53 retval = mask & *ADDR;
54 *ADDR &= ~mask;
55 return retval;
56}
57
58int ext2fs_test_bit(unsigned int nr, const void * addr)
59{
60 int mask;
61 const unsigned char *ADDR = (const unsigned char *) addr;
62
63 ADDR += nr >> 3;
64 mask = 1 << (nr & 0x07);
65 return (mask & *ADDR);
66}
67
68#endif /* !_EXT2_HAVE_ASM_BITOPS_ */
69
70void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
71 const char *description)
72{
73#ifndef OMIT_COM_ERR
74 if (description)
75 bb_error_msg("#%lu for %s", arg, description);
76 else
77 bb_error_msg("#%lu", arg);
78#endif
79}
80
81void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
82 int code, unsigned long arg)
83{
84#ifndef OMIT_COM_ERR
85 if (bitmap->description)
86 bb_error_msg("#%lu for %s", arg, bitmap->description);
87 else
88 bb_error_msg("#%lu", arg);
89#endif
90}
91
diff --git a/e2fsprogs/ext2fs/bitops.h b/e2fsprogs/ext2fs/bitops.h
deleted file mode 100644
index 6dd30862b..000000000
--- a/e2fsprogs/ext2fs/bitops.h
+++ /dev/null
@@ -1,107 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bitops.h --- Bitmap frobbing code. The byte swapping routines are
4 * also included here.
5 *
6 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 *
13 * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
14 * Linus Torvalds.
15 */
16
17#include <string.h>
18#include <strings.h>
19
20extern int ext2fs_set_bit(unsigned int nr,void * addr);
21extern int ext2fs_clear_bit(unsigned int nr, void * addr);
22extern int ext2fs_test_bit(unsigned int nr, const void * addr);
23extern __u16 ext2fs_swab16(__u16 val);
24extern __u32 ext2fs_swab32(__u32 val);
25
26#ifdef WORDS_BIGENDIAN
27#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
28#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
29#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
30#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
31#define ext2fs_cpu_to_be32(x) ((__u32)(x))
32#define ext2fs_be32_to_cpu(x) ((__u32)(x))
33#define ext2fs_cpu_to_be16(x) ((__u16)(x))
34#define ext2fs_be16_to_cpu(x) ((__u16)(x))
35#else
36#define ext2fs_cpu_to_le32(x) ((__u32)(x))
37#define ext2fs_le32_to_cpu(x) ((__u32)(x))
38#define ext2fs_cpu_to_le16(x) ((__u16)(x))
39#define ext2fs_le16_to_cpu(x) ((__u16)(x))
40#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
41#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
42#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
43#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
44#endif
45
46/*
47 * EXT2FS bitmap manipulation routines.
48 */
49
50/* Support for sending warning messages from the inline subroutines */
51extern const char *ext2fs_block_string;
52extern const char *ext2fs_inode_string;
53extern const char *ext2fs_mark_string;
54extern const char *ext2fs_unmark_string;
55extern const char *ext2fs_test_string;
56extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
57 const char *description);
58extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
59 int code, unsigned long arg);
60
61extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
62extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
63 blk_t block);
64extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
65
66extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
67extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
68 ext2_ino_t inode);
69extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
70
71extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
72 blk_t block);
73extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
74 blk_t block);
75extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
76 blk_t block);
77
78extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
79 ext2_ino_t inode);
80extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
81 ext2_ino_t inode);
82extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
83 ext2_ino_t inode);
84extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
85extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
86extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
87extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
88
89extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
90 blk_t block, int num);
91extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
92 blk_t block, int num);
93extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
94 blk_t block, int num);
95extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
96 blk_t block, int num);
97extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
98 blk_t block, int num);
99extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
100 blk_t block, int num);
101extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
102
103/* These two routines moved to gen_bitmap.c */
104extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
105 __u32 bitno);
106extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
107 blk_t bitno);
diff --git a/e2fsprogs/ext2fs/block.c b/e2fsprogs/ext2fs/block.c
deleted file mode 100644
index 0a757b201..000000000
--- a/e2fsprogs/ext2fs/block.c
+++ /dev/null
@@ -1,438 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * block.c --- iterate over all blocks in an inode
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct block_context {
23 ext2_filsys fs;
24 int (*func)(ext2_filsys fs,
25 blk_t *blocknr,
26 e2_blkcnt_t bcount,
27 blk_t ref_blk,
28 int ref_offset,
29 void *priv_data);
30 e2_blkcnt_t bcount;
31 int bsize;
32 int flags;
33 errcode_t errcode;
34 char *ind_buf;
35 char *dind_buf;
36 char *tind_buf;
37 void *priv_data;
38};
39
40static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
41 int ref_offset, struct block_context *ctx)
42{
43 int ret = 0, changed = 0;
44 int i, flags, limit, offset;
45 blk_t *block_nr;
46
47 limit = ctx->fs->blocksize >> 2;
48 if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
49 !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
50 ret = (*ctx->func)(ctx->fs, ind_block,
51 BLOCK_COUNT_IND, ref_block,
52 ref_offset, ctx->priv_data);
53 if (!*ind_block || (ret & BLOCK_ABORT)) {
54 ctx->bcount += limit;
55 return ret;
56 }
57 if (*ind_block >= ctx->fs->super->s_blocks_count ||
58 *ind_block < ctx->fs->super->s_first_data_block) {
59 ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
60 ret |= BLOCK_ERROR;
61 return ret;
62 }
63 ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block,
64 ctx->ind_buf);
65 if (ctx->errcode) {
66 ret |= BLOCK_ERROR;
67 return ret;
68 }
69
70 block_nr = (blk_t *) ctx->ind_buf;
71 offset = 0;
72 if (ctx->flags & BLOCK_FLAG_APPEND) {
73 for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
74 flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
75 *ind_block, offset,
76 ctx->priv_data);
77 changed |= flags;
78 if (flags & BLOCK_ABORT) {
79 ret |= BLOCK_ABORT;
80 break;
81 }
82 offset += sizeof(blk_t);
83 }
84 } else {
85 for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
86 if (*block_nr == 0)
87 continue;
88 flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
89 *ind_block, offset,
90 ctx->priv_data);
91 changed |= flags;
92 if (flags & BLOCK_ABORT) {
93 ret |= BLOCK_ABORT;
94 break;
95 }
96 offset += sizeof(blk_t);
97 }
98 }
99 if (changed & BLOCK_CHANGED) {
100 ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block,
101 ctx->ind_buf);
102 if (ctx->errcode)
103 ret |= BLOCK_ERROR | BLOCK_ABORT;
104 }
105 if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
106 !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
107 !(ret & BLOCK_ABORT))
108 ret |= (*ctx->func)(ctx->fs, ind_block,
109 BLOCK_COUNT_IND, ref_block,
110 ref_offset, ctx->priv_data);
111 return ret;
112}
113
114static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
115 int ref_offset, struct block_context *ctx)
116{
117 int ret = 0, changed = 0;
118 int i, flags, limit, offset;
119 blk_t *block_nr;
120
121 limit = ctx->fs->blocksize >> 2;
122 if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
123 BLOCK_FLAG_DATA_ONLY)))
124 ret = (*ctx->func)(ctx->fs, dind_block,
125 BLOCK_COUNT_DIND, ref_block,
126 ref_offset, ctx->priv_data);
127 if (!*dind_block || (ret & BLOCK_ABORT)) {
128 ctx->bcount += limit*limit;
129 return ret;
130 }
131 if (*dind_block >= ctx->fs->super->s_blocks_count ||
132 *dind_block < ctx->fs->super->s_first_data_block) {
133 ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
134 ret |= BLOCK_ERROR;
135 return ret;
136 }
137 ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block,
138 ctx->dind_buf);
139 if (ctx->errcode) {
140 ret |= BLOCK_ERROR;
141 return ret;
142 }
143
144 block_nr = (blk_t *) ctx->dind_buf;
145 offset = 0;
146 if (ctx->flags & BLOCK_FLAG_APPEND) {
147 for (i = 0; i < limit; i++, block_nr++) {
148 flags = block_iterate_ind(block_nr,
149 *dind_block, offset,
150 ctx);
151 changed |= flags;
152 if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
153 ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
154 break;
155 }
156 offset += sizeof(blk_t);
157 }
158 } else {
159 for (i = 0; i < limit; i++, block_nr++) {
160 if (*block_nr == 0) {
161 ctx->bcount += limit;
162 continue;
163 }
164 flags = block_iterate_ind(block_nr,
165 *dind_block, offset,
166 ctx);
167 changed |= flags;
168 if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
169 ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
170 break;
171 }
172 offset += sizeof(blk_t);
173 }
174 }
175 if (changed & BLOCK_CHANGED) {
176 ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block,
177 ctx->dind_buf);
178 if (ctx->errcode)
179 ret |= BLOCK_ERROR | BLOCK_ABORT;
180 }
181 if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
182 !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
183 !(ret & BLOCK_ABORT))
184 ret |= (*ctx->func)(ctx->fs, dind_block,
185 BLOCK_COUNT_DIND, ref_block,
186 ref_offset, ctx->priv_data);
187 return ret;
188}
189
190static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
191 int ref_offset, struct block_context *ctx)
192{
193 int ret = 0, changed = 0;
194 int i, flags, limit, offset;
195 blk_t *block_nr;
196
197 limit = ctx->fs->blocksize >> 2;
198 if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
199 BLOCK_FLAG_DATA_ONLY)))
200 ret = (*ctx->func)(ctx->fs, tind_block,
201 BLOCK_COUNT_TIND, ref_block,
202 ref_offset, ctx->priv_data);
203 if (!*tind_block || (ret & BLOCK_ABORT)) {
204 ctx->bcount += limit*limit*limit;
205 return ret;
206 }
207 if (*tind_block >= ctx->fs->super->s_blocks_count ||
208 *tind_block < ctx->fs->super->s_first_data_block) {
209 ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
210 ret |= BLOCK_ERROR;
211 return ret;
212 }
213 ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block,
214 ctx->tind_buf);
215 if (ctx->errcode) {
216 ret |= BLOCK_ERROR;
217 return ret;
218 }
219
220 block_nr = (blk_t *) ctx->tind_buf;
221 offset = 0;
222 if (ctx->flags & BLOCK_FLAG_APPEND) {
223 for (i = 0; i < limit; i++, block_nr++) {
224 flags = block_iterate_dind(block_nr,
225 *tind_block,
226 offset, ctx);
227 changed |= flags;
228 if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
229 ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
230 break;
231 }
232 offset += sizeof(blk_t);
233 }
234 } else {
235 for (i = 0; i < limit; i++, block_nr++) {
236 if (*block_nr == 0) {
237 ctx->bcount += limit*limit;
238 continue;
239 }
240 flags = block_iterate_dind(block_nr,
241 *tind_block,
242 offset, ctx);
243 changed |= flags;
244 if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
245 ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
246 break;
247 }
248 offset += sizeof(blk_t);
249 }
250 }
251 if (changed & BLOCK_CHANGED) {
252 ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block,
253 ctx->tind_buf);
254 if (ctx->errcode)
255 ret |= BLOCK_ERROR | BLOCK_ABORT;
256 }
257 if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
258 !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
259 !(ret & BLOCK_ABORT))
260 ret |= (*ctx->func)(ctx->fs, tind_block,
261 BLOCK_COUNT_TIND, ref_block,
262 ref_offset, ctx->priv_data);
263
264 return ret;
265}
266
267errcode_t ext2fs_block_iterate2(ext2_filsys fs,
268 ext2_ino_t ino,
269 int flags,
270 char *block_buf,
271 int (*func)(ext2_filsys fs,
272 blk_t *blocknr,
273 e2_blkcnt_t blockcnt,
274 blk_t ref_blk,
275 int ref_offset,
276 void *priv_data),
277 void *priv_data)
278{
279 int i;
280 int got_inode = 0;
281 int ret = 0;
282 blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
283 struct ext2_inode inode;
284 errcode_t retval;
285 struct block_context ctx;
286 int limit;
287
288 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
289
290 /*
291 * Check to see if we need to limit large files
292 */
293 if (flags & BLOCK_FLAG_NO_LARGE) {
294 ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
295 if (ctx.errcode)
296 return ctx.errcode;
297 got_inode = 1;
298 if (!LINUX_S_ISDIR(inode.i_mode) &&
299 (inode.i_size_high != 0))
300 return EXT2_ET_FILE_TOO_BIG;
301 }
302
303 retval = ext2fs_get_blocks(fs, ino, blocks);
304 if (retval)
305 return retval;
306
307 limit = fs->blocksize >> 2;
308
309 ctx.fs = fs;
310 ctx.func = func;
311 ctx.priv_data = priv_data;
312 ctx.flags = flags;
313 ctx.bcount = 0;
314 if (block_buf) {
315 ctx.ind_buf = block_buf;
316 } else {
317 retval = ext2fs_get_mem(fs->blocksize * 3, &ctx.ind_buf);
318 if (retval)
319 return retval;
320 }
321 ctx.dind_buf = ctx.ind_buf + fs->blocksize;
322 ctx.tind_buf = ctx.dind_buf + fs->blocksize;
323
324 /*
325 * Iterate over the HURD translator block (if present)
326 */
327 if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
328 !(flags & BLOCK_FLAG_DATA_ONLY)) {
329 ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
330 if (ctx.errcode)
331 goto abort_exit;
332 got_inode = 1;
333 if (inode.osd1.hurd1.h_i_translator) {
334 ret |= (*ctx.func)(fs,
335 &inode.osd1.hurd1.h_i_translator,
336 BLOCK_COUNT_TRANSLATOR,
337 0, 0, priv_data);
338 if (ret & BLOCK_ABORT)
339 goto abort_exit;
340 }
341 }
342
343 /*
344 * Iterate over normal data blocks
345 */
346 for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
347 if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
348 ret |= (*ctx.func)(fs, &blocks[i],
349 ctx.bcount, 0, i, priv_data);
350 if (ret & BLOCK_ABORT)
351 goto abort_exit;
352 }
353 }
354 if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
355 ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK,
356 0, EXT2_IND_BLOCK, &ctx);
357 if (ret & BLOCK_ABORT)
358 goto abort_exit;
359 } else
360 ctx.bcount += limit;
361 if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
362 ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
363 0, EXT2_DIND_BLOCK, &ctx);
364 if (ret & BLOCK_ABORT)
365 goto abort_exit;
366 } else
367 ctx.bcount += limit * limit;
368 if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
369 ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
370 0, EXT2_TIND_BLOCK, &ctx);
371 if (ret & BLOCK_ABORT)
372 goto abort_exit;
373 }
374
375abort_exit:
376 if (ret & BLOCK_CHANGED) {
377 if (!got_inode) {
378 retval = ext2fs_read_inode(fs, ino, &inode);
379 if (retval)
380 return retval;
381 }
382 for (i=0; i < EXT2_N_BLOCKS; i++)
383 inode.i_block[i] = blocks[i];
384 retval = ext2fs_write_inode(fs, ino, &inode);
385 if (retval)
386 return retval;
387 }
388
389 if (!block_buf)
390 ext2fs_free_mem(&ctx.ind_buf);
391
392 return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
393}
394
395/*
396 * Emulate the old ext2fs_block_iterate function!
397 */
398
399struct xlate {
400 int (*func)(ext2_filsys fs,
401 blk_t *blocknr,
402 int bcount,
403 void *priv_data);
404 void *real_private;
405};
406
407#ifdef __TURBOC__
408# pragma argsused
409#endif
410static int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
411 blk_t ref_block EXT2FS_ATTR((unused)),
412 int ref_offset EXT2FS_ATTR((unused)),
413 void *priv_data)
414{
415 struct xlate *xl = (struct xlate *) priv_data;
416
417 return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private);
418}
419
420errcode_t ext2fs_block_iterate(ext2_filsys fs,
421 ext2_ino_t ino,
422 int flags,
423 char *block_buf,
424 int (*func)(ext2_filsys fs,
425 blk_t *blocknr,
426 int blockcnt,
427 void *priv_data),
428 void *priv_data)
429{
430 struct xlate xl;
431
432 xl.real_private = priv_data;
433 xl.func = func;
434
435 return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
436 block_buf, xlate_func, &xl);
437}
438
diff --git a/e2fsprogs/ext2fs/bmap.c b/e2fsprogs/ext2fs/bmap.c
deleted file mode 100644
index b22fe3dbf..000000000
--- a/e2fsprogs/ext2fs/bmap.c
+++ /dev/null
@@ -1,264 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bmap.c --- logical to physical block mapping
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
23 struct ext2_inode *inode,
24 char *block_buf, int bmap_flags,
25 blk_t block, blk_t *phys_blk);
26
27#define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
28
29static errcode_t block_ind_bmap(ext2_filsys fs, int flags,
30 blk_t ind, char *block_buf,
31 int *blocks_alloc,
32 blk_t nr, blk_t *ret_blk)
33{
34 errcode_t retval;
35 blk_t b;
36
37 if (!ind) {
38 if (flags & BMAP_SET)
39 return EXT2_ET_SET_BMAP_NO_IND;
40 *ret_blk = 0;
41 return 0;
42 }
43 retval = io_channel_read_blk(fs->io, ind, 1, block_buf);
44 if (retval)
45 return retval;
46
47 if (flags & BMAP_SET) {
48 b = *ret_blk;
49#if BB_BIG_ENDIAN
50 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
51 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
52 b = ext2fs_swab32(b);
53#endif
54 ((blk_t *) block_buf)[nr] = b;
55 return io_channel_write_blk(fs->io, ind, 1, block_buf);
56 }
57
58 b = ((blk_t *) block_buf)[nr];
59
60#if BB_BIG_ENDIAN
61 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
62 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
63 b = ext2fs_swab32(b);
64#endif
65
66 if (!b && (flags & BMAP_ALLOC)) {
67 b = nr ? ((blk_t *) block_buf)[nr-1] : 0;
68 retval = ext2fs_alloc_block(fs, b,
69 block_buf + fs->blocksize, &b);
70 if (retval)
71 return retval;
72
73#if BB_BIG_ENDIAN
74 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
75 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
76 ((blk_t *) block_buf)[nr] = ext2fs_swab32(b);
77 else
78#endif
79 ((blk_t *) block_buf)[nr] = b;
80
81 retval = io_channel_write_blk(fs->io, ind, 1, block_buf);
82 if (retval)
83 return retval;
84
85 (*blocks_alloc)++;
86 }
87
88 *ret_blk = b;
89 return 0;
90}
91
92static errcode_t block_dind_bmap(ext2_filsys fs, int flags,
93 blk_t dind, char *block_buf,
94 int *blocks_alloc,
95 blk_t nr, blk_t *ret_blk)
96{
97 blk_t b;
98 errcode_t retval;
99 blk_t addr_per_block;
100
101 addr_per_block = (blk_t) fs->blocksize >> 2;
102
103 retval = block_ind_bmap(fs, flags & ~BMAP_SET, dind, block_buf,
104 blocks_alloc, nr / addr_per_block, &b);
105 if (retval)
106 return retval;
107 retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
108 nr % addr_per_block, ret_blk);
109 return retval;
110}
111
112static errcode_t block_tind_bmap(ext2_filsys fs, int flags,
113 blk_t tind, char *block_buf,
114 int *blocks_alloc,
115 blk_t nr, blk_t *ret_blk)
116{
117 blk_t b;
118 errcode_t retval;
119 blk_t addr_per_block;
120
121 addr_per_block = (blk_t) fs->blocksize >> 2;
122
123 retval = block_dind_bmap(fs, flags & ~BMAP_SET, tind, block_buf,
124 blocks_alloc, nr / addr_per_block, &b);
125 if (retval)
126 return retval;
127 retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
128 nr % addr_per_block, ret_blk);
129 return retval;
130}
131
132errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
133 char *block_buf, int bmap_flags, blk_t block,
134 blk_t *phys_blk)
135{
136 struct ext2_inode inode_buf;
137 blk_t addr_per_block;
138 blk_t b;
139 char *buf = 0;
140 errcode_t retval = 0;
141 int blocks_alloc = 0, inode_dirty = 0;
142
143 if (!(bmap_flags & BMAP_SET))
144 *phys_blk = 0;
145
146 /* Read inode structure if necessary */
147 if (!inode) {
148 retval = ext2fs_read_inode(fs, ino, &inode_buf);
149 if (retval)
150 return retval;
151 inode = &inode_buf;
152 }
153 addr_per_block = (blk_t) fs->blocksize >> 2;
154
155 if (!block_buf) {
156 retval = ext2fs_get_mem(fs->blocksize * 2, &buf);
157 if (retval)
158 return retval;
159 block_buf = buf;
160 }
161
162 if (block < EXT2_NDIR_BLOCKS) {
163 if (bmap_flags & BMAP_SET) {
164 b = *phys_blk;
165#if BB_BIG_ENDIAN
166 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
167 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
168 b = ext2fs_swab32(b);
169#endif
170 inode_bmap(inode, block) = b;
171 inode_dirty++;
172 goto done;
173 }
174
175 *phys_blk = inode_bmap(inode, block);
176 b = block ? inode_bmap(inode, block-1) : 0;
177
178 if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
179 retval = ext2fs_alloc_block(fs, b, block_buf, &b);
180 if (retval)
181 goto done;
182 inode_bmap(inode, block) = b;
183 blocks_alloc++;
184 *phys_blk = b;
185 }
186 goto done;
187 }
188
189 /* Indirect block */
190 block -= EXT2_NDIR_BLOCKS;
191 if (block < addr_per_block) {
192 b = inode_bmap(inode, EXT2_IND_BLOCK);
193 if (!b) {
194 if (!(bmap_flags & BMAP_ALLOC)) {
195 if (bmap_flags & BMAP_SET)
196 retval = EXT2_ET_SET_BMAP_NO_IND;
197 goto done;
198 }
199
200 b = inode_bmap(inode, EXT2_IND_BLOCK-1);
201 retval = ext2fs_alloc_block(fs, b, block_buf, &b);
202 if (retval)
203 goto done;
204 inode_bmap(inode, EXT2_IND_BLOCK) = b;
205 blocks_alloc++;
206 }
207 retval = block_ind_bmap(fs, bmap_flags, b, block_buf,
208 &blocks_alloc, block, phys_blk);
209 goto done;
210 }
211
212 /* Doubly indirect block */
213 block -= addr_per_block;
214 if (block < addr_per_block * addr_per_block) {
215 b = inode_bmap(inode, EXT2_DIND_BLOCK);
216 if (!b) {
217 if (!(bmap_flags & BMAP_ALLOC)) {
218 if (bmap_flags & BMAP_SET)
219 retval = EXT2_ET_SET_BMAP_NO_IND;
220 goto done;
221 }
222
223 b = inode_bmap(inode, EXT2_IND_BLOCK);
224 retval = ext2fs_alloc_block(fs, b, block_buf, &b);
225 if (retval)
226 goto done;
227 inode_bmap(inode, EXT2_DIND_BLOCK) = b;
228 blocks_alloc++;
229 }
230 retval = block_dind_bmap(fs, bmap_flags, b, block_buf,
231 &blocks_alloc, block, phys_blk);
232 goto done;
233 }
234
235 /* Triply indirect block */
236 block -= addr_per_block * addr_per_block;
237 b = inode_bmap(inode, EXT2_TIND_BLOCK);
238 if (!b) {
239 if (!(bmap_flags & BMAP_ALLOC)) {
240 if (bmap_flags & BMAP_SET)
241 retval = EXT2_ET_SET_BMAP_NO_IND;
242 goto done;
243 }
244
245 b = inode_bmap(inode, EXT2_DIND_BLOCK);
246 retval = ext2fs_alloc_block(fs, b, block_buf, &b);
247 if (retval)
248 goto done;
249 inode_bmap(inode, EXT2_TIND_BLOCK) = b;
250 blocks_alloc++;
251 }
252 retval = block_tind_bmap(fs, bmap_flags, b, block_buf,
253 &blocks_alloc, block, phys_blk);
254done:
255 ext2fs_free_mem(&buf);
256 if ((retval == 0) && (blocks_alloc || inode_dirty)) {
257 inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
258 retval = ext2fs_write_inode(fs, ino, inode);
259 }
260 return retval;
261}
262
263
264
diff --git a/e2fsprogs/ext2fs/bmove.c b/e2fsprogs/ext2fs/bmove.c
deleted file mode 100644
index 635410da5..000000000
--- a/e2fsprogs/ext2fs/bmove.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bmove.c --- Move blocks around to make way for a particular
4 * filesystem structure.
5 *
6 * Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
7 * under the terms of the GNU Public License.
8 */
9
10#include <stdio.h>
11#include <string.h>
12#if HAVE_UNISTD_H
13#include <unistd.h>
14#endif
15#if HAVE_SYS_TYPES_H
16#include <sys/types.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fsP.h"
21
22struct process_block_struct {
23 ext2_ino_t ino;
24 struct ext2_inode * inode;
25 ext2fs_block_bitmap reserve;
26 ext2fs_block_bitmap alloc_map;
27 errcode_t error;
28 char *buf;
29 int add_dir;
30 int flags;
31};
32
33static int process_block(ext2_filsys fs, blk_t *block_nr,
34 e2_blkcnt_t blockcnt, blk_t ref_block,
35 int ref_offset, void *priv_data)
36{
37 struct process_block_struct *pb;
38 errcode_t retval;
39 int ret;
40 blk_t block, orig;
41
42 pb = (struct process_block_struct *) priv_data;
43 block = orig = *block_nr;
44 ret = 0;
45
46 /*
47 * Let's see if this is one which we need to relocate
48 */
49 if (ext2fs_test_block_bitmap(pb->reserve, block)) {
50 do {
51 if (++block >= fs->super->s_blocks_count)
52 block = fs->super->s_first_data_block;
53 if (block == orig) {
54 pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
55 return BLOCK_ABORT;
56 }
57 } while (ext2fs_test_block_bitmap(pb->reserve, block) ||
58 ext2fs_test_block_bitmap(pb->alloc_map, block));
59
60 retval = io_channel_read_blk(fs->io, orig, 1, pb->buf);
61 if (retval) {
62 pb->error = retval;
63 return BLOCK_ABORT;
64 }
65 retval = io_channel_write_blk(fs->io, block, 1, pb->buf);
66 if (retval) {
67 pb->error = retval;
68 return BLOCK_ABORT;
69 }
70 *block_nr = block;
71 ext2fs_mark_block_bitmap(pb->alloc_map, block);
72 ret = BLOCK_CHANGED;
73 if (pb->flags & EXT2_BMOVE_DEBUG)
74 printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb->ino,
75 blockcnt, orig, block);
76 }
77 if (pb->add_dir) {
78 retval = ext2fs_add_dir_block(fs->dblist, pb->ino,
79 block, (int) blockcnt);
80 if (retval) {
81 pb->error = retval;
82 ret |= BLOCK_ABORT;
83 }
84 }
85 return ret;
86}
87
88errcode_t ext2fs_move_blocks(ext2_filsys fs,
89 ext2fs_block_bitmap reserve,
90 ext2fs_block_bitmap alloc_map,
91 int flags)
92{
93 ext2_ino_t ino;
94 struct ext2_inode inode;
95 errcode_t retval;
96 struct process_block_struct pb;
97 ext2_inode_scan scan;
98 char *block_buf;
99
100 retval = ext2fs_open_inode_scan(fs, 0, &scan);
101 if (retval)
102 return retval;
103
104 pb.reserve = reserve;
105 pb.error = 0;
106 pb.alloc_map = alloc_map ? alloc_map : fs->block_map;
107 pb.flags = flags;
108
109 retval = ext2fs_get_mem(fs->blocksize * 4, &block_buf);
110 if (retval)
111 return retval;
112 pb.buf = block_buf + fs->blocksize * 3;
113
114 /*
115 * If GET_DBLIST is set in the flags field, then we should
116 * gather directory block information while we're doing the
117 * block move.
118 */
119 if (flags & EXT2_BMOVE_GET_DBLIST) {
120 ext2fs_free_dblist(fs->dblist);
121 fs->dblist = NULL;
122 retval = ext2fs_init_dblist(fs, 0);
123 if (retval)
124 return retval;
125 }
126
127 retval = ext2fs_get_next_inode(scan, &ino, &inode);
128 if (retval)
129 return retval;
130
131 while (ino) {
132 if ((inode.i_links_count == 0) ||
133 !ext2fs_inode_has_valid_blocks(&inode))
134 goto next;
135
136 pb.ino = ino;
137 pb.inode = &inode;
138
139 pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) &&
140 flags & EXT2_BMOVE_GET_DBLIST);
141
142 retval = ext2fs_block_iterate2(fs, ino, 0, block_buf,
143 process_block, &pb);
144 if (retval)
145 return retval;
146 if (pb.error)
147 return pb.error;
148
149 next:
150 retval = ext2fs_get_next_inode(scan, &ino, &inode);
151 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
152 goto next;
153 }
154 return 0;
155}
156
diff --git a/e2fsprogs/ext2fs/brel.h b/e2fsprogs/ext2fs/brel.h
deleted file mode 100644
index 216fd132c..000000000
--- a/e2fsprogs/ext2fs/brel.h
+++ /dev/null
@@ -1,87 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * brel.h
4 *
5 * Copyright (C) 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13struct ext2_block_relocate_entry {
14 blk_t new;
15 __s16 offset;
16 __u16 flags;
17 union {
18 blk_t block_ref;
19 ext2_ino_t inode_ref;
20 } owner;
21};
22
23#define RELOCATE_TYPE_REF 0x0007
24#define RELOCATE_BLOCK_REF 0x0001
25#define RELOCATE_INODE_REF 0x0002
26
27typedef struct ext2_block_relocation_table *ext2_brel;
28
29struct ext2_block_relocation_table {
30 __u32 magic;
31 char *name;
32 blk_t current;
33 void *priv_data;
34
35 /*
36 * Add a block relocation entry.
37 */
38 errcode_t (*put)(ext2_brel brel, blk_t old,
39 struct ext2_block_relocate_entry *ent);
40
41 /*
42 * Get a block relocation entry.
43 */
44 errcode_t (*get)(ext2_brel brel, blk_t old,
45 struct ext2_block_relocate_entry *ent);
46
47 /*
48 * Initialize for iterating over the block relocation entries.
49 */
50 errcode_t (*start_iter)(ext2_brel brel);
51
52 /*
53 * The iterator function for the inode relocation entries.
54 * Returns an inode number of 0 when out of entries.
55 */
56 errcode_t (*next)(ext2_brel brel, blk_t *old,
57 struct ext2_block_relocate_entry *ent);
58
59 /*
60 * Move the inode relocation table from one block number to
61 * another.
62 */
63 errcode_t (*move)(ext2_brel brel, blk_t old, blk_t new);
64
65 /*
66 * Remove a block relocation entry.
67 */
68 errcode_t (*delete)(ext2_brel brel, blk_t old);
69
70
71 /*
72 * Free the block relocation table.
73 */
74 errcode_t (*free)(ext2_brel brel);
75};
76
77errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
78 ext2_brel *brel);
79
80#define ext2fs_brel_put(brel, old, ent) ((brel)->put((brel), old, ent))
81#define ext2fs_brel_get(brel, old, ent) ((brel)->get((brel), old, ent))
82#define ext2fs_brel_start_iter(brel) ((brel)->start_iter((brel)))
83#define ext2fs_brel_next(brel, old, ent) ((brel)->next((brel), old, ent))
84#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new))
85#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old))
86#define ext2fs_brel_free(brel) ((brel)->free((brel)))
87
diff --git a/e2fsprogs/ext2fs/brel_ma.c b/e2fsprogs/ext2fs/brel_ma.c
deleted file mode 100644
index 652a3509c..000000000
--- a/e2fsprogs/ext2fs/brel_ma.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * brel_ma.c
4 *
5 * Copyright (C) 1996, 1997 Theodore Ts'o.
6 *
7 * TODO: rewrite to not use a direct array!!! (Fortunately this
8 * module isn't really used yet.)
9 *
10 * %Begin-Header%
11 * This file may be redistributed under the terms of the GNU Public
12 * License.
13 * %End-Header%
14 */
15
16#include <fcntl.h>
17#include <stdio.h>
18#include <string.h>
19#if HAVE_UNISTD_H
20#include <unistd.h>
21#endif
22#if HAVE_ERRNO_H
23#include <errno.h>
24#endif
25
26#include "ext2_fs.h"
27#include "ext2fs.h"
28#include "brel.h"
29
30static errcode_t bma_put(ext2_brel brel, blk_t old,
31 struct ext2_block_relocate_entry *ent);
32static errcode_t bma_get(ext2_brel brel, blk_t old,
33 struct ext2_block_relocate_entry *ent);
34static errcode_t bma_start_iter(ext2_brel brel);
35static errcode_t bma_next(ext2_brel brel, blk_t *old,
36 struct ext2_block_relocate_entry *ent);
37static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
38static errcode_t bma_delete(ext2_brel brel, blk_t old);
39static errcode_t bma_free(ext2_brel brel);
40
41struct brel_ma {
42 __u32 magic;
43 blk_t max_block;
44 struct ext2_block_relocate_entry *entries;
45};
46
47errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
48 ext2_brel *new_brel)
49{
50 ext2_brel brel = 0;
51 errcode_t retval;
52 struct brel_ma *ma = 0;
53 size_t size;
54
55 *new_brel = 0;
56
57 /*
58 * Allocate memory structures
59 */
60 retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
61 &brel);
62 if (retval)
63 goto errout;
64 memset(brel, 0, sizeof(struct ext2_block_relocation_table));
65
66 retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
67 if (retval)
68 goto errout;
69 strcpy(brel->name, name);
70
71 retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
72 if (retval)
73 goto errout;
74 memset(ma, 0, sizeof(struct brel_ma));
75 brel->priv_data = ma;
76
77 size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
78 (max_block+1));
79 retval = ext2fs_get_mem(size, &ma->entries);
80 if (retval)
81 goto errout;
82 memset(ma->entries, 0, size);
83 ma->max_block = max_block;
84
85 /*
86 * Fill in the brel data structure
87 */
88 brel->put = bma_put;
89 brel->get = bma_get;
90 brel->start_iter = bma_start_iter;
91 brel->next = bma_next;
92 brel->move = bma_move;
93 brel->delete = bma_delete;
94 brel->free = bma_free;
95
96 *new_brel = brel;
97 return 0;
98
99errout:
100 bma_free(brel);
101 return retval;
102}
103
104static errcode_t bma_put(ext2_brel brel, blk_t old,
105 struct ext2_block_relocate_entry *ent)
106{
107 struct brel_ma *ma;
108
109 ma = brel->priv_data;
110 if (old > ma->max_block)
111 return EXT2_ET_INVALID_ARGUMENT;
112 ma->entries[(unsigned)old] = *ent;
113 return 0;
114}
115
116static errcode_t bma_get(ext2_brel brel, blk_t old,
117 struct ext2_block_relocate_entry *ent)
118{
119 struct brel_ma *ma;
120
121 ma = brel->priv_data;
122 if (old > ma->max_block)
123 return EXT2_ET_INVALID_ARGUMENT;
124 if (ma->entries[(unsigned)old].new == 0)
125 return ENOENT;
126 *ent = ma->entries[old];
127 return 0;
128}
129
130static errcode_t bma_start_iter(ext2_brel brel)
131{
132 brel->current = 0;
133 return 0;
134}
135
136static errcode_t bma_next(ext2_brel brel, blk_t *old,
137 struct ext2_block_relocate_entry *ent)
138{
139 struct brel_ma *ma;
140
141 ma = brel->priv_data;
142 while (++brel->current < ma->max_block) {
143 if (ma->entries[(unsigned)brel->current].new == 0)
144 continue;
145 *old = brel->current;
146 *ent = ma->entries[(unsigned)brel->current];
147 return 0;
148 }
149 *old = 0;
150 return 0;
151}
152
153static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new)
154{
155 struct brel_ma *ma;
156
157 ma = brel->priv_data;
158 if ((old > ma->max_block) || (new > ma->max_block))
159 return EXT2_ET_INVALID_ARGUMENT;
160 if (ma->entries[(unsigned)old].new == 0)
161 return ENOENT;
162 ma->entries[(unsigned)new] = ma->entries[old];
163 ma->entries[(unsigned)old].new = 0;
164 return 0;
165}
166
167static errcode_t bma_delete(ext2_brel brel, blk_t old)
168{
169 struct brel_ma *ma;
170
171 ma = brel->priv_data;
172 if (old > ma->max_block)
173 return EXT2_ET_INVALID_ARGUMENT;
174 if (ma->entries[(unsigned)old].new == 0)
175 return ENOENT;
176 ma->entries[(unsigned)old].new = 0;
177 return 0;
178}
179
180static errcode_t bma_free(ext2_brel brel)
181{
182 struct brel_ma *ma;
183
184 if (!brel)
185 return 0;
186
187 ma = brel->priv_data;
188
189 if (ma) {
190 ext2fs_free_mem(&ma->entries);
191 ext2fs_free_mem(&ma);
192 }
193 ext2fs_free_mem(&brel->name);
194 ext2fs_free_mem(&brel);
195 return 0;
196}
diff --git a/e2fsprogs/ext2fs/check_desc.c b/e2fsprogs/ext2fs/check_desc.c
deleted file mode 100644
index dd4b0e9cf..000000000
--- a/e2fsprogs/ext2fs/check_desc.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * check_desc.c --- Check the group descriptors of an ext2 filesystem
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30/*
31 * This routine sanity checks the group descriptors
32 */
33errcode_t ext2fs_check_desc(ext2_filsys fs)
34{
35 dgrp_t i;
36 blk_t block = fs->super->s_first_data_block;
37 blk_t next;
38
39 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
40
41 for (i = 0; i < fs->group_desc_count; i++) {
42 next = block + fs->super->s_blocks_per_group;
43 /*
44 * Check to make sure block bitmap for group is
45 * located within the group.
46 */
47 if (fs->group_desc[i].bg_block_bitmap < block ||
48 fs->group_desc[i].bg_block_bitmap >= next)
49 return EXT2_ET_GDESC_BAD_BLOCK_MAP;
50 /*
51 * Check to make sure inode bitmap for group is
52 * located within the group
53 */
54 if (fs->group_desc[i].bg_inode_bitmap < block ||
55 fs->group_desc[i].bg_inode_bitmap >= next)
56 return EXT2_ET_GDESC_BAD_INODE_MAP;
57 /*
58 * Check to make sure inode table for group is located
59 * within the group
60 */
61 if (fs->group_desc[i].bg_inode_table < block ||
62 ((fs->group_desc[i].bg_inode_table +
63 fs->inode_blocks_per_group) >= next))
64 return EXT2_ET_GDESC_BAD_INODE_TABLE;
65
66 block = next;
67 }
68 return 0;
69}
diff --git a/e2fsprogs/ext2fs/closefs.c b/e2fsprogs/ext2fs/closefs.c
deleted file mode 100644
index 008d5f36e..000000000
--- a/e2fsprogs/ext2fs/closefs.c
+++ /dev/null
@@ -1,381 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * closefs.c --- close an ext2 filesystem
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17#include <time.h>
18#include <string.h>
19
20#include "ext2_fs.h"
21#include "ext2fsP.h"
22
23static int test_root(int a, int b)
24{
25 if (a == 0)
26 return 1;
27 while (1) {
28 if (a == 1)
29 return 1;
30 if (a % b)
31 return 0;
32 a = a / b;
33 }
34}
35
36int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
37{
38 if (!(fs->super->s_feature_ro_compat &
39 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
40 return 1;
41
42 if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
43 test_root(group_block, 7))
44 return 1;
45
46 return 0;
47}
48
49int ext2fs_super_and_bgd_loc(ext2_filsys fs,
50 dgrp_t group,
51 blk_t *ret_super_blk,
52 blk_t *ret_old_desc_blk,
53 blk_t *ret_new_desc_blk,
54 int *ret_meta_bg)
55{
56 blk_t group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0;
57 unsigned int meta_bg, meta_bg_size;
58 int numblocks, has_super;
59 int old_desc_blocks;
60
61 group_block = fs->super->s_first_data_block +
62 (group * fs->super->s_blocks_per_group);
63
64 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
65 old_desc_blocks = fs->super->s_first_meta_bg;
66 else
67 old_desc_blocks =
68 fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
69
70 if (group == fs->group_desc_count-1) {
71 numblocks = (fs->super->s_blocks_count -
72 fs->super->s_first_data_block) %
73 fs->super->s_blocks_per_group;
74 if (!numblocks)
75 numblocks = fs->super->s_blocks_per_group;
76 } else
77 numblocks = fs->super->s_blocks_per_group;
78
79 has_super = ext2fs_bg_has_super(fs, group);
80
81 if (has_super) {
82 super_blk = group_block;
83 numblocks--;
84 }
85 meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
86 meta_bg = group / meta_bg_size;
87
88 if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
89 (meta_bg < fs->super->s_first_meta_bg)) {
90 if (has_super) {
91 old_desc_blk = group_block + 1;
92 numblocks -= old_desc_blocks;
93 }
94 } else {
95 if (((group % meta_bg_size) == 0) ||
96 ((group % meta_bg_size) == 1) ||
97 ((group % meta_bg_size) == (meta_bg_size-1))) {
98 if (has_super)
99 has_super = 1;
100 new_desc_blk = group_block + has_super;
101 numblocks--;
102 }
103 }
104
105 numblocks -= 2 + fs->inode_blocks_per_group;
106
107 if (ret_super_blk)
108 *ret_super_blk = super_blk;
109 if (ret_old_desc_blk)
110 *ret_old_desc_blk = old_desc_blk;
111 if (ret_new_desc_blk)
112 *ret_new_desc_blk = new_desc_blk;
113 if (ret_meta_bg)
114 *ret_meta_bg = meta_bg;
115 return numblocks;
116}
117
118
119/*
120 * This function forces out the primary superblock. We need to only
121 * write out those fields which we have changed, since if the
122 * filesystem is mounted, it may have changed some of the other
123 * fields.
124 *
125 * It takes as input a superblock which has already been byte swapped
126 * (if necessary).
127 *
128 */
129static errcode_t write_primary_superblock(ext2_filsys fs,
130 struct ext2_super_block *super)
131{
132 __u16 *old_super, *new_super;
133 int check_idx, write_idx, size;
134 errcode_t retval;
135
136 if (!fs->io->manager->write_byte || !fs->orig_super) {
137 io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
138 retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE,
139 super);
140 io_channel_set_blksize(fs->io, fs->blocksize);
141 return retval;
142 }
143
144 old_super = (__u16 *) fs->orig_super;
145 new_super = (__u16 *) super;
146
147 for (check_idx = 0; check_idx < SUPERBLOCK_SIZE/2; check_idx++) {
148 if (old_super[check_idx] == new_super[check_idx])
149 continue;
150 write_idx = check_idx;
151 for (check_idx++; check_idx < SUPERBLOCK_SIZE/2; check_idx++)
152 if (old_super[check_idx] == new_super[check_idx])
153 break;
154 size = 2 * (check_idx - write_idx);
155 retval = io_channel_write_byte(fs->io,
156 SUPERBLOCK_OFFSET + (2 * write_idx), size,
157 new_super + write_idx);
158 if (retval)
159 return retval;
160 }
161 memcpy(fs->orig_super, super, SUPERBLOCK_SIZE);
162 return 0;
163}
164
165
166/*
167 * Updates the revision to EXT2_DYNAMIC_REV
168 */
169void ext2fs_update_dynamic_rev(ext2_filsys fs)
170{
171 struct ext2_super_block *sb = fs->super;
172
173 if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
174 return;
175
176 sb->s_rev_level = EXT2_DYNAMIC_REV;
177 sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
178 sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
179 /* s_uuid is handled by e2fsck already */
180 /* other fields should be left alone */
181}
182
183static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
184 blk_t group_block,
185 struct ext2_super_block *super_shadow)
186{
187 dgrp_t sgrp = group;
188
189 if (sgrp > ((1 << 16) - 1))
190 sgrp = (1 << 16) - 1;
191#if BB_BIG_ENDIAN
192 if (fs->flags & EXT2_FLAG_SWAP_BYTES)
193 super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
194 else
195#endif
196 fs->super->s_block_group_nr = sgrp;
197
198 return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE,
199 super_shadow);
200}
201
202
203errcode_t ext2fs_flush(ext2_filsys fs)
204{
205 dgrp_t i;
206 blk_t group_block;
207 errcode_t retval;
208 unsigned long fs_state;
209 struct ext2_super_block *super_shadow = 0;
210 struct ext2_group_desc *group_shadow = 0;
211 char *group_ptr;
212 int old_desc_blocks;
213#if BB_BIG_ENDIAN
214 dgrp_t j;
215 struct ext2_group_desc *s, *t;
216#endif
217
218 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
219
220 fs_state = fs->super->s_state;
221
222 fs->super->s_wtime = time(NULL);
223 fs->super->s_block_group_nr = 0;
224#if BB_BIG_ENDIAN
225 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
226 retval = EXT2_ET_NO_MEMORY;
227 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
228 if (retval)
229 goto errout;
230 retval = ext2fs_get_mem((size_t)(fs->blocksize *
231 fs->desc_blocks),
232 &group_shadow);
233 if (retval)
234 goto errout;
235 memset(group_shadow, 0, (size_t) fs->blocksize *
236 fs->desc_blocks);
237
238 /* swap the group descriptors */
239 for (j=0, s=fs->group_desc, t=group_shadow;
240 j < fs->group_desc_count; j++, t++, s++) {
241 *t = *s;
242 ext2fs_swap_group_desc(t);
243 }
244 } else {
245 super_shadow = fs->super;
246 group_shadow = fs->group_desc;
247 }
248#else
249 super_shadow = fs->super;
250 group_shadow = fs->group_desc;
251#endif
252
253 /*
254 * If this is an external journal device, don't write out the
255 * block group descriptors or any of the backup superblocks
256 */
257 if (fs->super->s_feature_incompat &
258 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
259 goto write_primary_superblock_only;
260
261 /*
262 * Set the state of the FS to be non-valid. (The state has
263 * already been backed up earlier, and will be restored after
264 * we write out the backup superblocks.)
265 */
266 fs->super->s_state &= ~EXT2_VALID_FS;
267#if BB_BIG_ENDIAN
268 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
269 *super_shadow = *fs->super;
270 ext2fs_swap_super(super_shadow);
271 }
272#endif
273
274 /*
275 * Write out the master group descriptors, and the backup
276 * superblocks and group descriptors.
277 */
278 group_block = fs->super->s_first_data_block;
279 group_ptr = (char *) group_shadow;
280 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
281 old_desc_blocks = fs->super->s_first_meta_bg;
282 else
283 old_desc_blocks = fs->desc_blocks;
284
285 for (i = 0; i < fs->group_desc_count; i++) {
286 blk_t super_blk, old_desc_blk, new_desc_blk;
287 int meta_bg;
288
289 ext2fs_super_and_bgd_loc(fs, i, &super_blk, &old_desc_blk,
290 &new_desc_blk, &meta_bg);
291
292 if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) &&i && super_blk) {
293 retval = write_backup_super(fs, i, super_blk,
294 super_shadow);
295 if (retval)
296 goto errout;
297 }
298 if (fs->flags & EXT2_FLAG_SUPER_ONLY)
299 continue;
300 if ((old_desc_blk) &&
301 (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) {
302 retval = io_channel_write_blk(fs->io,
303 old_desc_blk, old_desc_blocks, group_ptr);
304 if (retval)
305 goto errout;
306 }
307 if (new_desc_blk) {
308 retval = io_channel_write_blk(fs->io, new_desc_blk,
309 1, group_ptr + (meta_bg*fs->blocksize));
310 if (retval)
311 goto errout;
312 }
313 }
314 fs->super->s_block_group_nr = 0;
315 fs->super->s_state = fs_state;
316#if BB_BIG_ENDIAN
317 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
318 *super_shadow = *fs->super;
319 ext2fs_swap_super(super_shadow);
320 }
321#endif
322
323 /*
324 * If the write_bitmaps() function is present, call it to
325 * flush the bitmaps. This is done this way so that a simple
326 * program that doesn't mess with the bitmaps doesn't need to
327 * drag in the bitmaps.c code.
328 */
329 if (fs->write_bitmaps) {
330 retval = fs->write_bitmaps(fs);
331 if (retval)
332 goto errout;
333 }
334
335write_primary_superblock_only:
336 /*
337 * Write out master superblock. This has to be done
338 * separately, since it is located at a fixed location
339 * (SUPERBLOCK_OFFSET). We flush all other pending changes
340 * out to disk first, just to avoid a race condition with an
341 * insy-tinsy window....
342 */
343 retval = io_channel_flush(fs->io);
344 retval = write_primary_superblock(fs, super_shadow);
345 if (retval)
346 goto errout;
347
348 fs->flags &= ~EXT2_FLAG_DIRTY;
349
350 retval = io_channel_flush(fs->io);
351errout:
352 fs->super->s_state = fs_state;
353 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
354 if (super_shadow)
355 ext2fs_free_mem(&super_shadow);
356 if (group_shadow)
357 ext2fs_free_mem(&group_shadow);
358 }
359 return retval;
360}
361
362errcode_t ext2fs_close(ext2_filsys fs)
363{
364 errcode_t retval;
365
366 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
367
368 if (fs->flags & EXT2_FLAG_DIRTY) {
369 retval = ext2fs_flush(fs);
370 if (retval)
371 return retval;
372 }
373 if (fs->write_bitmaps) {
374 retval = fs->write_bitmaps(fs);
375 if (retval)
376 return retval;
377 }
378 ext2fs_free(fs);
379 return 0;
380}
381
diff --git a/e2fsprogs/ext2fs/cmp_bitmaps.c b/e2fsprogs/ext2fs/cmp_bitmaps.c
deleted file mode 100644
index 05b8eb8d7..000000000
--- a/e2fsprogs/ext2fs/cmp_bitmaps.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * cmp_bitmaps.c --- routines to compare inode and block bitmaps.
4 *
5 * Copyright (C) 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
31 ext2fs_block_bitmap bm2)
32{
33 blk_t i;
34
35 EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_BLOCK_BITMAP);
36 EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_BLOCK_BITMAP);
37
38 if ((bm1->start != bm2->start) ||
39 (bm1->end != bm2->end) ||
40 (memcmp(bm1->bitmap, bm2->bitmap,
41 (size_t) (bm1->end - bm1->start)/8)))
42 return EXT2_ET_NEQ_BLOCK_BITMAP;
43
44 for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
45 if (ext2fs_fast_test_block_bitmap(bm1, i) !=
46 ext2fs_fast_test_block_bitmap(bm2, i))
47 return EXT2_ET_NEQ_BLOCK_BITMAP;
48
49 return 0;
50}
51
52errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
53 ext2fs_inode_bitmap bm2)
54{
55 ext2_ino_t i;
56
57 EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_INODE_BITMAP);
58 EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_INODE_BITMAP);
59
60 if ((bm1->start != bm2->start) ||
61 (bm1->end != bm2->end) ||
62 (memcmp(bm1->bitmap, bm2->bitmap,
63 (size_t) (bm1->end - bm1->start)/8)))
64 return EXT2_ET_NEQ_INODE_BITMAP;
65
66 for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
67 if (ext2fs_fast_test_inode_bitmap(bm1, i) !=
68 ext2fs_fast_test_inode_bitmap(bm2, i))
69 return EXT2_ET_NEQ_INODE_BITMAP;
70
71 return 0;
72}
73
diff --git a/e2fsprogs/ext2fs/dblist.c b/e2fsprogs/ext2fs/dblist.c
deleted file mode 100644
index 06ff6d807..000000000
--- a/e2fsprogs/ext2fs/dblist.c
+++ /dev/null
@@ -1,260 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dblist.c -- directory block list functions
4 *
5 * Copyright 1997 by Theodore Ts'o
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 */
13
14#include <stdio.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <string.h>
19#include <time.h>
20
21#include "ext2_fs.h"
22#include "ext2fsP.h"
23
24static int dir_block_cmp(const void *a, const void *b);
25
26/*
27 * Returns the number of directories in the filesystem as reported by
28 * the group descriptors. Of course, the group descriptors could be
29 * wrong!
30 */
31errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs)
32{
33 dgrp_t i;
34 ext2_ino_t num_dirs, max_dirs;
35
36 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
37
38 num_dirs = 0;
39 max_dirs = fs->super->s_inodes_per_group;
40 for (i = 0; i < fs->group_desc_count; i++) {
41 if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
42 num_dirs += max_dirs / 8;
43 else
44 num_dirs += fs->group_desc[i].bg_used_dirs_count;
45 }
46 if (num_dirs > fs->super->s_inodes_count)
47 num_dirs = fs->super->s_inodes_count;
48
49 *ret_num_dirs = num_dirs;
50
51 return 0;
52}
53
54/*
55 * helper function for making a new directory block list (for
56 * initialize and copy).
57 */
58static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count,
59 struct ext2_db_entry *list,
60 ext2_dblist *ret_dblist)
61{
62 ext2_dblist dblist;
63 errcode_t retval;
64 size_t len;
65
66 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
67
68 if ((ret_dblist == 0) && fs->dblist &&
69 (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
70 return 0;
71
72 retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist);
73 if (retval)
74 return retval;
75 memset(dblist, 0, sizeof(struct ext2_struct_dblist));
76
77 dblist->magic = EXT2_ET_MAGIC_DBLIST;
78 dblist->fs = fs;
79 if (size)
80 dblist->size = size;
81 else {
82 retval = ext2fs_get_num_dirs(fs, &dblist->size);
83 if (retval)
84 goto cleanup;
85 dblist->size = (dblist->size * 2) + 12;
86 }
87 len = (size_t) sizeof(struct ext2_db_entry) * dblist->size;
88 dblist->count = count;
89 retval = ext2fs_get_mem(len, &dblist->list);
90 if (retval)
91 goto cleanup;
92
93 if (list)
94 memcpy(dblist->list, list, len);
95 else
96 memset(dblist->list, 0, len);
97 if (ret_dblist)
98 *ret_dblist = dblist;
99 else
100 fs->dblist = dblist;
101 return 0;
102cleanup:
103 ext2fs_free_mem(&dblist);
104 return retval;
105}
106
107/*
108 * Initialize a directory block list
109 */
110errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
111{
112 ext2_dblist dblist;
113 errcode_t retval;
114
115 retval = make_dblist(fs, 0, 0, 0, &dblist);
116 if (retval)
117 return retval;
118
119 dblist->sorted = 1;
120 if (ret_dblist)
121 *ret_dblist = dblist;
122 else
123 fs->dblist = dblist;
124
125 return 0;
126}
127
128/*
129 * Copy a directory block list
130 */
131errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest)
132{
133 ext2_dblist dblist;
134 errcode_t retval;
135
136 retval = make_dblist(src->fs, src->size, src->count, src->list,
137 &dblist);
138 if (retval)
139 return retval;
140 dblist->sorted = src->sorted;
141 *dest = dblist;
142 return 0;
143}
144
145/*
146 * Close a directory block list
147 *
148 * (moved to closefs.c)
149 */
150
151
152/*
153 * Add a directory block to the directory block list
154 */
155errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
156 int blockcnt)
157{
158 struct ext2_db_entry *new_entry;
159 errcode_t retval;
160 unsigned long old_size;
161
162 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
163
164 if (dblist->count >= dblist->size) {
165 old_size = dblist->size * sizeof(struct ext2_db_entry);
166 dblist->size += 100;
167 retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
168 sizeof(struct ext2_db_entry),
169 &dblist->list);
170 if (retval) {
171 dblist->size -= 100;
172 return retval;
173 }
174 }
175 new_entry = dblist->list + ( (int) dblist->count++);
176 new_entry->blk = blk;
177 new_entry->ino = ino;
178 new_entry->blockcnt = blockcnt;
179
180 dblist->sorted = 0;
181
182 return 0;
183}
184
185/*
186 * Change the directory block to the directory block list
187 */
188errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
189 int blockcnt)
190{
191 dgrp_t i;
192
193 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
194
195 for (i=0; i < dblist->count; i++) {
196 if ((dblist->list[i].ino != ino) ||
197 (dblist->list[i].blockcnt != blockcnt))
198 continue;
199 dblist->list[i].blk = blk;
200 dblist->sorted = 0;
201 return 0;
202 }
203 return EXT2_ET_DB_NOT_FOUND;
204}
205
206void ext2fs_dblist_sort(ext2_dblist dblist,
207 int (*sortfunc)(const void *,
208 const void *))
209{
210 if (!sortfunc)
211 sortfunc = dir_block_cmp;
212 qsort(dblist->list, (size_t) dblist->count,
213 sizeof(struct ext2_db_entry), sortfunc);
214 dblist->sorted = 1;
215}
216
217/*
218 * This function iterates over the directory block list
219 */
220errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
221 int (*func)(ext2_filsys fs,
222 struct ext2_db_entry *db_info,
223 void *priv_data),
224 void *priv_data)
225{
226 ext2_ino_t i;
227 int ret;
228
229 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
230
231 if (!dblist->sorted)
232 ext2fs_dblist_sort(dblist, 0);
233 for (i=0; i < dblist->count; i++) {
234 ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data);
235 if (ret & DBLIST_ABORT)
236 return 0;
237 }
238 return 0;
239}
240
241static int dir_block_cmp(const void *a, const void *b)
242{
243 const struct ext2_db_entry *db_a =
244 (const struct ext2_db_entry *) a;
245 const struct ext2_db_entry *db_b =
246 (const struct ext2_db_entry *) b;
247
248 if (db_a->blk != db_b->blk)
249 return (int) (db_a->blk - db_b->blk);
250
251 if (db_a->ino != db_b->ino)
252 return (int) (db_a->ino - db_b->ino);
253
254 return (int) (db_a->blockcnt - db_b->blockcnt);
255}
256
257int ext2fs_dblist_count(ext2_dblist dblist)
258{
259 return (int) dblist->count;
260}
diff --git a/e2fsprogs/ext2fs/dblist_dir.c b/e2fsprogs/ext2fs/dblist_dir.c
deleted file mode 100644
index b23920466..000000000
--- a/e2fsprogs/ext2fs/dblist_dir.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dblist_dir.c --- iterate by directory entry
4 *
5 * Copyright 1997 by Theodore Ts'o
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 */
13
14#include <stdio.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <string.h>
19#include <time.h>
20
21#include "ext2_fs.h"
22#include "ext2fsP.h"
23
24static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
25 void *priv_data);
26
27errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist,
28 int flags,
29 char *block_buf,
30 int (*func)(ext2_ino_t dir,
31 int entry,
32 struct ext2_dir_entry *dirent,
33 int offset,
34 int blocksize,
35 char *buf,
36 void *priv_data),
37 void *priv_data)
38{
39 errcode_t retval;
40 struct dir_context ctx;
41
42 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
43
44 ctx.dir = 0;
45 ctx.flags = flags;
46 if (block_buf)
47 ctx.buf = block_buf;
48 else {
49 retval = ext2fs_get_mem(dblist->fs->blocksize, &ctx.buf);
50 if (retval)
51 return retval;
52 }
53 ctx.func = func;
54 ctx.priv_data = priv_data;
55 ctx.errcode = 0;
56
57 retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx);
58
59 if (!block_buf)
60 ext2fs_free_mem(&ctx.buf);
61 if (retval)
62 return retval;
63 return ctx.errcode;
64}
65
66static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
67 void *priv_data)
68{
69 struct dir_context *ctx;
70
71 ctx = (struct dir_context *) priv_data;
72 ctx->dir = db_info->ino;
73
74 return ext2fs_process_dir_block(fs, &db_info->blk,
75 db_info->blockcnt, 0, 0, priv_data);
76}
diff --git a/e2fsprogs/ext2fs/dir_iterate.c b/e2fsprogs/ext2fs/dir_iterate.c
deleted file mode 100644
index b7d873595..000000000
--- a/e2fsprogs/ext2fs/dir_iterate.c
+++ /dev/null
@@ -1,220 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dir_iterate.c --- ext2fs directory iteration operations
4 *
5 * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#if HAVE_ERRNO_H
19#include <errno.h>
20#endif
21
22#include "ext2_fs.h"
23#include "ext2fsP.h"
24
25/*
26 * This function checks to see whether or not a potential deleted
27 * directory entry looks valid. What we do is check the deleted entry
28 * and each successive entry to make sure that they all look valid and
29 * that the last deleted entry ends at the beginning of the next
30 * undeleted entry. Returns 1 if the deleted entry looks valid, zero
31 * if not valid.
32 */
33static int ext2fs_validate_entry(char *buf, int offset, int final_offset)
34{
35 struct ext2_dir_entry *dirent;
36
37 while (offset < final_offset) {
38 dirent = (struct ext2_dir_entry *)(buf + offset);
39 offset += dirent->rec_len;
40 if ((dirent->rec_len < 8) ||
41 ((dirent->rec_len % 4) != 0) ||
42 (((dirent->name_len & 0xFF)+8) > dirent->rec_len))
43 return 0;
44 }
45 return (offset == final_offset);
46}
47
48errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
49 ext2_ino_t dir,
50 int flags,
51 char *block_buf,
52 int (*func)(ext2_ino_t dir,
53 int entry,
54 struct ext2_dir_entry *dirent,
55 int offset,
56 int blocksize,
57 char *buf,
58 void *priv_data),
59 void *priv_data)
60{
61 struct dir_context ctx;
62 errcode_t retval;
63
64 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
65
66 retval = ext2fs_check_directory(fs, dir);
67 if (retval)
68 return retval;
69
70 ctx.dir = dir;
71 ctx.flags = flags;
72 if (block_buf)
73 ctx.buf = block_buf;
74 else {
75 retval = ext2fs_get_mem(fs->blocksize, &ctx.buf);
76 if (retval)
77 return retval;
78 }
79 ctx.func = func;
80 ctx.priv_data = priv_data;
81 ctx.errcode = 0;
82 retval = ext2fs_block_iterate2(fs, dir, 0, 0,
83 ext2fs_process_dir_block, &ctx);
84 if (!block_buf)
85 ext2fs_free_mem(&ctx.buf);
86 if (retval)
87 return retval;
88 return ctx.errcode;
89}
90
91struct xlate {
92 int (*func)(struct ext2_dir_entry *dirent,
93 int offset,
94 int blocksize,
95 char *buf,
96 void *priv_data);
97 void *real_private;
98};
99
100static int xlate_func(ext2_ino_t dir EXT2FS_ATTR((unused)),
101 int entry EXT2FS_ATTR((unused)),
102 struct ext2_dir_entry *dirent, int offset,
103 int blocksize, char *buf, void *priv_data)
104{
105 struct xlate *xl = (struct xlate *) priv_data;
106
107 return (*xl->func)(dirent, offset, blocksize, buf, xl->real_private);
108}
109
110extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
111 ext2_ino_t dir,
112 int flags,
113 char *block_buf,
114 int (*func)(struct ext2_dir_entry *dirent,
115 int offset,
116 int blocksize,
117 char *buf,
118 void *priv_data),
119 void *priv_data)
120{
121 struct xlate xl;
122
123 xl.real_private = priv_data;
124 xl.func = func;
125
126 return ext2fs_dir_iterate2(fs, dir, flags, block_buf,
127 xlate_func, &xl);
128}
129
130
131/*
132 * Helper function which is private to this module. Used by
133 * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate()
134 */
135int ext2fs_process_dir_block(ext2_filsys fs,
136 blk_t *blocknr,
137 e2_blkcnt_t blockcnt,
138 blk_t ref_block EXT2FS_ATTR((unused)),
139 int ref_offset EXT2FS_ATTR((unused)),
140 void *priv_data)
141{
142 struct dir_context *ctx = (struct dir_context *) priv_data;
143 unsigned int offset = 0;
144 unsigned int next_real_entry = 0;
145 int ret = 0;
146 int changed = 0;
147 int do_abort = 0;
148 int entry, size;
149 struct ext2_dir_entry *dirent;
150
151 if (blockcnt < 0)
152 return 0;
153
154 entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
155
156 ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf);
157 if (ctx->errcode)
158 return BLOCK_ABORT;
159
160 while (offset < fs->blocksize) {
161 dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
162 if (((offset + dirent->rec_len) > fs->blocksize) ||
163 (dirent->rec_len < 8) ||
164 ((dirent->rec_len % 4) != 0) ||
165 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
166 ctx->errcode = EXT2_ET_DIR_CORRUPTED;
167 return BLOCK_ABORT;
168 }
169 if (!dirent->inode &&
170 !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
171 goto next;
172
173 ret = (ctx->func)(ctx->dir,
174 (next_real_entry > offset) ?
175 DIRENT_DELETED_FILE : entry,
176 dirent, offset,
177 fs->blocksize, ctx->buf,
178 ctx->priv_data);
179 if (entry < DIRENT_OTHER_FILE)
180 entry++;
181
182 if (ret & DIRENT_CHANGED)
183 changed++;
184 if (ret & DIRENT_ABORT) {
185 do_abort++;
186 break;
187 }
188next:
189 if (next_real_entry == offset)
190 next_real_entry += dirent->rec_len;
191
192 if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) {
193 size = ((dirent->name_len & 0xFF) + 11) & ~3;
194
195 if (dirent->rec_len != size) {
196 unsigned int final_offset;
197
198 final_offset = offset + dirent->rec_len;
199 offset += size;
200 while (offset < final_offset &&
201 !ext2fs_validate_entry(ctx->buf,
202 offset,
203 final_offset))
204 offset += 4;
205 continue;
206 }
207 }
208 offset += dirent->rec_len;
209 }
210
211 if (changed) {
212 ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf);
213 if (ctx->errcode)
214 return BLOCK_ABORT;
215 }
216 if (do_abort)
217 return BLOCK_ABORT;
218 return 0;
219}
220
diff --git a/e2fsprogs/ext2fs/dirblock.c b/e2fsprogs/ext2fs/dirblock.c
deleted file mode 100644
index 5d3f6a1bc..000000000
--- a/e2fsprogs/ext2fs/dirblock.c
+++ /dev/null
@@ -1,133 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dirblock.c --- directory block routines.
4 *
5 * Copyright (C) 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17#include <string.h>
18#include <time.h>
19
20#include "ext2_fs.h"
21#include "ext2fs.h"
22
23errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
24 void *buf, int flags EXT2FS_ATTR((unused)))
25{
26 errcode_t retval;
27 char *p, *end;
28 struct ext2_dir_entry *dirent;
29 unsigned int name_len, rec_len;
30#if BB_BIG_ENDIAN
31 unsigned int do_swap;
32#endif
33
34 retval = io_channel_read_blk(fs->io, block, 1, buf);
35 if (retval)
36 return retval;
37#if BB_BIG_ENDIAN
38 do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
39 EXT2_FLAG_SWAP_BYTES_READ)) != 0;
40#endif
41 p = (char *) buf;
42 end = (char *) buf + fs->blocksize;
43 while (p < end-8) {
44 dirent = (struct ext2_dir_entry *) p;
45#if BB_BIG_ENDIAN
46 if (do_swap) {
47 dirent->inode = ext2fs_swab32(dirent->inode);
48 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
49 dirent->name_len = ext2fs_swab16(dirent->name_len);
50 }
51#endif
52 name_len = dirent->name_len;
53#ifdef WORDS_BIGENDIAN
54 if (flags & EXT2_DIRBLOCK_V2_STRUCT)
55 dirent->name_len = ext2fs_swab16(dirent->name_len);
56#endif
57 rec_len = dirent->rec_len;
58 if ((rec_len < 8) || (rec_len % 4)) {
59 rec_len = 8;
60 retval = EXT2_ET_DIR_CORRUPTED;
61 }
62 if (((name_len & 0xFF) + 8) > dirent->rec_len)
63 retval = EXT2_ET_DIR_CORRUPTED;
64 p += rec_len;
65 }
66 return retval;
67}
68
69errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
70 void *buf)
71{
72 return ext2fs_read_dir_block2(fs, block, buf, 0);
73}
74
75
76errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
77 void *inbuf, int flags EXT2FS_ATTR((unused)))
78{
79#if BB_BIG_ENDIAN
80 int do_swap = 0;
81 errcode_t retval;
82 char *p, *end;
83 char *buf = 0;
84 struct ext2_dir_entry *dirent;
85
86 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
87 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
88 do_swap = 1;
89
90#ifndef WORDS_BIGENDIAN
91 if (!do_swap)
92 return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
93#endif
94
95 retval = ext2fs_get_mem(fs->blocksize, &buf);
96 if (retval)
97 return retval;
98 memcpy(buf, inbuf, fs->blocksize);
99 p = buf;
100 end = buf + fs->blocksize;
101 while (p < end) {
102 dirent = (struct ext2_dir_entry *) p;
103 if ((dirent->rec_len < 8) ||
104 (dirent->rec_len % 4)) {
105 ext2fs_free_mem(&buf);
106 return EXT2_ET_DIR_CORRUPTED;
107 }
108 p += dirent->rec_len;
109 if (do_swap) {
110 dirent->inode = ext2fs_swab32(dirent->inode);
111 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
112 dirent->name_len = ext2fs_swab16(dirent->name_len);
113 }
114#ifdef WORDS_BIGENDIAN
115 if (flags & EXT2_DIRBLOCK_V2_STRUCT)
116 dirent->name_len = ext2fs_swab16(dirent->name_len);
117#endif
118 }
119 retval = io_channel_write_blk(fs->io, block, 1, buf);
120 ext2fs_free_mem(&buf);
121 return retval;
122#else
123 return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
124#endif
125}
126
127
128errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
129 void *inbuf)
130{
131 return ext2fs_write_dir_block2(fs, block, inbuf, 0);
132}
133
diff --git a/e2fsprogs/ext2fs/dirhash.c b/e2fsprogs/ext2fs/dirhash.c
deleted file mode 100644
index ab3243fd7..000000000
--- a/e2fsprogs/ext2fs/dirhash.c
+++ /dev/null
@@ -1,234 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dirhash.c -- Calculate the hash of a directory entry
4 *
5 * Copyright (c) 2001 Daniel Phillips
6 *
7 * Copyright (c) 2002 Theodore Ts'o.
8 *
9 * %Begin-Header%
10 * This file may be redistributed under the terms of the GNU Public
11 * License.
12 * %End-Header%
13 */
14
15#include <stdio.h>
16#include <string.h>
17
18#include "ext2_fs.h"
19#include "ext2fs.h"
20
21/*
22 * Keyed 32-bit hash function using TEA in a Davis-Meyer function
23 * H0 = Key
24 * Hi = E Mi(Hi-1) + Hi-1
25 *
26 * (see Applied Cryptography, 2nd edition, p448).
27 *
28 * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
29 *
30 * This code is made available under the terms of the GPL
31 */
32#define DELTA 0x9E3779B9
33
34static void TEA_transform(__u32 buf[4], __u32 const in[])
35{
36 __u32 sum = 0;
37 __u32 b0 = buf[0], b1 = buf[1];
38 __u32 a = in[0], b = in[1], c = in[2], d = in[3];
39 int n = 16;
40
41 do {
42 sum += DELTA;
43 b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
44 b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
45 } while(--n);
46
47 buf[0] += b0;
48 buf[1] += b1;
49}
50
51/* F, G and H are basic MD4 functions: selection, majority, parity */
52#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
53#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
54#define H(x, y, z) ((x) ^ (y) ^ (z))
55
56/*
57 * The generic round function. The application is so specific that
58 * we don't bother protecting all the arguments with parens, as is generally
59 * good macro practice, in favor of extra legibility.
60 * Rotation is separate from addition to prevent recomputation
61 */
62#define ROUND(f, a, b, c, d, x, s) \
63 (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
64#define K1 0
65#define K2 013240474631UL
66#define K3 015666365641UL
67
68/*
69 * Basic cut-down MD4 transform. Returns only 32 bits of result.
70 */
71static void halfMD4Transform (__u32 buf[4], __u32 const in[])
72{
73 __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
74
75 /* Round 1 */
76 ROUND(F, a, b, c, d, in[0] + K1, 3);
77 ROUND(F, d, a, b, c, in[1] + K1, 7);
78 ROUND(F, c, d, a, b, in[2] + K1, 11);
79 ROUND(F, b, c, d, a, in[3] + K1, 19);
80 ROUND(F, a, b, c, d, in[4] + K1, 3);
81 ROUND(F, d, a, b, c, in[5] + K1, 7);
82 ROUND(F, c, d, a, b, in[6] + K1, 11);
83 ROUND(F, b, c, d, a, in[7] + K1, 19);
84
85 /* Round 2 */
86 ROUND(G, a, b, c, d, in[1] + K2, 3);
87 ROUND(G, d, a, b, c, in[3] + K2, 5);
88 ROUND(G, c, d, a, b, in[5] + K2, 9);
89 ROUND(G, b, c, d, a, in[7] + K2, 13);
90 ROUND(G, a, b, c, d, in[0] + K2, 3);
91 ROUND(G, d, a, b, c, in[2] + K2, 5);
92 ROUND(G, c, d, a, b, in[4] + K2, 9);
93 ROUND(G, b, c, d, a, in[6] + K2, 13);
94
95 /* Round 3 */
96 ROUND(H, a, b, c, d, in[3] + K3, 3);
97 ROUND(H, d, a, b, c, in[7] + K3, 9);
98 ROUND(H, c, d, a, b, in[2] + K3, 11);
99 ROUND(H, b, c, d, a, in[6] + K3, 15);
100 ROUND(H, a, b, c, d, in[1] + K3, 3);
101 ROUND(H, d, a, b, c, in[5] + K3, 9);
102 ROUND(H, c, d, a, b, in[0] + K3, 11);
103 ROUND(H, b, c, d, a, in[4] + K3, 15);
104
105 buf[0] += a;
106 buf[1] += b;
107 buf[2] += c;
108 buf[3] += d;
109}
110
111#undef ROUND
112#undef F
113#undef G
114#undef H
115#undef K1
116#undef K2
117#undef K3
118
119/* The old legacy hash */
120static ext2_dirhash_t dx_hack_hash (const char *name, int len)
121{
122 __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
123 while (len--) {
124 __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
125
126 if (hash & 0x80000000) hash -= 0x7fffffff;
127 hash1 = hash0;
128 hash0 = hash;
129 }
130 return (hash0 << 1);
131}
132
133static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
134{
135 __u32 pad, val;
136 int i;
137
138 pad = (__u32)len | ((__u32)len << 8);
139 pad |= pad << 16;
140
141 val = pad;
142 if (len > num*4)
143 len = num * 4;
144 for (i=0; i < len; i++) {
145 if ((i % 4) == 0)
146 val = pad;
147 val = msg[i] + (val << 8);
148 if ((i % 4) == 3) {
149 *buf++ = val;
150 val = pad;
151 num--;
152 }
153 }
154 if (--num >= 0)
155 *buf++ = val;
156 while (--num >= 0)
157 *buf++ = pad;
158}
159
160/*
161 * Returns the hash of a filename. If len is 0 and name is NULL, then
162 * this function can be used to test whether or not a hash version is
163 * supported.
164 *
165 * The seed is an 4 longword (32 bits) "secret" which can be used to
166 * uniquify a hash. If the seed is all zero's, then some default seed
167 * may be used.
168 *
169 * A particular hash version specifies whether or not the seed is
170 * represented, and whether or not the returned hash is 32 bits or 64
171 * bits. 32 bit hashes will return 0 for the minor hash.
172 */
173errcode_t ext2fs_dirhash(int version, const char *name, int len,
174 const __u32 *seed,
175 ext2_dirhash_t *ret_hash,
176 ext2_dirhash_t *ret_minor_hash)
177{
178 __u32 hash;
179 __u32 minor_hash = 0;
180 const char *p;
181 int i;
182 __u32 in[8], buf[4];
183
184 /* Initialize the default seed for the hash checksum functions */
185 buf[0] = 0x67452301;
186 buf[1] = 0xefcdab89;
187 buf[2] = 0x98badcfe;
188 buf[3] = 0x10325476;
189
190 /* Check to see if the seed is all zero's */
191 if (seed) {
192 for (i=0; i < 4; i++) {
193 if (seed[i])
194 break;
195 }
196 if (i < 4)
197 memcpy(buf, seed, sizeof(buf));
198 }
199
200 switch (version) {
201 case EXT2_HASH_LEGACY:
202 hash = dx_hack_hash(name, len);
203 break;
204 case EXT2_HASH_HALF_MD4:
205 p = name;
206 while (len > 0) {
207 str2hashbuf(p, len, in, 8);
208 halfMD4Transform(buf, in);
209 len -= 32;
210 p += 32;
211 }
212 minor_hash = buf[2];
213 hash = buf[1];
214 break;
215 case EXT2_HASH_TEA:
216 p = name;
217 while (len > 0) {
218 str2hashbuf(p, len, in, 4);
219 TEA_transform(buf, in);
220 len -= 16;
221 p += 16;
222 }
223 hash = buf[0];
224 minor_hash = buf[1];
225 break;
226 default:
227 *ret_hash = 0;
228 return EXT2_ET_DIRHASH_UNSUPP;
229 }
230 *ret_hash = hash & ~1;
231 if (ret_minor_hash)
232 *ret_minor_hash = minor_hash;
233 return 0;
234}
diff --git a/e2fsprogs/ext2fs/dupfs.c b/e2fsprogs/ext2fs/dupfs.c
deleted file mode 100644
index 203c29fe3..000000000
--- a/e2fsprogs/ext2fs/dupfs.c
+++ /dev/null
@@ -1,97 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * dupfs.c --- duplicate a ext2 filesystem handle
4 *
5 * Copyright (C) 1997, 1998, 2001, 2003, 2005 by Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17#include <time.h>
18#include <string.h>
19
20#include "ext2_fs.h"
21#include "ext2fsP.h"
22
23errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
24{
25 ext2_filsys fs;
26 errcode_t retval;
27
28 EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS);
29
30 retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
31 if (retval)
32 return retval;
33
34 *fs = *src;
35 fs->device_name = 0;
36 fs->super = 0;
37 fs->orig_super = 0;
38 fs->group_desc = 0;
39 fs->inode_map = 0;
40 fs->block_map = 0;
41 fs->badblocks = 0;
42 fs->dblist = 0;
43
44 io_channel_bumpcount(fs->io);
45 if (fs->icache)
46 fs->icache->refcount++;
47
48 retval = ext2fs_get_mem(strlen(src->device_name)+1, &fs->device_name);
49 if (retval)
50 goto errout;
51 strcpy(fs->device_name, src->device_name);
52
53 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
54 if (retval)
55 goto errout;
56 memcpy(fs->super, src->super, SUPERBLOCK_SIZE);
57
58 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
59 if (retval)
60 goto errout;
61 memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE);
62
63 retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
64 &fs->group_desc);
65 if (retval)
66 goto errout;
67 memcpy(fs->group_desc, src->group_desc,
68 (size_t) fs->desc_blocks * fs->blocksize);
69
70 if (src->inode_map) {
71 retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
72 if (retval)
73 goto errout;
74 }
75 if (src->block_map) {
76 retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map);
77 if (retval)
78 goto errout;
79 }
80 if (src->badblocks) {
81 retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
82 if (retval)
83 goto errout;
84 }
85 if (src->dblist) {
86 retval = ext2fs_copy_dblist(src->dblist, &fs->dblist);
87 if (retval)
88 goto errout;
89 }
90 *dest = fs;
91 return 0;
92errout:
93 ext2fs_free(fs);
94 return retval;
95
96}
97
diff --git a/e2fsprogs/ext2fs/e2image.h b/e2fsprogs/ext2fs/e2image.h
deleted file mode 100644
index 8d38ecc13..000000000
--- a/e2fsprogs/ext2fs/e2image.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * e2image.h --- header file describing the ext2 image format
4 *
5 * Copyright (C) 2000 Theodore Ts'o.
6 *
7 * Note: this uses the POSIX IO interfaces, unlike most of the other
8 * functions in this library. So sue me.
9 *
10 * %Begin-Header%
11 * This file may be redistributed under the terms of the GNU Public
12 * License.
13 * %End-Header%
14 */
15
16
17struct ext2_image_hdr {
18 __u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */
19 char magic_descriptor[16]; /* "Ext2 Image 1.0", w/ null padding */
20 char fs_hostname[64];/* Hostname of machine of image */
21 char fs_netaddr[32]; /* Network address */
22 __u32 fs_netaddr_type;/* 0 = IPV4, 1 = IPV6, etc. */
23 __u32 fs_device; /* Device number of image */
24 char fs_device_name[64]; /* Device name */
25 char fs_uuid[16]; /* UUID of filesystem */
26 __u32 fs_blocksize; /* Block size of the filesystem */
27 __u32 fs_reserved[8];
28
29 __u32 image_device; /* Device number of image file */
30 __u32 image_inode; /* Inode number of image file */
31 __u32 image_time; /* Time of image creation */
32 __u32 image_reserved[8];
33
34 __u32 offset_super; /* Byte offset of the sb and descriptors */
35 __u32 offset_inode; /* Byte offset of the inode table */
36 __u32 offset_inodemap; /* Byte offset of the inode bitmaps */
37 __u32 offset_blockmap; /* Byte offset of the inode bitmaps */
38 __u32 offset_reserved[8];
39};
40
41
42
43
44
45
46
47
48
49
50
51
52
diff --git a/e2fsprogs/ext2fs/expanddir.c b/e2fsprogs/ext2fs/expanddir.c
deleted file mode 100644
index 8a29ae584..000000000
--- a/e2fsprogs/ext2fs/expanddir.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * expand.c --- expand an ext2fs directory
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct expand_dir_struct {
23 int done;
24 int newblocks;
25 errcode_t err;
26};
27
28static int expand_dir_proc(ext2_filsys fs,
29 blk_t *blocknr,
30 e2_blkcnt_t blockcnt,
31 blk_t ref_block EXT2FS_ATTR((unused)),
32 int ref_offset EXT2FS_ATTR((unused)),
33 void *priv_data)
34{
35 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
36 blk_t new_blk;
37 static blk_t last_blk = 0;
38 char *block;
39 errcode_t retval;
40
41 if (*blocknr) {
42 last_blk = *blocknr;
43 return 0;
44 }
45 retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
46 if (retval) {
47 es->err = retval;
48 return BLOCK_ABORT;
49 }
50 if (blockcnt > 0) {
51 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
52 if (retval) {
53 es->err = retval;
54 return BLOCK_ABORT;
55 }
56 es->done = 1;
57 retval = ext2fs_write_dir_block(fs, new_blk, block);
58 } else {
59 retval = ext2fs_get_mem(fs->blocksize, &block);
60 if (retval) {
61 es->err = retval;
62 return BLOCK_ABORT;
63 }
64 memset(block, 0, fs->blocksize);
65 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
66 }
67 if (retval) {
68 es->err = retval;
69 return BLOCK_ABORT;
70 }
71 ext2fs_free_mem(&block);
72 *blocknr = new_blk;
73 ext2fs_block_alloc_stats(fs, new_blk, +1);
74 es->newblocks++;
75
76 if (es->done)
77 return (BLOCK_CHANGED | BLOCK_ABORT);
78 else
79 return BLOCK_CHANGED;
80}
81
82errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
83{
84 errcode_t retval;
85 struct expand_dir_struct es;
86 struct ext2_inode inode;
87
88 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
89
90 if (!(fs->flags & EXT2_FLAG_RW))
91 return EXT2_ET_RO_FILSYS;
92
93 if (!fs->block_map)
94 return EXT2_ET_NO_BLOCK_BITMAP;
95
96 retval = ext2fs_check_directory(fs, dir);
97 if (retval)
98 return retval;
99
100 es.done = 0;
101 es.err = 0;
102 es.newblocks = 0;
103
104 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
105 0, expand_dir_proc, &es);
106
107 if (es.err)
108 return es.err;
109 if (!es.done)
110 return EXT2_ET_EXPAND_DIR_ERR;
111
112 /*
113 * Update the size and block count fields in the inode.
114 */
115 retval = ext2fs_read_inode(fs, dir, &inode);
116 if (retval)
117 return retval;
118
119 inode.i_size += fs->blocksize;
120 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
121
122 retval = ext2fs_write_inode(fs, dir, &inode);
123 if (retval)
124 return retval;
125
126 return 0;
127}
diff --git a/e2fsprogs/ext2fs/ext2_err.h b/e2fsprogs/ext2fs/ext2_err.h
deleted file mode 100644
index ead352810..000000000
--- a/e2fsprogs/ext2fs/ext2_err.h
+++ /dev/null
@@ -1,116 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ext2_err.h:
4 * This file is automatically generated; please do not edit it.
5 */
6
7#define EXT2_ET_BASE (2133571328L)
8#define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L)
9#define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L)
10#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE (2133571331L)
11#define EXT2_ET_MAGIC_INODE_SCAN (2133571332L)
12#define EXT2_ET_MAGIC_IO_CHANNEL (2133571333L)
13#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL (2133571334L)
14#define EXT2_ET_MAGIC_IO_MANAGER (2133571335L)
15#define EXT2_ET_MAGIC_BLOCK_BITMAP (2133571336L)
16#define EXT2_ET_MAGIC_INODE_BITMAP (2133571337L)
17#define EXT2_ET_MAGIC_GENERIC_BITMAP (2133571338L)
18#define EXT2_ET_MAGIC_TEST_IO_CHANNEL (2133571339L)
19#define EXT2_ET_MAGIC_DBLIST (2133571340L)
20#define EXT2_ET_MAGIC_ICOUNT (2133571341L)
21#define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L)
22#define EXT2_ET_MAGIC_EXT2_FILE (2133571343L)
23#define EXT2_ET_MAGIC_E2IMAGE (2133571344L)
24#define EXT2_ET_MAGIC_INODE_IO_CHANNEL (2133571345L)
25#define EXT2_ET_MAGIC_RESERVED_9 (2133571346L)
26#define EXT2_ET_BAD_MAGIC (2133571347L)
27#define EXT2_ET_REV_TOO_HIGH (2133571348L)
28#define EXT2_ET_RO_FILSYS (2133571349L)
29#define EXT2_ET_GDESC_READ (2133571350L)
30#define EXT2_ET_GDESC_WRITE (2133571351L)
31#define EXT2_ET_GDESC_BAD_BLOCK_MAP (2133571352L)
32#define EXT2_ET_GDESC_BAD_INODE_MAP (2133571353L)
33#define EXT2_ET_GDESC_BAD_INODE_TABLE (2133571354L)
34#define EXT2_ET_INODE_BITMAP_WRITE (2133571355L)
35#define EXT2_ET_INODE_BITMAP_READ (2133571356L)
36#define EXT2_ET_BLOCK_BITMAP_WRITE (2133571357L)
37#define EXT2_ET_BLOCK_BITMAP_READ (2133571358L)
38#define EXT2_ET_INODE_TABLE_WRITE (2133571359L)
39#define EXT2_ET_INODE_TABLE_READ (2133571360L)
40#define EXT2_ET_NEXT_INODE_READ (2133571361L)
41#define EXT2_ET_UNEXPECTED_BLOCK_SIZE (2133571362L)
42#define EXT2_ET_DIR_CORRUPTED (2133571363L)
43#define EXT2_ET_SHORT_READ (2133571364L)
44#define EXT2_ET_SHORT_WRITE (2133571365L)
45#define EXT2_ET_DIR_NO_SPACE (2133571366L)
46#define EXT2_ET_NO_INODE_BITMAP (2133571367L)
47#define EXT2_ET_NO_BLOCK_BITMAP (2133571368L)
48#define EXT2_ET_BAD_INODE_NUM (2133571369L)
49#define EXT2_ET_BAD_BLOCK_NUM (2133571370L)
50#define EXT2_ET_EXPAND_DIR_ERR (2133571371L)
51#define EXT2_ET_TOOSMALL (2133571372L)
52#define EXT2_ET_BAD_BLOCK_MARK (2133571373L)
53#define EXT2_ET_BAD_BLOCK_UNMARK (2133571374L)
54#define EXT2_ET_BAD_BLOCK_TEST (2133571375L)
55#define EXT2_ET_BAD_INODE_MARK (2133571376L)
56#define EXT2_ET_BAD_INODE_UNMARK (2133571377L)
57#define EXT2_ET_BAD_INODE_TEST (2133571378L)
58#define EXT2_ET_FUDGE_BLOCK_BITMAP_END (2133571379L)
59#define EXT2_ET_FUDGE_INODE_BITMAP_END (2133571380L)
60#define EXT2_ET_BAD_IND_BLOCK (2133571381L)
61#define EXT2_ET_BAD_DIND_BLOCK (2133571382L)
62#define EXT2_ET_BAD_TIND_BLOCK (2133571383L)
63#define EXT2_ET_NEQ_BLOCK_BITMAP (2133571384L)
64#define EXT2_ET_NEQ_INODE_BITMAP (2133571385L)
65#define EXT2_ET_BAD_DEVICE_NAME (2133571386L)
66#define EXT2_ET_MISSING_INODE_TABLE (2133571387L)
67#define EXT2_ET_CORRUPT_SUPERBLOCK (2133571388L)
68#define EXT2_ET_BAD_GENERIC_MARK (2133571389L)
69#define EXT2_ET_BAD_GENERIC_UNMARK (2133571390L)
70#define EXT2_ET_BAD_GENERIC_TEST (2133571391L)
71#define EXT2_ET_SYMLINK_LOOP (2133571392L)
72#define EXT2_ET_CALLBACK_NOTHANDLED (2133571393L)
73#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE (2133571394L)
74#define EXT2_ET_UNSUPP_FEATURE (2133571395L)
75#define EXT2_ET_RO_UNSUPP_FEATURE (2133571396L)
76#define EXT2_ET_LLSEEK_FAILED (2133571397L)
77#define EXT2_ET_NO_MEMORY (2133571398L)
78#define EXT2_ET_INVALID_ARGUMENT (2133571399L)
79#define EXT2_ET_BLOCK_ALLOC_FAIL (2133571400L)
80#define EXT2_ET_INODE_ALLOC_FAIL (2133571401L)
81#define EXT2_ET_NO_DIRECTORY (2133571402L)
82#define EXT2_ET_TOO_MANY_REFS (2133571403L)
83#define EXT2_ET_FILE_NOT_FOUND (2133571404L)
84#define EXT2_ET_FILE_RO (2133571405L)
85#define EXT2_ET_DB_NOT_FOUND (2133571406L)
86#define EXT2_ET_DIR_EXISTS (2133571407L)
87#define EXT2_ET_UNIMPLEMENTED (2133571408L)
88#define EXT2_ET_CANCEL_REQUESTED (2133571409L)
89#define EXT2_ET_FILE_TOO_BIG (2133571410L)
90#define EXT2_ET_JOURNAL_NOT_BLOCK (2133571411L)
91#define EXT2_ET_NO_JOURNAL_SB (2133571412L)
92#define EXT2_ET_JOURNAL_TOO_SMALL (2133571413L)
93#define EXT2_ET_JOURNAL_UNSUPP_VERSION (2133571414L)
94#define EXT2_ET_LOAD_EXT_JOURNAL (2133571415L)
95#define EXT2_ET_NO_JOURNAL (2133571416L)
96#define EXT2_ET_DIRHASH_UNSUPP (2133571417L)
97#define EXT2_ET_BAD_EA_BLOCK_NUM (2133571418L)
98#define EXT2_ET_TOO_MANY_INODES (2133571419L)
99#define EXT2_ET_NOT_IMAGE_FILE (2133571420L)
100#define EXT2_ET_RES_GDT_BLOCKS (2133571421L)
101#define EXT2_ET_RESIZE_INODE_CORRUPT (2133571422L)
102#define EXT2_ET_SET_BMAP_NO_IND (2133571423L)
103
104#if 0
105extern const struct error_table et_ext2_error_table;
106extern void initialize_ext2_error_table(void);
107
108/* For compatibility with Heimdal */
109extern void initialize_ext2_error_table_r(struct et_list **list);
110
111#define ERROR_TABLE_BASE_ext2 (2133571328L)
112
113/* for compatibility with older versions... */
114#define init_ext2_err_tbl initialize_ext2_error_table
115#define ext2_err_base ERROR_TABLE_BASE_ext2
116#endif
diff --git a/e2fsprogs/ext2fs/ext2_ext_attr.h b/e2fsprogs/ext2fs/ext2_ext_attr.h
deleted file mode 100644
index cc91bb8d6..000000000
--- a/e2fsprogs/ext2fs/ext2_ext_attr.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 File: linux/ext2_ext_attr.h
4
5 On-disk format of extended attributes for the ext2 filesystem.
6
7 (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
8*/
9
10/* Magic value in attribute blocks */
11#define EXT2_EXT_ATTR_MAGIC_v1 0xEA010000
12#define EXT2_EXT_ATTR_MAGIC 0xEA020000
13
14/* Maximum number of references to one attribute block */
15#define EXT2_EXT_ATTR_REFCOUNT_MAX 1024
16
17struct ext2_ext_attr_header {
18 __u32 h_magic; /* magic number for identification */
19 __u32 h_refcount; /* reference count */
20 __u32 h_blocks; /* number of disk blocks used */
21 __u32 h_hash; /* hash value of all attributes */
22 __u32 h_reserved[4]; /* zero right now */
23};
24
25struct ext2_ext_attr_entry {
26 __u8 e_name_len; /* length of name */
27 __u8 e_name_index; /* attribute name index */
28 __u16 e_value_offs; /* offset in disk block of value */
29 __u32 e_value_block; /* disk block attribute is stored on (n/i) */
30 __u32 e_value_size; /* size of attribute value */
31 __u32 e_hash; /* hash value of name and value */
32};
33
34#define EXT2_EXT_ATTR_PAD_BITS 2
35#define EXT2_EXT_ATTR_PAD (1<<EXT2_EXT_ATTR_PAD_BITS)
36#define EXT2_EXT_ATTR_ROUND (EXT2_EXT_ATTR_PAD-1)
37#define EXT2_EXT_ATTR_LEN(name_len) \
38 (((name_len) + EXT2_EXT_ATTR_ROUND + \
39 sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
40#define EXT2_EXT_ATTR_NEXT(entry) \
41 ( (struct ext2_ext_attr_entry *)( \
42 (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) )
43#define EXT2_EXT_ATTR_SIZE(size) \
44 (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
45#define EXT2_EXT_IS_LAST_ENTRY(entry) (*((__u32 *)(entry)) == 0UL)
46#define EXT2_EXT_ATTR_NAME(entry) \
47 (((char *) (entry)) + sizeof(struct ext2_ext_attr_entry))
48#define EXT2_XATTR_LEN(name_len) \
49 (((name_len) + EXT2_EXT_ATTR_ROUND + \
50 sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND)
51#define EXT2_XATTR_SIZE(size) \
52 (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
53
diff --git a/e2fsprogs/ext2fs/ext2_fs.h b/e2fsprogs/ext2fs/ext2_fs.h
deleted file mode 100644
index cb49d7a60..000000000
--- a/e2fsprogs/ext2fs/ext2_fs.h
+++ /dev/null
@@ -1,570 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * linux/include/linux/ext2_fs.h
4 *
5 * Copyright (C) 1992, 1993, 1994, 1995
6 * Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)
9 *
10 * from
11 *
12 * linux/include/linux/minix_fs.h
13 *
14 * Copyright (C) 1991, 1992 Linus Torvalds
15 */
16
17#ifndef _LINUX_EXT2_FS_H
18#define _LINUX_EXT2_FS_H
19
20#include "ext2_types.h" /* Changed from linux/types.h */
21
22/*
23 * Special inode numbers
24 */
25#define EXT2_BAD_INO 1 /* Bad blocks inode */
26#define EXT2_ROOT_INO 2 /* Root inode */
27#define EXT2_ACL_IDX_INO 3 /* ACL inode */
28#define EXT2_ACL_DATA_INO 4 /* ACL inode */
29#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */
30#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */
31#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */
32#define EXT2_JOURNAL_INO 8 /* Journal inode */
33
34/* First non-reserved inode for old ext2 filesystems */
35#define EXT2_GOOD_OLD_FIRST_INO 11
36
37/*
38 * The second extended file system magic number
39 */
40#define EXT2_SUPER_MAGIC 0xEF53
41
42/* Assume that user mode programs are passing in an ext2fs superblock, not
43 * a kernel struct super_block. This will allow us to call the feature-test
44 * macros from user land. */
45#define EXT2_SB(sb) (sb)
46
47/*
48 * Maximal count of links to a file
49 */
50#define EXT2_LINK_MAX 32000
51
52/*
53 * Macro-instructions used to manage several block sizes
54 */
55#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
56#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */
57#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE)
58#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE)
59#define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
60#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
61#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
62 EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
63#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
64 EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino)
65#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(__u32))
66
67/*
68 * Macro-instructions used to manage fragments
69 */
70#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE
71#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE
72#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE
73# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
74# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
75
76/*
77 * ACL structures
78 */
79struct ext2_acl_header /* Header of Access Control Lists */
80{
81 __u32 aclh_size;
82 __u32 aclh_file_count;
83 __u32 aclh_acle_count;
84 __u32 aclh_first_acle;
85};
86
87struct ext2_acl_entry /* Access Control List Entry */
88{
89 __u32 acle_size;
90 __u16 acle_perms; /* Access permissions */
91 __u16 acle_type; /* Type of entry */
92 __u16 acle_tag; /* User or group identity */
93 __u16 acle_pad1;
94 __u32 acle_next; /* Pointer on next entry for the */
95 /* same inode or on next free entry */
96};
97
98/*
99 * Structure of a blocks group descriptor
100 */
101struct ext2_group_desc
102{
103 __u32 bg_block_bitmap; /* Blocks bitmap block */
104 __u32 bg_inode_bitmap; /* Inodes bitmap block */
105 __u32 bg_inode_table; /* Inodes table block */
106 __u16 bg_free_blocks_count; /* Free blocks count */
107 __u16 bg_free_inodes_count; /* Free inodes count */
108 __u16 bg_used_dirs_count; /* Directories count */
109 __u16 bg_pad;
110 __u32 bg_reserved[3];
111};
112
113/*
114 * Data structures used by the directory indexing feature
115 *
116 * Note: all of the multibyte integer fields are little endian.
117 */
118
119/*
120 * Note: dx_root_info is laid out so that if it should somehow get
121 * overlaid by a dirent the two low bits of the hash version will be
122 * zero. Therefore, the hash version mod 4 should never be 0.
123 * Sincerely, the paranoia department.
124 */
125struct ext2_dx_root_info {
126 __u32 reserved_zero;
127 __u8 hash_version; /* 0 now, 1 at release */
128 __u8 info_length; /* 8 */
129 __u8 indirect_levels;
130 __u8 unused_flags;
131};
132
133#define EXT2_HASH_LEGACY 0
134#define EXT2_HASH_HALF_MD4 1
135#define EXT2_HASH_TEA 2
136
137#define EXT2_HASH_FLAG_INCOMPAT 0x1
138
139struct ext2_dx_entry {
140 __u32 hash;
141 __u32 block;
142};
143
144struct ext2_dx_countlimit {
145 __u16 limit;
146 __u16 count;
147};
148
149
150/*
151 * Macro-instructions used to manage group descriptors
152 */
153#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group)
154#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group)
155#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
156/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
157#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8)
158#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s))
159#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
160
161/*
162 * Constants relative to the data blocks
163 */
164#define EXT2_NDIR_BLOCKS 12
165#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
166#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
167#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
168#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
169
170/*
171 * Inode flags
172 */
173#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
174#define EXT2_UNRM_FL 0x00000002 /* Undelete */
175#define EXT2_COMPR_FL 0x00000004 /* Compress file */
176#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
177#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
178#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
179#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
180#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */
181/* Reserved for compression usage... */
182#define EXT2_DIRTY_FL 0x00000100
183#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
184#define EXT2_NOCOMPR_FL 0x00000400 /* Access raw compressed data */
185#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */
186/* End compression flags --- maybe not all used */
187#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
188#define EXT2_INDEX_FL 0x00001000 /* hash-indexed directory */
189#define EXT2_IMAGIC_FL 0x00002000
190#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
191#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */
192#define EXT2_DIRSYNC_FL 0x00010000 /* Synchronous directory modifications */
193#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
194#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */
195#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
196
197#define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
198#define EXT2_FL_USER_MODIFIABLE 0x000080FF /* User modifiable flags */
199
200/*
201 * ioctl commands
202 */
203#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
204#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
205#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
206#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
207
208/*
209 * Structure of an inode on the disk
210 */
211struct ext2_inode {
212 __u16 i_mode; /* File mode */
213 __u16 i_uid; /* Low 16 bits of Owner Uid */
214 __u32 i_size; /* Size in bytes */
215 __u32 i_atime; /* Access time */
216 __u32 i_ctime; /* Creation time */
217 __u32 i_mtime; /* Modification time */
218 __u32 i_dtime; /* Deletion Time */
219 __u16 i_gid; /* Low 16 bits of Group Id */
220 __u16 i_links_count; /* Links count */
221 __u32 i_blocks; /* Blocks count */
222 __u32 i_flags; /* File flags */
223 union {
224 struct {
225 __u32 l_i_reserved1;
226 } linux1;
227 struct {
228 __u32 h_i_translator;
229 } hurd1;
230 struct {
231 __u32 m_i_reserved1;
232 } masix1;
233 } osd1; /* OS dependent 1 */
234 __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
235 __u32 i_generation; /* File version (for NFS) */
236 __u32 i_file_acl; /* File ACL */
237 __u32 i_dir_acl; /* Directory ACL */
238 __u32 i_faddr; /* Fragment address */
239 union {
240 struct {
241 __u8 l_i_frag; /* Fragment number */
242 __u8 l_i_fsize; /* Fragment size */
243 __u16 i_pad1;
244 __u16 l_i_uid_high; /* these 2 fields */
245 __u16 l_i_gid_high; /* were reserved2[0] */
246 __u32 l_i_reserved2;
247 } linux2;
248 struct {
249 __u8 h_i_frag; /* Fragment number */
250 __u8 h_i_fsize; /* Fragment size */
251 __u16 h_i_mode_high;
252 __u16 h_i_uid_high;
253 __u16 h_i_gid_high;
254 __u32 h_i_author;
255 } hurd2;
256 struct {
257 __u8 m_i_frag; /* Fragment number */
258 __u8 m_i_fsize; /* Fragment size */
259 __u16 m_pad1;
260 __u32 m_i_reserved2[2];
261 } masix2;
262 } osd2; /* OS dependent 2 */
263};
264
265/*
266 * Permanent part of an large inode on the disk
267 */
268struct ext2_inode_large {
269 __u16 i_mode; /* File mode */
270 __u16 i_uid; /* Low 16 bits of Owner Uid */
271 __u32 i_size; /* Size in bytes */
272 __u32 i_atime; /* Access time */
273 __u32 i_ctime; /* Creation time */
274 __u32 i_mtime; /* Modification time */
275 __u32 i_dtime; /* Deletion Time */
276 __u16 i_gid; /* Low 16 bits of Group Id */
277 __u16 i_links_count; /* Links count */
278 __u32 i_blocks; /* Blocks count */
279 __u32 i_flags; /* File flags */
280 union {
281 struct {
282 __u32 l_i_reserved1;
283 } linux1;
284 struct {
285 __u32 h_i_translator;
286 } hurd1;
287 struct {
288 __u32 m_i_reserved1;
289 } masix1;
290 } osd1; /* OS dependent 1 */
291 __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
292 __u32 i_generation; /* File version (for NFS) */
293 __u32 i_file_acl; /* File ACL */
294 __u32 i_dir_acl; /* Directory ACL */
295 __u32 i_faddr; /* Fragment address */
296 union {
297 struct {
298 __u8 l_i_frag; /* Fragment number */
299 __u8 l_i_fsize; /* Fragment size */
300 __u16 i_pad1;
301 __u16 l_i_uid_high; /* these 2 fields */
302 __u16 l_i_gid_high; /* were reserved2[0] */
303 __u32 l_i_reserved2;
304 } linux2;
305 struct {
306 __u8 h_i_frag; /* Fragment number */
307 __u8 h_i_fsize; /* Fragment size */
308 __u16 h_i_mode_high;
309 __u16 h_i_uid_high;
310 __u16 h_i_gid_high;
311 __u32 h_i_author;
312 } hurd2;
313 struct {
314 __u8 m_i_frag; /* Fragment number */
315 __u8 m_i_fsize; /* Fragment size */
316 __u16 m_pad1;
317 __u32 m_i_reserved2[2];
318 } masix2;
319 } osd2; /* OS dependent 2 */
320 __u16 i_extra_isize;
321 __u16 i_pad1;
322};
323
324#define i_size_high i_dir_acl
325
326/*
327 * File system states
328 */
329#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */
330#define EXT2_ERROR_FS 0x0002 /* Errors detected */
331
332/*
333 * Mount flags
334 */
335#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */
336#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */
337#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */
338#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
339#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
340#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
341#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
342#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
343
344#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
345#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
346#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \
347 EXT2_MOUNT_##opt)
348/*
349 * Maximal mount counts between two filesystem checks
350 */
351#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
352#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */
353
354/*
355 * Behaviour when detecting errors
356 */
357#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */
358#define EXT2_ERRORS_RO 2 /* Remount fs read-only */
359#define EXT2_ERRORS_PANIC 3 /* Panic */
360#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE
361
362/*
363 * Structure of the super block
364 */
365struct ext2_super_block {
366 __u32 s_inodes_count; /* Inodes count */
367 __u32 s_blocks_count; /* Blocks count */
368 __u32 s_r_blocks_count; /* Reserved blocks count */
369 __u32 s_free_blocks_count; /* Free blocks count */
370 __u32 s_free_inodes_count; /* Free inodes count */
371 __u32 s_first_data_block; /* First Data Block */
372 __u32 s_log_block_size; /* Block size */
373 __s32 s_log_frag_size; /* Fragment size */
374 __u32 s_blocks_per_group; /* # Blocks per group */
375 __u32 s_frags_per_group; /* # Fragments per group */
376 __u32 s_inodes_per_group; /* # Inodes per group */
377 __u32 s_mtime; /* Mount time */
378 __u32 s_wtime; /* Write time */
379 __u16 s_mnt_count; /* Mount count */
380 __s16 s_max_mnt_count; /* Maximal mount count */
381 __u16 s_magic; /* Magic signature */
382 __u16 s_state; /* File system state */
383 __u16 s_errors; /* Behaviour when detecting errors */
384 __u16 s_minor_rev_level; /* minor revision level */
385 __u32 s_lastcheck; /* time of last check */
386 __u32 s_checkinterval; /* max. time between checks */
387 __u32 s_creator_os; /* OS */
388 __u32 s_rev_level; /* Revision level */
389 __u16 s_def_resuid; /* Default uid for reserved blocks */
390 __u16 s_def_resgid; /* Default gid for reserved blocks */
391 /*
392 * These fields are for EXT2_DYNAMIC_REV superblocks only.
393 *
394 * Note: the difference between the compatible feature set and
395 * the incompatible feature set is that if there is a bit set
396 * in the incompatible feature set that the kernel doesn't
397 * know about, it should refuse to mount the filesystem.
398 *
399 * e2fsck's requirements are more strict; if it doesn't know
400 * about a feature in either the compatible or incompatible
401 * feature set, it must abort and not try to meddle with
402 * things it doesn't understand...
403 */
404 __u32 s_first_ino; /* First non-reserved inode */
405 __u16 s_inode_size; /* size of inode structure */
406 __u16 s_block_group_nr; /* block group # of this superblock */
407 __u32 s_feature_compat; /* compatible feature set */
408 __u32 s_feature_incompat; /* incompatible feature set */
409 __u32 s_feature_ro_compat; /* readonly-compatible feature set */
410 __u8 s_uuid[16]; /* 128-bit uuid for volume */
411 char s_volume_name[16]; /* volume name */
412 char s_last_mounted[64]; /* directory where last mounted */
413 __u32 s_algorithm_usage_bitmap; /* For compression */
414 /*
415 * Performance hints. Directory preallocation should only
416 * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
417 */
418 __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
419 __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
420 __u16 s_reserved_gdt_blocks; /* Per group table for online growth */
421 /*
422 * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
423 */
424 __u8 s_journal_uuid[16]; /* uuid of journal superblock */
425 __u32 s_journal_inum; /* inode number of journal file */
426 __u32 s_journal_dev; /* device number of journal file */
427 __u32 s_last_orphan; /* start of list of inodes to delete */
428 __u32 s_hash_seed[4]; /* HTREE hash seed */
429 __u8 s_def_hash_version; /* Default hash version to use */
430 __u8 s_jnl_backup_type; /* Default type of journal backup */
431 __u16 s_reserved_word_pad;
432 __u32 s_default_mount_opts;
433 __u32 s_first_meta_bg; /* First metablock group */
434 __u32 s_mkfs_time; /* When the filesystem was created */
435 __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
436 __u32 s_reserved[172]; /* Padding to the end of the block */
437};
438
439/*
440 * Codes for operating systems
441 */
442#define EXT2_OS_LINUX 0
443#define EXT2_OS_HURD 1
444#define EXT2_OS_MASIX 2
445#define EXT2_OS_FREEBSD 3
446#define EXT2_OS_LITES 4
447
448/*
449 * Revision levels
450 */
451#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
452#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
453
454#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
455#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
456
457#define EXT2_GOOD_OLD_INODE_SIZE 128
458
459/*
460 * Journal inode backup types
461 */
462#define EXT3_JNL_BACKUP_BLOCKS 1
463
464/*
465 * Feature set definitions
466 */
467
468#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
469 ( EXT2_SB(sb)->s_feature_compat & (mask) )
470#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
471 ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
472#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
473 ( EXT2_SB(sb)->s_feature_incompat & (mask) )
474
475#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
476#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
477#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
478#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008
479#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010
480#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
481
482#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
483#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
484/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 not used */
485
486#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
487#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
488#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
489#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
490#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
491#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040
492
493
494#define EXT2_FEATURE_COMPAT_SUPP 0
495#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE)
496#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
497 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
498 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
499
500/*
501 * Default values for user and/or group using reserved blocks
502 */
503#define EXT2_DEF_RESUID 0
504#define EXT2_DEF_RESGID 0
505
506/*
507 * Default mount options
508 */
509#define EXT2_DEFM_DEBUG 0x0001
510#define EXT2_DEFM_BSDGROUPS 0x0002
511#define EXT2_DEFM_XATTR_USER 0x0004
512#define EXT2_DEFM_ACL 0x0008
513#define EXT2_DEFM_UID16 0x0010
514#define EXT3_DEFM_JMODE 0x0060
515#define EXT3_DEFM_JMODE_DATA 0x0020
516#define EXT3_DEFM_JMODE_ORDERED 0x0040
517#define EXT3_DEFM_JMODE_WBACK 0x0060
518
519/*
520 * Structure of a directory entry
521 */
522#define EXT2_NAME_LEN 255
523
524struct ext2_dir_entry {
525 __u32 inode; /* Inode number */
526 __u16 rec_len; /* Directory entry length */
527 __u16 name_len; /* Name length */
528 char name[EXT2_NAME_LEN]; /* File name */
529};
530
531/*
532 * The new version of the directory entry. Since EXT2 structures are
533 * stored in intel byte order, and the name_len field could never be
534 * bigger than 255 chars, it's safe to reclaim the extra byte for the
535 * file_type field.
536 */
537struct ext2_dir_entry_2 {
538 __u32 inode; /* Inode number */
539 __u16 rec_len; /* Directory entry length */
540 __u8 name_len; /* Name length */
541 __u8 file_type;
542 char name[EXT2_NAME_LEN]; /* File name */
543};
544
545/*
546 * Ext2 directory file types. Only the low 3 bits are used. The
547 * other bits are reserved for now.
548 */
549#define EXT2_FT_UNKNOWN 0
550#define EXT2_FT_REG_FILE 1
551#define EXT2_FT_DIR 2
552#define EXT2_FT_CHRDEV 3
553#define EXT2_FT_BLKDEV 4
554#define EXT2_FT_FIFO 5
555#define EXT2_FT_SOCK 6
556#define EXT2_FT_SYMLINK 7
557
558#define EXT2_FT_MAX 8
559
560/*
561 * EXT2_DIR_PAD defines the directory entries boundaries
562 *
563 * NOTE: It must be a multiple of 4
564 */
565#define EXT2_DIR_PAD 4
566#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
567#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
568 ~EXT2_DIR_ROUND)
569
570#endif /* _LINUX_EXT2_FS_H */
diff --git a/e2fsprogs/ext2fs/ext2_io.h b/e2fsprogs/ext2fs/ext2_io.h
deleted file mode 100644
index e6c9630e2..000000000
--- a/e2fsprogs/ext2fs/ext2_io.h
+++ /dev/null
@@ -1,114 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * io.h --- the I/O manager abstraction
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#ifndef _EXT2FS_EXT2_IO_H
14#define _EXT2FS_EXT2_IO_H
15
16/*
17 * ext2_loff_t is defined here since unix_io.c needs it.
18 */
19#if defined(__GNUC__) || defined(HAS_LONG_LONG)
20typedef long long ext2_loff_t;
21#else
22typedef long ext2_loff_t;
23#endif
24
25/* llseek.c */
26/* ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int); */
27#ifdef CONFIG_LFS
28# define ext2fs_llseek lseek64
29#else
30# define ext2fs_llseek lseek
31#endif
32
33typedef struct struct_io_manager *io_manager;
34typedef struct struct_io_channel *io_channel;
35
36#define CHANNEL_FLAGS_WRITETHROUGH 0x01
37
38struct struct_io_channel {
39 errcode_t magic;
40 io_manager manager;
41 char *name;
42 int block_size;
43 errcode_t (*read_error)(io_channel channel,
44 unsigned long block,
45 int count,
46 void *data,
47 size_t size,
48 int actual_bytes_read,
49 errcode_t error);
50 errcode_t (*write_error)(io_channel channel,
51 unsigned long block,
52 int count,
53 const void *data,
54 size_t size,
55 int actual_bytes_written,
56 errcode_t error);
57 int refcount;
58 int flags;
59 int reserved[14];
60 void *private_data;
61 void *app_data;
62};
63
64struct struct_io_manager {
65 errcode_t magic;
66 const char *name;
67 errcode_t (*open)(const char *name, int flags, io_channel *channel);
68 errcode_t (*close)(io_channel channel);
69 errcode_t (*set_blksize)(io_channel channel, int blksize);
70 errcode_t (*read_blk)(io_channel channel, unsigned long block,
71 int count, void *data);
72 errcode_t (*write_blk)(io_channel channel, unsigned long block,
73 int count, const void *data);
74 errcode_t (*flush)(io_channel channel);
75 errcode_t (*write_byte)(io_channel channel, unsigned long offset,
76 int count, const void *data);
77 errcode_t (*set_option)(io_channel channel, const char *option,
78 const char *arg);
79 int reserved[14];
80};
81
82#define IO_FLAG_RW 1
83
84/*
85 * Convenience functions....
86 */
87#define io_channel_close(c) ((c)->manager->close((c)))
88#define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s))
89#define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d))
90#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
91#define io_channel_flush(c) ((c)->manager->flush((c)))
92#define io_channel_bumpcount(c) ((c)->refcount++)
93
94/* io_manager.c */
95extern errcode_t io_channel_set_options(io_channel channel,
96 const char *options);
97extern errcode_t io_channel_write_byte(io_channel channel,
98 unsigned long offset,
99 int count, const void *data);
100
101/* unix_io.c */
102extern io_manager unix_io_manager;
103
104/* test_io.c */
105extern io_manager test_io_manager, test_io_backing_manager;
106extern void (*test_io_cb_read_blk)
107 (unsigned long block, int count, errcode_t err);
108extern void (*test_io_cb_write_blk)
109 (unsigned long block, int count, errcode_t err);
110extern void (*test_io_cb_set_blksize)
111 (int blksize, errcode_t err);
112
113#endif /* _EXT2FS_EXT2_IO_H */
114
diff --git a/e2fsprogs/ext2fs/ext2_types.h b/e2fsprogs/ext2fs/ext2_types.h
deleted file mode 100644
index 2c1196b8b..000000000
--- a/e2fsprogs/ext2fs/ext2_types.h
+++ /dev/null
@@ -1,2 +0,0 @@
1/* vi: set sw=4 ts=4: */
2#include <linux/types.h>
diff --git a/e2fsprogs/ext2fs/ext2fs.h b/e2fsprogs/ext2fs/ext2fs.h
deleted file mode 100644
index 133fb1f1b..000000000
--- a/e2fsprogs/ext2fs/ext2fs.h
+++ /dev/null
@@ -1,923 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ext2fs.h --- ext2fs
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#ifndef _EXT2FS_EXT2FS_H
14#define _EXT2FS_EXT2FS_H
15
16
17#define EXT2FS_ATTR(x)
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23/*
24 * Where the master copy of the superblock is located, and how big
25 * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
26 * the size of the superblock structure is not necessarily trustworthy
27 * (some versions have the padding set up so that the superblock is
28 * 1032 bytes long).
29 */
30#define SUPERBLOCK_OFFSET 1024
31#define SUPERBLOCK_SIZE 1024
32
33/*
34 * The last ext2fs revision level that this version of the library is
35 * able to support.
36 */
37#define EXT2_LIB_CURRENT_REV EXT2_DYNAMIC_REV
38
39#ifdef HAVE_SYS_TYPES_H
40#include <sys/types.h>
41#endif
42
43#include <stdio.h>
44#include <stdlib.h>
45
46#include "ext2_types.h"
47#include "ext2_fs.h"
48
49typedef __u32 ext2_ino_t;
50typedef __u32 blk_t;
51typedef __u32 dgrp_t;
52typedef __u32 ext2_off_t;
53typedef __s64 e2_blkcnt_t;
54typedef __u32 ext2_dirhash_t;
55
56#include "ext2_io.h"
57#include "ext2_err.h"
58
59typedef struct struct_ext2_filsys *ext2_filsys;
60
61struct ext2fs_struct_generic_bitmap {
62 errcode_t magic;
63 ext2_filsys fs;
64 __u32 start, end;
65 __u32 real_end;
66 char * description;
67 char * bitmap;
68 errcode_t base_error_code;
69 __u32 reserved[7];
70};
71
72#define EXT2FS_MARK_ERROR 0
73#define EXT2FS_UNMARK_ERROR 1
74#define EXT2FS_TEST_ERROR 2
75
76typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
77typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
78typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
79
80#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
81
82/*
83 * badblocks list definitions
84 */
85
86typedef struct ext2_struct_u32_list *ext2_badblocks_list;
87typedef struct ext2_struct_u32_iterate *ext2_badblocks_iterate;
88
89typedef struct ext2_struct_u32_list *ext2_u32_list;
90typedef struct ext2_struct_u32_iterate *ext2_u32_iterate;
91
92/* old */
93typedef struct ext2_struct_u32_list *badblocks_list;
94typedef struct ext2_struct_u32_iterate *badblocks_iterate;
95
96#define BADBLOCKS_FLAG_DIRTY 1
97
98/*
99 * ext2_dblist structure and abstractions (see dblist.c)
100 */
101struct ext2_db_entry {
102 ext2_ino_t ino;
103 blk_t blk;
104 int blockcnt;
105};
106
107typedef struct ext2_struct_dblist *ext2_dblist;
108
109#define DBLIST_ABORT 1
110
111/*
112 * ext2_fileio definitions
113 */
114
115#define EXT2_FILE_WRITE 0x0001
116#define EXT2_FILE_CREATE 0x0002
117
118#define EXT2_FILE_MASK 0x00FF
119
120#define EXT2_FILE_BUF_DIRTY 0x4000
121#define EXT2_FILE_BUF_VALID 0x2000
122
123typedef struct ext2_file *ext2_file_t;
124
125#define EXT2_SEEK_SET 0
126#define EXT2_SEEK_CUR 1
127#define EXT2_SEEK_END 2
128
129/*
130 * Flags for the ext2_filsys structure and for ext2fs_open()
131 */
132#define EXT2_FLAG_RW 0x01
133#define EXT2_FLAG_CHANGED 0x02
134#define EXT2_FLAG_DIRTY 0x04
135#define EXT2_FLAG_VALID 0x08
136#define EXT2_FLAG_IB_DIRTY 0x10
137#define EXT2_FLAG_BB_DIRTY 0x20
138#define EXT2_FLAG_SWAP_BYTES 0x40
139#define EXT2_FLAG_SWAP_BYTES_READ 0x80
140#define EXT2_FLAG_SWAP_BYTES_WRITE 0x100
141#define EXT2_FLAG_MASTER_SB_ONLY 0x200
142#define EXT2_FLAG_FORCE 0x400
143#define EXT2_FLAG_SUPER_ONLY 0x800
144#define EXT2_FLAG_JOURNAL_DEV_OK 0x1000
145#define EXT2_FLAG_IMAGE_FILE 0x2000
146
147/*
148 * Special flag in the ext2 inode i_flag field that means that this is
149 * a new inode. (So that ext2_write_inode() can clear extra fields.)
150 */
151#define EXT2_NEW_INODE_FL 0x80000000
152
153/*
154 * Flags for mkjournal
155 *
156 * EXT2_MKJOURNAL_V1_SUPER Make a (deprecated) V1 journal superblock
157 */
158#define EXT2_MKJOURNAL_V1_SUPER 0x0000001
159
160struct struct_ext2_filsys {
161 errcode_t magic;
162 io_channel io;
163 int flags;
164 char * device_name;
165 struct ext2_super_block * super;
166 unsigned int blocksize;
167 int fragsize;
168 dgrp_t group_desc_count;
169 unsigned long desc_blocks;
170 struct ext2_group_desc * group_desc;
171 int inode_blocks_per_group;
172 ext2fs_inode_bitmap inode_map;
173 ext2fs_block_bitmap block_map;
174 errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
175 errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
176 errcode_t (*write_bitmaps)(ext2_filsys fs);
177 errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
178 struct ext2_inode *inode);
179 errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
180 struct ext2_inode *inode);
181 ext2_badblocks_list badblocks;
182 ext2_dblist dblist;
183 __u32 stride; /* for mke2fs */
184 struct ext2_super_block * orig_super;
185 struct ext2_image_hdr * image_header;
186 __u32 umask;
187 /*
188 * Reserved for future expansion
189 */
190 __u32 reserved[8];
191
192 /*
193 * Reserved for the use of the calling application.
194 */
195 void * priv_data;
196
197 /*
198 * Inode cache
199 */
200 struct ext2_inode_cache *icache;
201 io_channel image_io;
202};
203
204#include "bitops.h"
205
206/*
207 * Return flags for the block iterator functions
208 */
209#define BLOCK_CHANGED 1
210#define BLOCK_ABORT 2
211#define BLOCK_ERROR 4
212
213/*
214 * Block interate flags
215 *
216 * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
217 * function should be called on blocks where the block number is zero.
218 * This is used by ext2fs_expand_dir() to be able to add a new block
219 * to an inode. It can also be used for programs that want to be able
220 * to deal with files that contain "holes".
221 *
222 * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
223 * indirect, doubly indirect, etc. blocks should be called after all
224 * of the blocks containined in the indirect blocks are processed.
225 * This is useful if you are going to be deallocating blocks from an
226 * inode.
227 *
228 * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
229 * called for data blocks only.
230 *
231 * BLOCK_FLAG_NO_LARGE is for internal use only. It informs
232 * ext2fs_block_iterate2 that large files won't be accepted.
233 */
234#define BLOCK_FLAG_APPEND 1
235#define BLOCK_FLAG_HOLE 1
236#define BLOCK_FLAG_DEPTH_TRAVERSE 2
237#define BLOCK_FLAG_DATA_ONLY 4
238
239#define BLOCK_FLAG_NO_LARGE 0x1000
240
241/*
242 * Magic "block count" return values for the block iterator function.
243 */
244#define BLOCK_COUNT_IND (-1)
245#define BLOCK_COUNT_DIND (-2)
246#define BLOCK_COUNT_TIND (-3)
247#define BLOCK_COUNT_TRANSLATOR (-4)
248
249#if 0
250/*
251 * Flags for ext2fs_move_blocks
252 */
253#define EXT2_BMOVE_GET_DBLIST 0x0001
254#define EXT2_BMOVE_DEBUG 0x0002
255#endif
256
257/*
258 * Flags for directory block reading and writing functions
259 */
260#define EXT2_DIRBLOCK_V2_STRUCT 0x0001
261
262/*
263 * Return flags for the directory iterator functions
264 */
265#define DIRENT_CHANGED 1
266#define DIRENT_ABORT 2
267#define DIRENT_ERROR 3
268
269/*
270 * Directory iterator flags
271 */
272
273#define DIRENT_FLAG_INCLUDE_EMPTY 1
274#define DIRENT_FLAG_INCLUDE_REMOVED 2
275
276#define DIRENT_DOT_FILE 1
277#define DIRENT_DOT_DOT_FILE 2
278#define DIRENT_OTHER_FILE 3
279#define DIRENT_DELETED_FILE 4
280
281/*
282 * Inode scan definitions
283 */
284typedef struct ext2_struct_inode_scan *ext2_inode_scan;
285
286/*
287 * ext2fs_scan flags
288 */
289#define EXT2_SF_CHK_BADBLOCKS 0x0001
290#define EXT2_SF_BAD_INODE_BLK 0x0002
291#define EXT2_SF_BAD_EXTRA_BYTES 0x0004
292#define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
293
294/*
295 * ext2fs_check_if_mounted flags
296 */
297#define EXT2_MF_MOUNTED 1
298#define EXT2_MF_ISROOT 2
299#define EXT2_MF_READONLY 4
300#define EXT2_MF_SWAP 8
301#define EXT2_MF_BUSY 16
302
303/*
304 * Ext2/linux mode flags. We define them here so that we don't need
305 * to depend on the OS's sys/stat.h, since we may be compiling on a
306 * non-Linux system.
307 */
308#define LINUX_S_IFMT 00170000
309#define LINUX_S_IFSOCK 0140000
310#define LINUX_S_IFLNK 0120000
311#define LINUX_S_IFREG 0100000
312#define LINUX_S_IFBLK 0060000
313#define LINUX_S_IFDIR 0040000
314#define LINUX_S_IFCHR 0020000
315#define LINUX_S_IFIFO 0010000
316#define LINUX_S_ISUID 0004000
317#define LINUX_S_ISGID 0002000
318#define LINUX_S_ISVTX 0001000
319
320#define LINUX_S_IRWXU 00700
321#define LINUX_S_IRUSR 00400
322#define LINUX_S_IWUSR 00200
323#define LINUX_S_IXUSR 00100
324
325#define LINUX_S_IRWXG 00070
326#define LINUX_S_IRGRP 00040
327#define LINUX_S_IWGRP 00020
328#define LINUX_S_IXGRP 00010
329
330#define LINUX_S_IRWXO 00007
331#define LINUX_S_IROTH 00004
332#define LINUX_S_IWOTH 00002
333#define LINUX_S_IXOTH 00001
334
335#define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
336#define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
337#define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
338#define LINUX_S_ISCHR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
339#define LINUX_S_ISBLK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
340#define LINUX_S_ISFIFO(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
341#define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
342
343/*
344 * ext2 size of an inode
345 */
346#define EXT2_I_SIZE(i) ((i)->i_size | ((__u64) (i)->i_size_high << 32))
347
348/*
349 * ext2_icount_t abstraction
350 */
351#define EXT2_ICOUNT_OPT_INCREMENT 0x01
352
353typedef struct ext2_icount *ext2_icount_t;
354
355/*
356 * Flags for ext2fs_bmap
357 */
358#define BMAP_ALLOC 0x0001
359#define BMAP_SET 0x0002
360
361/*
362 * Flags for imager.c functions
363 */
364#define IMAGER_FLAG_INODEMAP 1
365#define IMAGER_FLAG_SPARSEWRITE 2
366
367/*
368 * For checking structure magic numbers...
369 */
370
371#define EXT2_CHECK_MAGIC(struct, code) \
372 if ((struct)->magic != (code)) return (code)
373
374
375/*
376 * For ext2 compression support
377 */
378#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) 0xffffffff)
379#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
380
381/*
382 * Features supported by this version of the library
383 */
384#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
385 EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
386 EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
387 EXT2_FEATURE_COMPAT_RESIZE_INODE|\
388 EXT2_FEATURE_COMPAT_DIR_INDEX|\
389 EXT2_FEATURE_COMPAT_EXT_ATTR)
390
391/* This #ifdef is temporary until compression is fully supported */
392#ifdef ENABLE_COMPRESSION
393#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
394/* If the below warning bugs you, then have
395 `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
396 environment at configure time. */
397 #warning "Compression support is experimental"
398#endif
399#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
400 EXT2_FEATURE_INCOMPAT_COMPRESSION|\
401 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
402 EXT2_FEATURE_INCOMPAT_META_BG|\
403 EXT3_FEATURE_INCOMPAT_RECOVER)
404#else
405#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
406 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
407 EXT2_FEATURE_INCOMPAT_META_BG|\
408 EXT3_FEATURE_INCOMPAT_RECOVER)
409#endif
410#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
411 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
412/*
413 * function prototypes
414 */
415
416/* alloc.c */
417extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
418 ext2fs_inode_bitmap map, ext2_ino_t *ret);
419extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
420 ext2fs_block_bitmap map, blk_t *ret);
421extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
422 blk_t finish, int num,
423 ext2fs_block_bitmap map,
424 blk_t *ret);
425extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
426 char *block_buf, blk_t *ret);
427
428/* alloc_sb.c */
429extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
430 dgrp_t group,
431 ext2fs_block_bitmap bmap);
432
433/* alloc_stats.c */
434void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse);
435void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
436 int inuse, int isdir);
437void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
438
439/* alloc_tables.c */
440extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
441extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
442 ext2fs_block_bitmap bmap);
443
444/* badblocks.c */
445extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
446extern errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk);
447extern int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk);
448extern int ext2fs_u32_list_test(ext2_u32_list bb, blk_t blk);
449extern errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
450 ext2_u32_iterate *ret);
451extern int ext2fs_u32_list_iterate(ext2_u32_iterate iter, blk_t *blk);
452extern void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter);
453extern errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest);
454extern int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2);
455
456extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
457 int size);
458extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
459 blk_t blk);
460extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
461 blk_t blk);
462extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
463extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
464extern errcode_t
465 ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
466 ext2_badblocks_iterate *ret);
467extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
468 blk_t *blk);
469extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
470extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
471 ext2_badblocks_list *dest);
472extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
473 ext2_badblocks_list bb2);
474extern int ext2fs_u32_list_count(ext2_u32_list bb);
475
476/* bb_compat */
477extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
478extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
479extern int badblocks_list_test(badblocks_list bb, blk_t blk);
480extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
481 badblocks_iterate *ret);
482extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
483extern void badblocks_list_iterate_end(badblocks_iterate iter);
484extern void badblocks_list_free(badblocks_list bb);
485
486/* bb_inode.c */
487extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
488 ext2_badblocks_list bb_list);
489
490/* bitmaps.c */
491extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
492extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
493extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
494extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
495extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
496 __u32 end,
497 __u32 real_end,
498 const char *descr,
499 ext2fs_generic_bitmap *ret);
500extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
501 const char *descr,
502 ext2fs_block_bitmap *ret);
503extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
504 const char *descr,
505 ext2fs_inode_bitmap *ret);
506extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
507 ext2_ino_t end, ext2_ino_t *oend);
508extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
509 blk_t end, blk_t *oend);
510extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
511extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
512extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
513extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
514
515/* block.c */
516extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
517 ext2_ino_t ino,
518 int flags,
519 char *block_buf,
520 int (*func)(ext2_filsys fs,
521 blk_t *blocknr,
522 int blockcnt,
523 void *priv_data),
524 void *priv_data);
525errcode_t ext2fs_block_iterate2(ext2_filsys fs,
526 ext2_ino_t ino,
527 int flags,
528 char *block_buf,
529 int (*func)(ext2_filsys fs,
530 blk_t *blocknr,
531 e2_blkcnt_t blockcnt,
532 blk_t ref_blk,
533 int ref_offset,
534 void *priv_data),
535 void *priv_data);
536
537/* bmap.c */
538extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
539 struct ext2_inode *inode,
540 char *block_buf, int bmap_flags,
541 blk_t block, blk_t *phys_blk);
542
543
544#if 0
545/* bmove.c */
546extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
547 ext2fs_block_bitmap reserve,
548 ext2fs_block_bitmap alloc_map,
549 int flags);
550#endif
551
552/* check_desc.c */
553extern errcode_t ext2fs_check_desc(ext2_filsys fs);
554
555/* closefs.c */
556extern errcode_t ext2fs_close(ext2_filsys fs);
557extern errcode_t ext2fs_flush(ext2_filsys fs);
558extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
559extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
560 dgrp_t group,
561 blk_t *ret_super_blk,
562 blk_t *ret_old_desc_blk,
563 blk_t *ret_new_desc_blk,
564 int *ret_meta_bg);
565extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
566
567/* cmp_bitmaps.c */
568extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
569 ext2fs_block_bitmap bm2);
570extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
571 ext2fs_inode_bitmap bm2);
572
573/* dblist.c */
574
575extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
576extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
577extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
578 blk_t blk, int blockcnt);
579extern void ext2fs_dblist_sort(ext2_dblist dblist,
580 int (*sortfunc)(const void *,
581 const void *));
582extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
583 int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
584 void *priv_data),
585 void *priv_data);
586extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
587 blk_t blk, int blockcnt);
588extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
589 ext2_dblist *dest);
590extern int ext2fs_dblist_count(ext2_dblist dblist);
591
592/* dblist_dir.c */
593extern errcode_t
594 ext2fs_dblist_dir_iterate(ext2_dblist dblist,
595 int flags,
596 char *block_buf,
597 int (*func)(ext2_ino_t dir,
598 int entry,
599 struct ext2_dir_entry *dirent,
600 int offset,
601 int blocksize,
602 char *buf,
603 void *priv_data),
604 void *priv_data);
605
606/* dirblock.c */
607extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
608 void *buf);
609extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
610 void *buf, int flags);
611extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
612 void *buf);
613extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
614 void *buf, int flags);
615
616/* dirhash.c */
617extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
618 const __u32 *seed,
619 ext2_dirhash_t *ret_hash,
620 ext2_dirhash_t *ret_minor_hash);
621
622
623/* dir_iterate.c */
624extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
625 ext2_ino_t dir,
626 int flags,
627 char *block_buf,
628 int (*func)(struct ext2_dir_entry *dirent,
629 int offset,
630 int blocksize,
631 char *buf,
632 void *priv_data),
633 void *priv_data);
634extern errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
635 ext2_ino_t dir,
636 int flags,
637 char *block_buf,
638 int (*func)(ext2_ino_t dir,
639 int entry,
640 struct ext2_dir_entry *dirent,
641 int offset,
642 int blocksize,
643 char *buf,
644 void *priv_data),
645 void *priv_data);
646
647/* dupfs.c */
648extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
649
650/* expanddir.c */
651extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
652
653/* ext_attr.c */
654extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
655extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
656 void *buf);
657extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
658 char *block_buf,
659 int adjust, __u32 *newcount);
660
661/* fileio.c */
662extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
663 struct ext2_inode *inode,
664 int flags, ext2_file_t *ret);
665extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
666 int flags, ext2_file_t *ret);
667extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
668extern errcode_t ext2fs_file_close(ext2_file_t file);
669extern errcode_t ext2fs_file_flush(ext2_file_t file);
670extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
671 unsigned int wanted, unsigned int *got);
672extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
673 unsigned int nbytes, unsigned int *written);
674extern errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
675 int whence, __u64 *ret_pos);
676extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
677 int whence, ext2_off_t *ret_pos);
678errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
679extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
680extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
681
682/* finddev.c */
683extern char *ext2fs_find_block_device(dev_t device);
684
685/* flushb.c */
686extern errcode_t ext2fs_sync_device(int fd, int flushb);
687
688/* freefs.c */
689extern void ext2fs_free(ext2_filsys fs);
690extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
691extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
692extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
693extern void ext2fs_free_dblist(ext2_dblist dblist);
694extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
695extern void ext2fs_u32_list_free(ext2_u32_list bb);
696
697/* getsize.c */
698extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
699 blk_t *retblocks);
700
701/* getsectsize.c */
702errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
703
704/* imager.c */
705extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
706extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
707extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
708extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
709extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
710extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
711
712/* ind_block.c */
713errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
714errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
715
716/* initialize.c */
717extern errcode_t ext2fs_initialize(const char *name, int flags,
718 struct ext2_super_block *param,
719 io_manager manager, ext2_filsys *ret_fs);
720
721/* icount.c */
722extern void ext2fs_free_icount(ext2_icount_t icount);
723extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
724 unsigned int size,
725 ext2_icount_t hint, ext2_icount_t *ret);
726extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags,
727 unsigned int size,
728 ext2_icount_t *ret);
729extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
730 __u16 *ret);
731extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
732 __u16 *ret);
733extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
734 __u16 *ret);
735extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
736 __u16 count);
737extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
738errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
739
740/* inode.c */
741extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
742extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan,
743 ext2_ino_t *ino,
744 struct ext2_inode *inode,
745 int bufsize);
746extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
747 ext2_inode_scan *ret_scan);
748extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
749extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
750 struct ext2_inode *inode);
751extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
752 int group);
753extern void ext2fs_set_inode_callback
754 (ext2_inode_scan scan,
755 errcode_t (*done_group)(ext2_filsys fs,
756 dgrp_t group,
757 void * priv_data),
758 void *done_group_data);
759extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
760 int clear_flags);
761extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
762 struct ext2_inode * inode,
763 int bufsize);
764extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
765 struct ext2_inode * inode);
766extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
767 struct ext2_inode * inode,
768 int bufsize);
769extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
770 struct ext2_inode * inode);
771extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
772 struct ext2_inode * inode);
773extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
774extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
775
776/* inode_io.c */
777extern io_manager inode_io_manager;
778extern errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
779 char **name);
780extern errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
781 struct ext2_inode *inode,
782 char **name);
783
784/* ismounted.c */
785extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
786extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
787 char *mtpt, int mtlen);
788
789/* namei.c */
790extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
791 int namelen, char *buf, ext2_ino_t *inode);
792extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
793 const char *name, ext2_ino_t *inode);
794errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
795 const char *name, ext2_ino_t *inode);
796extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
797 ext2_ino_t inode, ext2_ino_t *res_inode);
798
799/* native.c */
800int ext2fs_native_flag(void);
801
802/* newdir.c */
803extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
804 ext2_ino_t parent_ino, char **block);
805
806/* mkdir.c */
807extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
808 const char *name);
809
810/* mkjournal.c */
811extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
812 __u32 size, int flags,
813 char **ret_jsb);
814extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
815 ext2_filsys journal_dev);
816extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
817 int flags);
818
819/* openfs.c */
820extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
821 unsigned int block_size, io_manager manager,
822 ext2_filsys *ret_fs);
823extern errcode_t ext2fs_open2(const char *name, const char *io_options,
824 int flags, int superblock,
825 unsigned int block_size, io_manager manager,
826 ext2_filsys *ret_fs);
827extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block,
828 dgrp_t i);
829errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
830errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
831errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
832
833/* get_pathname.c */
834extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
835 char **name);
836
837/* link.c */
838errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
839 ext2_ino_t ino, int flags);
840errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
841 ext2_ino_t ino, int flags);
842
843/* read_bb.c */
844extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
845 ext2_badblocks_list *bb_list);
846
847/* read_bb_file.c */
848extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
849 ext2_badblocks_list *bb_list,
850 void *priv_data,
851 void (*invalid)(ext2_filsys fs,
852 blk_t blk,
853 char *badstr,
854 void *priv_data));
855extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
856 ext2_badblocks_list *bb_list,
857 void (*invalid)(ext2_filsys fs,
858 blk_t blk));
859
860/* res_gdt.c */
861extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
862
863/* rs_bitmap.c */
864extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
865 __u32 new_real_end,
866 ext2fs_generic_bitmap bmap);
867extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
868 ext2fs_inode_bitmap bmap);
869extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
870 ext2fs_block_bitmap bmap);
871extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
872 ext2fs_generic_bitmap *dest);
873
874/* swapfs.c */
875extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
876 int has_header);
877extern void ext2fs_swap_super(struct ext2_super_block * super);
878extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
879extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
880 struct ext2_inode_large *f, int hostorder,
881 int bufsize);
882extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
883 struct ext2_inode *f, int hostorder);
884
885/* valid_blk.c */
886extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
887
888/* version.c */
889extern int ext2fs_parse_version_string(const char *ver_string);
890extern int ext2fs_get_library_version(const char **ver_string,
891 const char **date_string);
892
893/* write_bb_file.c */
894extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
895 unsigned int flags,
896 FILE *f);
897
898
899/* inline functions */
900extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
901extern errcode_t ext2fs_free_mem(void *ptr);
902extern errcode_t ext2fs_resize_mem(unsigned long old_size,
903 unsigned long size, void *ptr);
904extern void ext2fs_mark_super_dirty(ext2_filsys fs);
905extern void ext2fs_mark_changed(ext2_filsys fs);
906extern int ext2fs_test_changed(ext2_filsys fs);
907extern void ext2fs_mark_valid(ext2_filsys fs);
908extern void ext2fs_unmark_valid(ext2_filsys fs);
909extern int ext2fs_test_valid(ext2_filsys fs);
910extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
911extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
912extern int ext2fs_test_ib_dirty(ext2_filsys fs);
913extern int ext2fs_test_bb_dirty(ext2_filsys fs);
914extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
915extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
916extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
917 struct ext2_inode *inode);
918
919#ifdef __cplusplus
920}
921#endif
922
923#endif /* _EXT2FS_EXT2FS_H */
diff --git a/e2fsprogs/ext2fs/ext2fsP.h b/e2fsprogs/ext2fs/ext2fsP.h
deleted file mode 100644
index 908b5d9a4..000000000
--- a/e2fsprogs/ext2fs/ext2fsP.h
+++ /dev/null
@@ -1,89 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ext2fsP.h --- private header file for ext2 library
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include "ext2fs.h"
14
15/*
16 * Badblocks list
17 */
18struct ext2_struct_u32_list {
19 int magic;
20 int num;
21 int size;
22 __u32 *list;
23 int badblocks_flags;
24};
25
26struct ext2_struct_u32_iterate {
27 int magic;
28 ext2_u32_list bb;
29 int ptr;
30};
31
32
33/*
34 * Directory block iterator definition
35 */
36struct ext2_struct_dblist {
37 int magic;
38 ext2_filsys fs;
39 ext2_ino_t size;
40 ext2_ino_t count;
41 int sorted;
42 struct ext2_db_entry * list;
43};
44
45/*
46 * For directory iterators
47 */
48struct dir_context {
49 ext2_ino_t dir;
50 int flags;
51 char *buf;
52 int (*func)(ext2_ino_t dir,
53 int entry,
54 struct ext2_dir_entry *dirent,
55 int offset,
56 int blocksize,
57 char *buf,
58 void *priv_data);
59 void *priv_data;
60 errcode_t errcode;
61};
62
63/*
64 * Inode cache structure
65 */
66struct ext2_inode_cache {
67 void * buffer;
68 blk_t buffer_blk;
69 int cache_last;
70 int cache_size;
71 int refcount;
72 struct ext2_inode_cache_ent *cache;
73};
74
75struct ext2_inode_cache_ent {
76 ext2_ino_t ino;
77 struct ext2_inode inode;
78};
79
80/* Function prototypes */
81
82extern int ext2fs_process_dir_block(ext2_filsys fs,
83 blk_t *blocknr,
84 e2_blkcnt_t blockcnt,
85 blk_t ref_block,
86 int ref_offset,
87 void *priv_data);
88
89
diff --git a/e2fsprogs/ext2fs/ext2fs_inline.c b/e2fsprogs/ext2fs/ext2fs_inline.c
deleted file mode 100644
index da1cf5be5..000000000
--- a/e2fsprogs/ext2fs/ext2fs_inline.c
+++ /dev/null
@@ -1,367 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ext2fs.h --- ext2fs
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include "ext2fs.h"
14#include "bitops.h"
15#include <string.h>
16
17/*
18 * Allocate memory
19 */
20errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
21{
22 void **pp = (void **)ptr;
23
24 *pp = malloc(size);
25 if (!*pp)
26 return EXT2_ET_NO_MEMORY;
27 return 0;
28}
29
30/*
31 * Free memory
32 */
33errcode_t ext2fs_free_mem(void *ptr)
34{
35 void **pp = (void **)ptr;
36
37 free(*pp);
38 *pp = 0;
39 return 0;
40}
41
42/*
43 * Resize memory
44 */
45errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
46 unsigned long size, void *ptr)
47{
48 void *p;
49
50 /* Use "memcpy" for pointer assignments here to avoid problems
51 * with C99 strict type aliasing rules. */
52 memcpy(&p, ptr, sizeof (p));
53 p = realloc(p, size);
54 if (!p)
55 return EXT2_ET_NO_MEMORY;
56 memcpy(ptr, &p, sizeof (p));
57 return 0;
58}
59
60/*
61 * Mark a filesystem superblock as dirty
62 */
63void ext2fs_mark_super_dirty(ext2_filsys fs)
64{
65 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
66}
67
68/*
69 * Mark a filesystem as changed
70 */
71void ext2fs_mark_changed(ext2_filsys fs)
72{
73 fs->flags |= EXT2_FLAG_CHANGED;
74}
75
76/*
77 * Check to see if a filesystem has changed
78 */
79int ext2fs_test_changed(ext2_filsys fs)
80{
81 return (fs->flags & EXT2_FLAG_CHANGED);
82}
83
84/*
85 * Mark a filesystem as valid
86 */
87void ext2fs_mark_valid(ext2_filsys fs)
88{
89 fs->flags |= EXT2_FLAG_VALID;
90}
91
92/*
93 * Mark a filesystem as NOT valid
94 */
95void ext2fs_unmark_valid(ext2_filsys fs)
96{
97 fs->flags &= ~EXT2_FLAG_VALID;
98}
99
100/*
101 * Check to see if a filesystem is valid
102 */
103int ext2fs_test_valid(ext2_filsys fs)
104{
105 return (fs->flags & EXT2_FLAG_VALID);
106}
107
108/*
109 * Mark the inode bitmap as dirty
110 */
111void ext2fs_mark_ib_dirty(ext2_filsys fs)
112{
113 fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
114}
115
116/*
117 * Mark the block bitmap as dirty
118 */
119void ext2fs_mark_bb_dirty(ext2_filsys fs)
120{
121 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
122}
123
124/*
125 * Check to see if a filesystem's inode bitmap is dirty
126 */
127int ext2fs_test_ib_dirty(ext2_filsys fs)
128{
129 return (fs->flags & EXT2_FLAG_IB_DIRTY);
130}
131
132/*
133 * Check to see if a filesystem's block bitmap is dirty
134 */
135int ext2fs_test_bb_dirty(ext2_filsys fs)
136{
137 return (fs->flags & EXT2_FLAG_BB_DIRTY);
138}
139
140/*
141 * Return the group # of a block
142 */
143int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
144{
145 return (blk - fs->super->s_first_data_block) /
146 fs->super->s_blocks_per_group;
147}
148
149/*
150 * Return the group # of an inode number
151 */
152int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
153{
154 return (ino - 1) / fs->super->s_inodes_per_group;
155}
156
157blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
158 struct ext2_inode *inode)
159{
160 return inode->i_blocks -
161 (inode->i_file_acl ? fs->blocksize >> 9 : 0);
162}
163
164
165
166
167
168
169
170
171
172__u16 ext2fs_swab16(__u16 val)
173{
174 return (val >> 8) | (val << 8);
175}
176
177__u32 ext2fs_swab32(__u32 val)
178{
179 return ((val>>24) | ((val>>8)&0xFF00) |
180 ((val<<8)&0xFF0000) | (val<<24));
181}
182
183int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
184 blk_t bitno);
185
186int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
187 blk_t bitno)
188{
189 if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
190 ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
191 return 0;
192 }
193 return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
194}
195
196int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
197 blk_t block)
198{
199 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
200 bitmap,
201 block);
202}
203
204int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
205 blk_t block)
206{
207 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
208 block);
209}
210
211int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
212 blk_t block)
213{
214 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
215 block);
216}
217
218int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
219 ext2_ino_t inode)
220{
221 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
222 inode);
223}
224
225int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
226 ext2_ino_t inode)
227{
228 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
229 inode);
230}
231
232int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
233 ext2_ino_t inode)
234{
235 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
236 inode);
237}
238
239void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
240 blk_t block)
241{
242 ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
243}
244
245void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
246 blk_t block)
247{
248 ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
249}
250
251int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
252 blk_t block)
253{
254 return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
255}
256
257void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
258 ext2_ino_t inode)
259{
260 ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
261}
262
263void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
264 ext2_ino_t inode)
265{
266 ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
267}
268
269int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
270 ext2_ino_t inode)
271{
272 return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
273}
274
275blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
276{
277 return bitmap->start;
278}
279
280ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
281{
282 return bitmap->start;
283}
284
285blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
286{
287 return bitmap->end;
288}
289
290ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
291{
292 return bitmap->end;
293}
294
295int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
296 blk_t block, int num)
297{
298 int i;
299
300 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
301 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
302 block, bitmap->description);
303 return 0;
304 }
305 for (i=0; i < num; i++) {
306 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
307 return 0;
308 }
309 return 1;
310}
311
312int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
313 blk_t block, int num)
314{
315 int i;
316
317 for (i=0; i < num; i++) {
318 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
319 return 0;
320 }
321 return 1;
322}
323
324void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
325 blk_t block, int num)
326{
327 int i;
328
329 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
330 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
331 bitmap->description);
332 return;
333 }
334 for (i=0; i < num; i++)
335 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
336}
337
338void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
339 blk_t block, int num)
340{
341 int i;
342
343 for (i=0; i < num; i++)
344 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
345}
346
347void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
348 blk_t block, int num)
349{
350 int i;
351
352 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
353 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
354 bitmap->description);
355 return;
356 }
357 for (i=0; i < num; i++)
358 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
359}
360
361void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
362 blk_t block, int num)
363{
364 int i;
365 for (i=0; i < num; i++)
366 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
367}
diff --git a/e2fsprogs/ext2fs/ext_attr.c b/e2fsprogs/ext2fs/ext_attr.c
deleted file mode 100644
index 7ee41f234..000000000
--- a/e2fsprogs/ext2fs/ext_attr.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ext_attr.c --- extended attribute blocks
4 *
5 * Copyright (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
6 *
7 * Copyright (C) 2002 Theodore Ts'o.
8 *
9 * %Begin-Header%
10 * This file may be redistributed under the terms of the GNU Public
11 * License.
12 * %End-Header%
13 */
14
15#include <stdio.h>
16#include <unistd.h>
17#include <string.h>
18#include <time.h>
19
20#include "ext2_fs.h"
21#include "ext2_ext_attr.h"
22#include "ext2fs.h"
23
24errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
25{
26 errcode_t retval;
27
28 retval = io_channel_read_blk(fs->io, block, 1, buf);
29 if (retval)
30 return retval;
31#if BB_BIG_ENDIAN
32 if ((fs->flags & (EXT2_FLAG_SWAP_BYTES|
33 EXT2_FLAG_SWAP_BYTES_READ)) != 0)
34 ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1);
35#endif
36 return 0;
37}
38
39errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
40{
41 errcode_t retval;
42 char *write_buf;
43 char *buf = NULL;
44
45 if (BB_BIG_ENDIAN && ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
46 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))) {
47 retval = ext2fs_get_mem(fs->blocksize, &buf);
48 if (retval)
49 return retval;
50 write_buf = buf;
51 ext2fs_swap_ext_attr(buf, inbuf, fs->blocksize, 1);
52 } else
53 write_buf = (char *) inbuf;
54 retval = io_channel_write_blk(fs->io, block, 1, write_buf);
55 if (buf)
56 ext2fs_free_mem(&buf);
57 if (!retval)
58 ext2fs_mark_changed(fs);
59 return retval;
60}
61
62/*
63 * This function adjusts the reference count of the EA block.
64 */
65errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
66 char *block_buf, int adjust,
67 __u32 *newcount)
68{
69 errcode_t retval;
70 struct ext2_ext_attr_header *header;
71 char *buf = 0;
72
73 if ((blk >= fs->super->s_blocks_count) ||
74 (blk < fs->super->s_first_data_block))
75 return EXT2_ET_BAD_EA_BLOCK_NUM;
76
77 if (!block_buf) {
78 retval = ext2fs_get_mem(fs->blocksize, &buf);
79 if (retval)
80 return retval;
81 block_buf = buf;
82 }
83
84 retval = ext2fs_read_ext_attr(fs, blk, block_buf);
85 if (retval)
86 goto errout;
87
88 header = (struct ext2_ext_attr_header *) block_buf;
89 header->h_refcount += adjust;
90 if (newcount)
91 *newcount = header->h_refcount;
92
93 retval = ext2fs_write_ext_attr(fs, blk, block_buf);
94 if (retval)
95 goto errout;
96
97errout:
98 if (buf)
99 ext2fs_free_mem(&buf);
100 return retval;
101}
diff --git a/e2fsprogs/ext2fs/fileio.c b/e2fsprogs/ext2fs/fileio.c
deleted file mode 100644
index c56a21aa8..000000000
--- a/e2fsprogs/ext2fs/fileio.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * fileio.c --- Simple file I/O routines
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct ext2_file {
23 errcode_t magic;
24 ext2_filsys fs;
25 ext2_ino_t ino;
26 struct ext2_inode inode;
27 int flags;
28 __u64 pos;
29 blk_t blockno;
30 blk_t physblock;
31 char *buf;
32};
33
34#define BMAP_BUFFER (file->buf + fs->blocksize)
35
36errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
37 struct ext2_inode *inode,
38 int flags, ext2_file_t *ret)
39{
40 ext2_file_t file;
41 errcode_t retval;
42
43 /*
44 * Don't let caller create or open a file for writing if the
45 * filesystem is read-only.
46 */
47 if ((flags & (EXT2_FILE_WRITE | EXT2_FILE_CREATE)) &&
48 !(fs->flags & EXT2_FLAG_RW))
49 return EXT2_ET_RO_FILSYS;
50
51 retval = ext2fs_get_mem(sizeof(struct ext2_file), &file);
52 if (retval)
53 return retval;
54
55 memset(file, 0, sizeof(struct ext2_file));
56 file->magic = EXT2_ET_MAGIC_EXT2_FILE;
57 file->fs = fs;
58 file->ino = ino;
59 file->flags = flags & EXT2_FILE_MASK;
60
61 if (inode) {
62 memcpy(&file->inode, inode, sizeof(struct ext2_inode));
63 } else {
64 retval = ext2fs_read_inode(fs, ino, &file->inode);
65 if (retval)
66 goto fail;
67 }
68
69 retval = ext2fs_get_mem(fs->blocksize * 3, &file->buf);
70 if (retval)
71 goto fail;
72
73 *ret = file;
74 return 0;
75
76fail:
77 ext2fs_free_mem(&file->buf);
78 ext2fs_free_mem(&file);
79 return retval;
80}
81
82errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
83 int flags, ext2_file_t *ret)
84{
85 return ext2fs_file_open2(fs, ino, NULL, flags, ret);
86}
87
88/*
89 * This function returns the filesystem handle of a file from the structure
90 */
91ext2_filsys ext2fs_file_get_fs(ext2_file_t file)
92{
93 if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
94 return 0;
95 return file->fs;
96}
97
98/*
99 * This function flushes the dirty block buffer out to disk if
100 * necessary.
101 */
102errcode_t ext2fs_file_flush(ext2_file_t file)
103{
104 errcode_t retval;
105 ext2_filsys fs;
106
107 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
108 fs = file->fs;
109
110 if (!(file->flags & EXT2_FILE_BUF_VALID) ||
111 !(file->flags & EXT2_FILE_BUF_DIRTY))
112 return 0;
113
114 /*
115 * OK, the physical block hasn't been allocated yet.
116 * Allocate it.
117 */
118 if (!file->physblock) {
119 retval = ext2fs_bmap(fs, file->ino, &file->inode,
120 BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0,
121 file->blockno, &file->physblock);
122 if (retval)
123 return retval;
124 }
125
126 retval = io_channel_write_blk(fs->io, file->physblock,
127 1, file->buf);
128 if (retval)
129 return retval;
130
131 file->flags &= ~EXT2_FILE_BUF_DIRTY;
132
133 return retval;
134}
135
136/*
137 * This function synchronizes the file's block buffer and the current
138 * file position, possibly invalidating block buffer if necessary
139 */
140static errcode_t sync_buffer_position(ext2_file_t file)
141{
142 blk_t b;
143 errcode_t retval;
144
145 b = file->pos / file->fs->blocksize;
146 if (b != file->blockno) {
147 retval = ext2fs_file_flush(file);
148 if (retval)
149 return retval;
150 file->flags &= ~EXT2_FILE_BUF_VALID;
151 }
152 file->blockno = b;
153 return 0;
154}
155
156/*
157 * This function loads the file's block buffer with valid data from
158 * the disk as necessary.
159 *
160 * If dontfill is true, then skip initializing the buffer since we're
161 * going to be replacing its entire contents anyway. If set, then the
162 * function basically only sets file->physblock and EXT2_FILE_BUF_VALID
163 */
164#define DONTFILL 1
165static errcode_t load_buffer(ext2_file_t file, int dontfill)
166{
167 ext2_filsys fs = file->fs;
168 errcode_t retval;
169
170 if (!(file->flags & EXT2_FILE_BUF_VALID)) {
171 retval = ext2fs_bmap(fs, file->ino, &file->inode,
172 BMAP_BUFFER, 0, file->blockno,
173 &file->physblock);
174 if (retval)
175 return retval;
176 if (!dontfill) {
177 if (file->physblock) {
178 retval = io_channel_read_blk(fs->io,
179 file->physblock,
180 1, file->buf);
181 if (retval)
182 return retval;
183 } else
184 memset(file->buf, 0, fs->blocksize);
185 }
186 file->flags |= EXT2_FILE_BUF_VALID;
187 }
188 return 0;
189}
190
191
192errcode_t ext2fs_file_close(ext2_file_t file)
193{
194 errcode_t retval;
195
196 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
197
198 retval = ext2fs_file_flush(file);
199
200 ext2fs_free_mem(&file->buf);
201 ext2fs_free_mem(&file);
202
203 return retval;
204}
205
206
207errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
208 unsigned int wanted, unsigned int *got)
209{
210 ext2_filsys fs;
211 errcode_t retval = 0;
212 unsigned int start, c, count = 0;
213 __u64 left;
214 char *ptr = (char *) buf;
215
216 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
217 fs = file->fs;
218
219 while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) {
220 retval = sync_buffer_position(file);
221 if (retval)
222 goto fail;
223 retval = load_buffer(file, 0);
224 if (retval)
225 goto fail;
226
227 start = file->pos % fs->blocksize;
228 c = fs->blocksize - start;
229 if (c > wanted)
230 c = wanted;
231 left = EXT2_I_SIZE(&file->inode) - file->pos ;
232 if (c > left)
233 c = left;
234
235 memcpy(ptr, file->buf+start, c);
236 file->pos += c;
237 ptr += c;
238 count += c;
239 wanted -= c;
240 }
241
242fail:
243 if (got)
244 *got = count;
245 return retval;
246}
247
248
249errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
250 unsigned int nbytes, unsigned int *written)
251{
252 ext2_filsys fs;
253 errcode_t retval = 0;
254 unsigned int start, c, count = 0;
255 const char *ptr = (const char *) buf;
256
257 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
258 fs = file->fs;
259
260 if (!(file->flags & EXT2_FILE_WRITE))
261 return EXT2_ET_FILE_RO;
262
263 while (nbytes > 0) {
264 retval = sync_buffer_position(file);
265 if (retval)
266 goto fail;
267
268 start = file->pos % fs->blocksize;
269 c = fs->blocksize - start;
270 if (c > nbytes)
271 c = nbytes;
272
273 /*
274 * We only need to do a read-modify-update cycle if
275 * we're doing a partial write.
276 */
277 retval = load_buffer(file, (c == fs->blocksize));
278 if (retval)
279 goto fail;
280
281 file->flags |= EXT2_FILE_BUF_DIRTY;
282 memcpy(file->buf+start, ptr, c);
283 file->pos += c;
284 ptr += c;
285 count += c;
286 nbytes -= c;
287 }
288
289fail:
290 if (written)
291 *written = count;
292 return retval;
293}
294
295errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
296 int whence, __u64 *ret_pos)
297{
298 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
299
300 if (whence == EXT2_SEEK_SET)
301 file->pos = offset;
302 else if (whence == EXT2_SEEK_CUR)
303 file->pos += offset;
304 else if (whence == EXT2_SEEK_END)
305 file->pos = EXT2_I_SIZE(&file->inode) + offset;
306 else
307 return EXT2_ET_INVALID_ARGUMENT;
308
309 if (ret_pos)
310 *ret_pos = file->pos;
311
312 return 0;
313}
314
315errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
316 int whence, ext2_off_t *ret_pos)
317{
318 __u64 loffset, ret_loffset;
319 errcode_t retval;
320
321 loffset = offset;
322 retval = ext2fs_file_llseek(file, loffset, whence, &ret_loffset);
323 if (ret_pos)
324 *ret_pos = (ext2_off_t) ret_loffset;
325 return retval;
326}
327
328
329/*
330 * This function returns the size of the file, according to the inode
331 */
332errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size)
333{
334 if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
335 return EXT2_ET_MAGIC_EXT2_FILE;
336 *ret_size = EXT2_I_SIZE(&file->inode);
337 return 0;
338}
339
340/*
341 * This function returns the size of the file, according to the inode
342 */
343ext2_off_t ext2fs_file_get_size(ext2_file_t file)
344{
345 __u64 size;
346
347 if (ext2fs_file_get_lsize(file, &size))
348 return 0;
349 if ((size >> 32) != 0)
350 return 0;
351 return size;
352}
353
354/*
355 * This function sets the size of the file, truncating it if necessary
356 *
357 * XXX still need to call truncate
358 */
359errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
360{
361 errcode_t retval;
362 EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
363
364 file->inode.i_size = size;
365 file->inode.i_size_high = 0;
366 if (file->ino) {
367 retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
368 if (retval)
369 return retval;
370 }
371
372 /*
373 * XXX truncate inode if necessary
374 */
375
376 return 0;
377}
diff --git a/e2fsprogs/ext2fs/finddev.c b/e2fsprogs/ext2fs/finddev.c
deleted file mode 100644
index 5e2cce940..000000000
--- a/e2fsprogs/ext2fs/finddev.c
+++ /dev/null
@@ -1,199 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * finddev.c -- this routine attempts to find a particular device in
4 * /dev
5 *
6 * Copyright (C) 2000 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#ifdef HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <stdlib.h>
20#include <string.h>
21#ifdef HAVE_SYS_TYPES_H
22#include <sys/types.h>
23#endif
24#ifdef HAVE_SYS_STAT_H
25#include <sys/stat.h>
26#endif
27#include <dirent.h>
28#ifdef HAVE_ERRNO_H
29#include <errno.h>
30#endif
31#ifdef HAVE_SYS_MKDEV_H
32#include <sys/mkdev.h>
33#endif
34
35#include "ext2_fs.h"
36#include "ext2fs.h"
37
38struct dir_list {
39 char *name;
40 struct dir_list *next;
41};
42
43/*
44 * This function adds an entry to the directory list
45 */
46static void add_to_dirlist(const char *name, struct dir_list **list)
47{
48 struct dir_list *dp;
49
50 dp = xmalloc(sizeof(struct dir_list));
51 dp->name = xmalloc(strlen(name)+1);
52 strcpy(dp->name, name);
53 dp->next = *list;
54 *list = dp;
55}
56
57/*
58 * This function frees a directory list
59 */
60static void free_dirlist(struct dir_list **list)
61{
62 struct dir_list *dp, *next;
63
64 for (dp = *list; dp; dp = next) {
65 next = dp->next;
66 free(dp->name);
67 free(dp);
68 }
69 *list = 0;
70}
71
72static int scan_dir(char *dir_name, dev_t device, struct dir_list **list,
73 char **ret_path)
74{
75 DIR *dir;
76 struct dirent *dp;
77 char path[1024], *cp;
78 int dirlen;
79 struct stat st;
80
81 dirlen = strlen(dir_name);
82 if ((dir = opendir(dir_name)) == NULL)
83 return errno;
84 dp = readdir(dir);
85 while (dp) {
86 if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
87 goto skip_to_next;
88 if (dp->d_name[0] == '.' &&
89 ((dp->d_name[1] == 0) ||
90 ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
91 goto skip_to_next;
92 sprintf(path, "%s/%s", dir_name, dp->d_name);
93 if (stat(path, &st) < 0)
94 goto skip_to_next;
95 if (S_ISDIR(st.st_mode))
96 add_to_dirlist(path, list);
97 if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
98 cp = xmalloc(strlen(path)+1);
99 strcpy(cp, path);
100 *ret_path = cp;
101 goto success;
102 }
103 skip_to_next:
104 dp = readdir(dir);
105 }
106success:
107 closedir(dir);
108 return 0;
109}
110
111/*
112 * This function finds the pathname to a block device with a given
113 * device number. It returns a pointer to allocated memory to the
114 * pathname on success, and NULL on failure.
115 */
116char *ext2fs_find_block_device(dev_t device)
117{
118 struct dir_list *list = 0, *new_list = 0;
119 struct dir_list *current;
120 char *ret_path = 0;
121
122 /*
123 * Add the starting directories to search...
124 */
125 add_to_dirlist("/devices", &list);
126 add_to_dirlist("/devfs", &list);
127 add_to_dirlist("/dev", &list);
128
129 while (list) {
130 current = list;
131 list = list->next;
132#ifdef DEBUG
133 printf("Scanning directory %s\n", current->name);
134#endif
135 scan_dir(current->name, device, &new_list, &ret_path);
136 free(current->name);
137 free(current);
138 if (ret_path)
139 break;
140 /*
141 * If we're done checking at this level, descend to
142 * the next level of subdirectories. (breadth-first)
143 */
144 if (list == 0) {
145 list = new_list;
146 new_list = 0;
147 }
148 }
149 free_dirlist(&list);
150 free_dirlist(&new_list);
151 return ret_path;
152}
153
154
155#ifdef DEBUG
156int main(int argc, char** argv)
157{
158 char *devname, *tmp;
159 int major, minor;
160 dev_t device;
161 const char *errmsg = "Cannot parse %s: %s\n";
162
163 if ((argc != 2) && (argc != 3)) {
164 fprintf(stderr, "Usage: %s device_number\n", argv[0]);
165 fprintf(stderr, "\t: %s major minor\n", argv[0]);
166 exit(1);
167 }
168 if (argc == 2) {
169 device = strtoul(argv[1], &tmp, 0);
170 if (*tmp) {
171 fprintf(stderr, errmsg, "device number", argv[1]);
172 exit(1);
173 }
174 } else {
175 major = strtoul(argv[1], &tmp, 0);
176 if (*tmp) {
177 fprintf(stderr, errmsg, "major number", argv[1]);
178 exit(1);
179 }
180 minor = strtoul(argv[2], &tmp, 0);
181 if (*tmp) {
182 fprintf(stderr, errmsg, "minor number", argv[2]);
183 exit(1);
184 }
185 device = makedev(major, minor);
186 printf("Looking for device 0x%04x (%d:%d)\n", device,
187 major, minor);
188 }
189 devname = ext2fs_find_block_device(device);
190 if (devname) {
191 printf("Found device! %s\n", devname);
192 free(devname);
193 } else {
194 printf("Cannot find device.\n");
195 }
196 return 0;
197}
198
199#endif
diff --git a/e2fsprogs/ext2fs/flushb.c b/e2fsprogs/ext2fs/flushb.c
deleted file mode 100644
index e42982653..000000000
--- a/e2fsprogs/ext2fs/flushb.c
+++ /dev/null
@@ -1,83 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * flushb.c --- Hides system-dependent information for both syncing a
4 * device to disk and to flush any buffers from disk cache.
5 *
6 * Copyright (C) 2000 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#if HAVE_ERRNO_H
16#include <errno.h>
17#endif
18#if HAVE_UNISTD_H
19#include <unistd.h>
20#endif
21#if HAVE_SYS_IOCTL_H
22#include <sys/ioctl.h>
23#endif
24#if HAVE_SYS_MOUNT_H
25#include <sys/param.h>
26#include <sys/mount.h> /* This may define BLKFLSBUF */
27#endif
28
29#include "ext2_fs.h"
30#include "ext2fs.h"
31
32/*
33 * For Linux, define BLKFLSBUF and FDFLUSH if necessary, since
34 * not all portable header file does so for us. This really should be
35 * fixed in the glibc header files. (Recent glibcs appear to define
36 * BLKFLSBUF in sys/mount.h, but FDFLUSH still doesn't seem to be
37 * defined anywhere portable.) Until then....
38 */
39#ifdef __linux__
40#ifndef BLKFLSBUF
41#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
42#endif
43#ifndef FDFLUSH
44#define FDFLUSH _IO(2,0x4b) /* flush floppy disk */
45#endif
46#endif
47
48/*
49 * This function will sync a device/file, and optionally attempt to
50 * flush the buffer cache. The latter is basically only useful for
51 * system benchmarks and for torturing systems in burn-in tests. :)
52 */
53errcode_t ext2fs_sync_device(int fd, int flushb)
54{
55 /*
56 * We always sync the device in case we're running on old
57 * kernels for which we can lose data if we don't. (There
58 * still is a race condition for those kernels, but this
59 * reduces it greatly.)
60 */
61 if (fsync (fd) == -1)
62 return errno;
63
64 if (flushb) {
65
66#ifdef BLKFLSBUF
67 if (ioctl (fd, BLKFLSBUF, 0) == 0)
68 return 0;
69#else
70#ifdef __GNUC__
71# warning BLKFLSBUF not defined
72#endif /* __GNUC__ */
73#endif
74#ifdef FDFLUSH
75 ioctl (fd, FDFLUSH, 0); /* In case this is a floppy */
76#else
77#ifdef __GNUC__
78# warning FDFLUSH not defined
79#endif /* __GNUC__ */
80#endif
81 }
82 return 0;
83}
diff --git a/e2fsprogs/ext2fs/freefs.c b/e2fsprogs/ext2fs/freefs.c
deleted file mode 100644
index 65c4ee794..000000000
--- a/e2fsprogs/ext2fs/freefs.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * freefs.c --- free an ext2 filesystem
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17
18#include "ext2_fs.h"
19#include "ext2fsP.h"
20
21static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
22
23void ext2fs_free(ext2_filsys fs)
24{
25 if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
26 return;
27 if (fs->image_io != fs->io) {
28 if (fs->image_io)
29 io_channel_close(fs->image_io);
30 }
31 if (fs->io) {
32 io_channel_close(fs->io);
33 }
34 ext2fs_free_mem(&fs->device_name);
35 ext2fs_free_mem(&fs->super);
36 ext2fs_free_mem(&fs->orig_super);
37 ext2fs_free_mem(&fs->group_desc);
38 ext2fs_free_block_bitmap(fs->block_map);
39 ext2fs_free_inode_bitmap(fs->inode_map);
40
41 ext2fs_badblocks_list_free(fs->badblocks);
42 fs->badblocks = 0;
43
44 ext2fs_free_dblist(fs->dblist);
45
46 if (fs->icache)
47 ext2fs_free_inode_cache(fs->icache);
48
49 fs->magic = 0;
50
51 ext2fs_free_mem(&fs);
52}
53
54void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
55{
56 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
57 return;
58
59 bitmap->magic = 0;
60 ext2fs_free_mem(&bitmap->description);
61 ext2fs_free_mem(&bitmap->bitmap);
62 ext2fs_free_mem(&bitmap);
63}
64
65void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
66{
67 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
68 return;
69
70 bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
71 ext2fs_free_generic_bitmap(bitmap);
72}
73
74void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
75{
76 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
77 return;
78
79 bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
80 ext2fs_free_generic_bitmap(bitmap);
81}
82
83/*
84 * Free the inode cache structure
85 */
86static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
87{
88 if (--icache->refcount)
89 return;
90 ext2fs_free_mem(&icache->buffer);
91 ext2fs_free_mem(&icache->cache);
92 icache->buffer_blk = 0;
93 ext2fs_free_mem(&icache);
94}
95
96/*
97 * This procedure frees a badblocks list.
98 */
99void ext2fs_u32_list_free(ext2_u32_list bb)
100{
101 if (!bb || bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
102 return;
103
104 ext2fs_free_mem(&bb->list);
105 ext2fs_free_mem(&bb);
106}
107
108void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
109{
110 ext2fs_u32_list_free((ext2_u32_list) bb);
111}
112
113
114/*
115 * Free a directory block list
116 */
117void ext2fs_free_dblist(ext2_dblist dblist)
118{
119 if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
120 return;
121
122 ext2fs_free_mem(&dblist->list);
123 if (dblist->fs && dblist->fs->dblist == dblist)
124 dblist->fs->dblist = 0;
125 dblist->magic = 0;
126 ext2fs_free_mem(&dblist);
127}
128
diff --git a/e2fsprogs/ext2fs/gen_bitmap.c b/e2fsprogs/ext2fs/gen_bitmap.c
deleted file mode 100644
index d0869c919..000000000
--- a/e2fsprogs/ext2fs/gen_bitmap.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * gen_bitmap.c --- Generic bitmap routines that used to be inlined.
4 *
5 * Copyright (C) 2001 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <fcntl.h>
20#include <time.h>
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
32 __u32 bitno)
33{
34 if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
35 ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
36 return 0;
37 }
38 return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
39}
40
41int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
42 blk_t bitno)
43{
44 if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
45 ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
46 return 0;
47 }
48 return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
49}
diff --git a/e2fsprogs/ext2fs/get_pathname.c b/e2fsprogs/ext2fs/get_pathname.c
deleted file mode 100644
index a98b2b9e5..000000000
--- a/e2fsprogs/ext2fs/get_pathname.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * get_pathname.c --- do directry/inode -> name translation
4 *
5 * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 * ext2fs_get_pathname(fs, dir, ino, name)
13 *
14 * This function translates takes two inode numbers into a
15 * string, placing the result in <name>. <dir> is the containing
16 * directory inode, and <ino> is the inode number itself. If
17 * <ino> is zero, then ext2fs_get_pathname will return pathname
18 * of the the directory <dir>.
19 *
20 */
21
22#include <stdio.h>
23#include <string.h>
24#if HAVE_UNISTD_H
25#include <unistd.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31struct get_pathname_struct {
32 ext2_ino_t search_ino;
33 ext2_ino_t parent;
34 char *name;
35 errcode_t errcode;
36};
37
38#ifdef __TURBOC__
39# pragma argsused
40#endif
41static int get_pathname_proc(struct ext2_dir_entry *dirent,
42 int offset EXT2FS_ATTR((unused)),
43 int blocksize EXT2FS_ATTR((unused)),
44 char *buf EXT2FS_ATTR((unused)),
45 void *priv_data)
46{
47 struct get_pathname_struct *gp;
48 errcode_t retval;
49
50 gp = (struct get_pathname_struct *) priv_data;
51
52 if (((dirent->name_len & 0xFF) == 2) &&
53 !strncmp(dirent->name, "..", 2))
54 gp->parent = dirent->inode;
55 if (dirent->inode == gp->search_ino) {
56 retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1,
57 &gp->name);
58 if (retval) {
59 gp->errcode = retval;
60 return DIRENT_ABORT;
61 }
62 strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF));
63 gp->name[dirent->name_len & 0xFF] = '\0';
64 return DIRENT_ABORT;
65 }
66 return 0;
67}
68
69static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
70 ext2_ino_t ino, int maxdepth,
71 char *buf, char **name)
72{
73 struct get_pathname_struct gp;
74 char *parent_name, *ret;
75 errcode_t retval;
76
77 if (dir == ino) {
78 retval = ext2fs_get_mem(2, name);
79 if (retval)
80 return retval;
81 strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : ".");
82 return 0;
83 }
84
85 if (!dir || (maxdepth < 0)) {
86 retval = ext2fs_get_mem(4, name);
87 if (retval)
88 return retval;
89 strcpy(*name, "...");
90 return 0;
91 }
92
93 gp.search_ino = ino;
94 gp.parent = 0;
95 gp.name = 0;
96 gp.errcode = 0;
97
98 retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
99 if (retval)
100 goto cleanup;
101 if (gp.errcode) {
102 retval = gp.errcode;
103 goto cleanup;
104 }
105
106 retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1,
107 buf, &parent_name);
108 if (retval)
109 goto cleanup;
110 if (!ino) {
111 *name = parent_name;
112 return 0;
113 }
114
115 if (gp.name)
116 retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2,
117 &ret);
118 else
119 retval = ext2fs_get_mem(strlen(parent_name)+5, &ret);
120 if (retval)
121 goto cleanup;
122
123 ret[0] = 0;
124 if (parent_name[1])
125 strcat(ret, parent_name);
126 strcat(ret, "/");
127 if (gp.name)
128 strcat(ret, gp.name);
129 else
130 strcat(ret, "???");
131 *name = ret;
132 ext2fs_free_mem(&parent_name);
133 retval = 0;
134
135cleanup:
136 ext2fs_free_mem(&gp.name);
137 return retval;
138}
139
140errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
141 char **name)
142{
143 char *buf;
144 errcode_t retval;
145
146 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
147
148 retval = ext2fs_get_mem(fs->blocksize, &buf);
149 if (retval)
150 return retval;
151 if (dir == ino)
152 ino = 0;
153 retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
154 ext2fs_free_mem(&buf);
155 return retval;
156
157}
diff --git a/e2fsprogs/ext2fs/getsectsize.c b/e2fsprogs/ext2fs/getsectsize.c
deleted file mode 100644
index 163ec65e5..000000000
--- a/e2fsprogs/ext2fs/getsectsize.c
+++ /dev/null
@@ -1,58 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * getsectsize.c --- get the sector size of a device.
4 *
5 * Copyright (C) 1995, 1995 Theodore Ts'o.
6 * Copyright (C) 2003 VMware, Inc.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#if HAVE_ERRNO_H
19#include <errno.h>
20#endif
21#include <fcntl.h>
22#ifdef HAVE_LINUX_FD_H
23#include <sys/ioctl.h>
24#include <linux/fd.h>
25#endif
26
27#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
28#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
29#endif
30
31#include "ext2_fs.h"
32#include "ext2fs.h"
33
34/*
35 * Returns the number of blocks in a partition
36 */
37errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
38{
39 int fd;
40
41#ifdef CONFIG_LFS
42 fd = open64(file, O_RDONLY);
43#else
44 fd = open(file, O_RDONLY);
45#endif
46 if (fd < 0)
47 return errno;
48
49#ifdef BLKSSZGET
50 if (ioctl(fd, BLKSSZGET, sectsize) >= 0) {
51 close(fd);
52 return 0;
53 }
54#endif
55 *sectsize = 0;
56 close(fd);
57 return 0;
58}
diff --git a/e2fsprogs/ext2fs/getsize.c b/e2fsprogs/ext2fs/getsize.c
deleted file mode 100644
index 516886c1f..000000000
--- a/e2fsprogs/ext2fs/getsize.c
+++ /dev/null
@@ -1,291 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * getsize.c --- get the size of a partition.
4 *
5 * Copyright (C) 1995, 1995 Theodore Ts'o.
6 * Copyright (C) 2003 VMware, Inc.
7 *
8 * Windows version of ext2fs_get_device_size by Chris Li, VMware.
9 *
10 * %Begin-Header%
11 * This file may be redistributed under the terms of the GNU Public
12 * License.
13 * %End-Header%
14 */
15
16#include <stdio.h>
17#if HAVE_UNISTD_H
18#include <unistd.h>
19#endif
20#if HAVE_ERRNO_H
21#include <errno.h>
22#endif
23#include <fcntl.h>
24#ifdef HAVE_SYS_IOCTL_H
25#include <sys/ioctl.h>
26#endif
27#ifdef HAVE_LINUX_FD_H
28#include <linux/fd.h>
29#endif
30#ifdef HAVE_SYS_DISKLABEL_H
31#include <sys/disklabel.h>
32#endif
33#ifdef HAVE_SYS_DISK_H
34#ifdef HAVE_SYS_QUEUE_H
35#include <sys/queue.h> /* for LIST_HEAD */
36#endif
37#include <sys/disk.h>
38#endif
39#ifdef __linux__
40#include <sys/utsname.h>
41#endif
42
43#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
44#define BLKGETSIZE _IO(0x12,96) /* return device size */
45#endif
46
47#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
48#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
49#endif
50
51#ifdef APPLE_DARWIN
52#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
53#endif /* APPLE_DARWIN */
54
55#include "ext2_fs.h"
56#include "ext2fs.h"
57
58#if defined(__CYGWIN__) || defined (WIN32)
59#include <windows.h>
60#include <winioctl.h>
61
62#if (_WIN32_WINNT >= 0x0500)
63#define HAVE_GET_FILE_SIZE_EX 1
64#endif
65
66errcode_t ext2fs_get_device_size(const char *file, int blocksize,
67 blk_t *retblocks)
68{
69 HANDLE dev;
70 PARTITION_INFORMATION pi;
71 DISK_GEOMETRY gi;
72 DWORD retbytes;
73#ifdef HAVE_GET_FILE_SIZE_EX
74 LARGE_INTEGER filesize;
75#else
76 DWORD filesize;
77#endif /* HAVE_GET_FILE_SIZE_EX */
78
79 dev = CreateFile(file, GENERIC_READ,
80 FILE_SHARE_READ | FILE_SHARE_WRITE ,
81 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
82
83 if (dev == INVALID_HANDLE_VALUE)
84 return EBADF;
85 if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
86 &pi, sizeof(PARTITION_INFORMATION),
87 &pi, sizeof(PARTITION_INFORMATION),
88 &retbytes, NULL)) {
89
90 *retblocks = pi.PartitionLength.QuadPart / blocksize;
91
92 } else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
93 &gi, sizeof(DISK_GEOMETRY),
94 &gi, sizeof(DISK_GEOMETRY),
95 &retbytes, NULL)) {
96
97 *retblocks = gi.BytesPerSector *
98 gi.SectorsPerTrack *
99 gi.TracksPerCylinder *
100 gi.Cylinders.QuadPart / blocksize;
101
102#ifdef HAVE_GET_FILE_SIZE_EX
103 } else if (GetFileSizeEx(dev, &filesize)) {
104 *retblocks = filesize.QuadPart / blocksize;
105 }
106#else
107 } else {
108 filesize = GetFileSize(dev, NULL);
109 if (INVALID_FILE_SIZE != filesize) {
110 *retblocks = filesize / blocksize;
111 }
112 }
113#endif /* HAVE_GET_FILE_SIZE_EX */
114
115 CloseHandle(dev);
116 return 0;
117}
118
119#else
120
121static int valid_offset (int fd, ext2_loff_t offset)
122{
123 char ch;
124
125 if (ext2fs_llseek (fd, offset, 0) < 0)
126 return 0;
127 if (read (fd, &ch, 1) < 1)
128 return 0;
129 return 1;
130}
131
132/*
133 * Returns the number of blocks in a partition
134 */
135errcode_t ext2fs_get_device_size(const char *file, int blocksize,
136 blk_t *retblocks)
137{
138 int fd;
139 int valid_blkgetsize64 = 1;
140#ifdef __linux__
141 struct utsname ut;
142#endif
143 unsigned long long size64;
144 unsigned long size;
145 ext2_loff_t high, low;
146#ifdef FDGETPRM
147 struct floppy_struct this_floppy;
148#endif
149#ifdef HAVE_SYS_DISKLABEL_H
150 int part;
151 struct disklabel lab;
152 struct partition *pp;
153 char ch;
154#endif /* HAVE_SYS_DISKLABEL_H */
155
156#ifdef CONFIG_LFS
157 fd = open64(file, O_RDONLY);
158#else
159 fd = open(file, O_RDONLY);
160#endif
161 if (fd < 0)
162 return errno;
163
164#ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */
165 if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
166 if ((sizeof(*retblocks) < sizeof(unsigned long long))
167 && ((size64 / (blocksize / 512)) > 0xFFFFFFFF))
168 return EFBIG;
169 close(fd);
170 *retblocks = size64 / (blocksize / 512);
171 return 0;
172 }
173#endif
174
175#ifdef BLKGETSIZE64
176#ifdef __linux__
177 if ((uname(&ut) == 0) &&
178 ((ut.release[0] == '2') && (ut.release[1] == '.') &&
179 (ut.release[2] < '6') && (ut.release[3] == '.')))
180 valid_blkgetsize64 = 0;
181#endif
182 if (valid_blkgetsize64 &&
183 ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
184 if ((sizeof(*retblocks) < sizeof(unsigned long long))
185 && ((size64 / blocksize) > 0xFFFFFFFF))
186 return EFBIG;
187 close(fd);
188 *retblocks = size64 / blocksize;
189 return 0;
190 }
191#endif
192
193#ifdef BLKGETSIZE
194 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
195 close(fd);
196 *retblocks = size / (blocksize / 512);
197 return 0;
198 }
199#endif
200
201#ifdef FDGETPRM
202 if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
203 close(fd);
204 *retblocks = this_floppy.size / (blocksize / 512);
205 return 0;
206 }
207#endif
208
209#ifdef HAVE_SYS_DISKLABEL_H
210#if defined(DIOCGMEDIASIZE)
211 {
212 off_t ms;
213 u_int bs;
214 if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
215 *retblocks = ms / blocksize;
216 return 0;
217 }
218 }
219#elif defined(DIOCGDINFO)
220 /* old disklabel interface */
221 part = strlen(file) - 1;
222 if (part >= 0) {
223 ch = file[part];
224 if (isdigit(ch))
225 part = 0;
226 else if (ch >= 'a' && ch <= 'h')
227 part = ch - 'a';
228 else
229 part = -1;
230 }
231 if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
232 pp = &lab.d_partitions[part];
233 if (pp->p_size) {
234 close(fd);
235 *retblocks = pp->p_size / (blocksize / 512);
236 return 0;
237 }
238 }
239#endif /* defined(DIOCG*) */
240#endif /* HAVE_SYS_DISKLABEL_H */
241
242 /*
243 * OK, we couldn't figure it out by using a specialized ioctl,
244 * which is generally the best way. So do binary search to
245 * find the size of the partition.
246 */
247 low = 0;
248 for (high = 1024; valid_offset (fd, high); high *= 2)
249 low = high;
250 while (low < high - 1)
251 {
252 const ext2_loff_t mid = (low + high) / 2;
253
254 if (valid_offset (fd, mid))
255 low = mid;
256 else
257 high = mid;
258 }
259 valid_offset (fd, 0);
260 close(fd);
261 size64 = low + 1;
262 if ((sizeof(*retblocks) < sizeof(unsigned long long))
263 && ((size64 / blocksize) > 0xFFFFFFFF))
264 return EFBIG;
265 *retblocks = size64 / blocksize;
266 return 0;
267}
268
269#endif /* WIN32 */
270
271#ifdef DEBUG
272int main(int argc, char **argv)
273{
274 blk_t blocks;
275 int retval;
276
277 if (argc < 2) {
278 fprintf(stderr, "Usage: %s device\n", argv[0]);
279 exit(1);
280 }
281
282 retval = ext2fs_get_device_size(argv[1], 1024, &blocks);
283 if (retval) {
284 com_err(argv[0], retval,
285 "while calling ext2fs_get_device_size");
286 exit(1);
287 }
288 printf("Device %s has %d 1k blocks.\n", argv[1], blocks);
289 exit(0);
290}
291#endif
diff --git a/e2fsprogs/ext2fs/icount.c b/e2fsprogs/ext2fs/icount.c
deleted file mode 100644
index 7ab5f51f4..000000000
--- a/e2fsprogs/ext2fs/icount.c
+++ /dev/null
@@ -1,467 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * icount.c --- an efficient inode count abstraction
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#if HAVE_UNISTD_H
14#include <unistd.h>
15#endif
16#include <string.h>
17#include <stdio.h>
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22/*
23 * The data storage strategy used by icount relies on the observation
24 * that most inode counts are either zero (for non-allocated inodes),
25 * one (for most files), and only a few that are two or more
26 * (directories and files that are linked to more than one directory).
27 *
28 * Also, e2fsck tends to load the icount data sequentially.
29 *
30 * So, we use an inode bitmap to indicate which inodes have a count of
31 * one, and then use a sorted list to store the counts for inodes
32 * which are greater than one.
33 *
34 * We also use an optional bitmap to indicate which inodes are already
35 * in the sorted list, to speed up the use of this abstraction by
36 * e2fsck's pass 2. Pass 2 increments inode counts as it finds them,
37 * so this extra bitmap avoids searching the sorted list to see if a
38 * particular inode is on the sorted list already.
39 */
40
41struct ext2_icount_el {
42 ext2_ino_t ino;
43 __u16 count;
44};
45
46struct ext2_icount {
47 errcode_t magic;
48 ext2fs_inode_bitmap single;
49 ext2fs_inode_bitmap multiple;
50 ext2_ino_t count;
51 ext2_ino_t size;
52 ext2_ino_t num_inodes;
53 ext2_ino_t cursor;
54 struct ext2_icount_el *list;
55};
56
57void ext2fs_free_icount(ext2_icount_t icount)
58{
59 if (!icount)
60 return;
61
62 icount->magic = 0;
63 ext2fs_free_mem(&icount->list);
64 ext2fs_free_inode_bitmap(icount->single);
65 ext2fs_free_inode_bitmap(icount->multiple);
66 ext2fs_free_mem(&icount);
67}
68
69errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, unsigned int size,
70 ext2_icount_t hint, ext2_icount_t *ret)
71{
72 ext2_icount_t icount;
73 errcode_t retval;
74 size_t bytes;
75 ext2_ino_t i;
76
77 if (hint) {
78 EXT2_CHECK_MAGIC(hint, EXT2_ET_MAGIC_ICOUNT);
79 if (hint->size > size)
80 size = (size_t) hint->size;
81 }
82
83 retval = ext2fs_get_mem(sizeof(struct ext2_icount), &icount);
84 if (retval)
85 return retval;
86 memset(icount, 0, sizeof(struct ext2_icount));
87
88 retval = ext2fs_allocate_inode_bitmap(fs, 0,
89 &icount->single);
90 if (retval)
91 goto errout;
92
93 if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
94 retval = ext2fs_allocate_inode_bitmap(fs, 0,
95 &icount->multiple);
96 if (retval)
97 goto errout;
98 } else
99 icount->multiple = 0;
100
101 if (size) {
102 icount->size = size;
103 } else {
104 /*
105 * Figure out how many special case inode counts we will
106 * have. We know we will need one for each directory;
107 * we also need to reserve some extra room for file links
108 */
109 retval = ext2fs_get_num_dirs(fs, &icount->size);
110 if (retval)
111 goto errout;
112 icount->size += fs->super->s_inodes_count / 50;
113 }
114
115 bytes = (size_t) (icount->size * sizeof(struct ext2_icount_el));
116 retval = ext2fs_get_mem(bytes, &icount->list);
117 if (retval)
118 goto errout;
119 memset(icount->list, 0, bytes);
120
121 icount->magic = EXT2_ET_MAGIC_ICOUNT;
122 icount->count = 0;
123 icount->cursor = 0;
124 icount->num_inodes = fs->super->s_inodes_count;
125
126 /*
127 * Populate the sorted list with those entries which were
128 * found in the hint icount (since those are ones which will
129 * likely need to be in the sorted list this time around).
130 */
131 if (hint) {
132 for (i=0; i < hint->count; i++)
133 icount->list[i].ino = hint->list[i].ino;
134 icount->count = hint->count;
135 }
136
137 *ret = icount;
138 return 0;
139
140errout:
141 ext2fs_free_icount(icount);
142 return retval;
143}
144
145errcode_t ext2fs_create_icount(ext2_filsys fs, int flags,
146 unsigned int size,
147 ext2_icount_t *ret)
148{
149 return ext2fs_create_icount2(fs, flags, size, 0, ret);
150}
151
152/*
153 * insert_icount_el() --- Insert a new entry into the sorted list at a
154 * specified position.
155 */
156static struct ext2_icount_el *insert_icount_el(ext2_icount_t icount,
157 ext2_ino_t ino, int pos)
158{
159 struct ext2_icount_el *el;
160 errcode_t retval;
161 ext2_ino_t new_size = 0;
162 int num;
163
164 if (icount->count >= icount->size) {
165 if (icount->count) {
166 new_size = icount->list[(unsigned)icount->count-1].ino;
167 new_size = (ext2_ino_t) (icount->count *
168 ((float) icount->num_inodes / new_size));
169 }
170 if (new_size < (icount->size + 100))
171 new_size = icount->size + 100;
172 retval = ext2fs_resize_mem((size_t) icount->size *
173 sizeof(struct ext2_icount_el),
174 (size_t) new_size *
175 sizeof(struct ext2_icount_el),
176 &icount->list);
177 if (retval)
178 return 0;
179 icount->size = new_size;
180 }
181 num = (int) icount->count - pos;
182 if (num < 0)
183 return 0; /* should never happen */
184 if (num) {
185 memmove(&icount->list[pos+1], &icount->list[pos],
186 sizeof(struct ext2_icount_el) * num);
187 }
188 icount->count++;
189 el = &icount->list[pos];
190 el->count = 0;
191 el->ino = ino;
192 return el;
193}
194
195/*
196 * get_icount_el() --- given an inode number, try to find icount
197 * information in the sorted list. If the create flag is set,
198 * and we can't find an entry, create one in the sorted list.
199 */
200static struct ext2_icount_el *get_icount_el(ext2_icount_t icount,
201 ext2_ino_t ino, int create)
202{
203 float range;
204 int low, high, mid;
205 ext2_ino_t lowval, highval;
206
207 if (!icount || !icount->list)
208 return 0;
209
210 if (create && ((icount->count == 0) ||
211 (ino > icount->list[(unsigned)icount->count-1].ino))) {
212 return insert_icount_el(icount, ino, (unsigned) icount->count);
213 }
214 if (icount->count == 0)
215 return 0;
216
217 if (icount->cursor >= icount->count)
218 icount->cursor = 0;
219 if (ino == icount->list[icount->cursor].ino)
220 return &icount->list[icount->cursor++];
221 low = 0;
222 high = (int) icount->count-1;
223 while (low <= high) {
224 if (low == high)
225 mid = low;
226 else {
227 /* Interpolate for efficiency */
228 lowval = icount->list[low].ino;
229 highval = icount->list[high].ino;
230
231 if (ino < lowval)
232 range = 0;
233 else if (ino > highval)
234 range = 1;
235 else
236 range = ((float) (ino - lowval)) /
237 (highval - lowval);
238 mid = low + ((int) (range * (high-low)));
239 }
240 if (ino == icount->list[mid].ino) {
241 icount->cursor = mid+1;
242 return &icount->list[mid];
243 }
244 if (ino < icount->list[mid].ino)
245 high = mid-1;
246 else
247 low = mid+1;
248 }
249 /*
250 * If we need to create a new entry, it should be right at
251 * low (where high will be left at low-1).
252 */
253 if (create)
254 return insert_icount_el(icount, ino, low);
255 return 0;
256}
257
258errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
259{
260 errcode_t ret = 0;
261 unsigned int i;
262 const char *bad = "bad icount";
263
264 EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
265
266 if (icount->count > icount->size) {
267 fprintf(out, "%s: count > size\n", bad);
268 return EXT2_ET_INVALID_ARGUMENT;
269 }
270 for (i=1; i < icount->count; i++) {
271 if (icount->list[i-1].ino >= icount->list[i].ino) {
272 fprintf(out, "%s: list[%d].ino=%u, list[%d].ino=%u\n",
273 bad, i-1, icount->list[i-1].ino,
274 i, icount->list[i].ino);
275 ret = EXT2_ET_INVALID_ARGUMENT;
276 }
277 }
278 return ret;
279}
280
281errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
282{
283 struct ext2_icount_el *el;
284
285 EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
286
287 if (!ino || (ino > icount->num_inodes))
288 return EXT2_ET_INVALID_ARGUMENT;
289
290 if (ext2fs_test_inode_bitmap(icount->single, ino)) {
291 *ret = 1;
292 return 0;
293 }
294 if (icount->multiple &&
295 !ext2fs_test_inode_bitmap(icount->multiple, ino)) {
296 *ret = 0;
297 return 0;
298 }
299 el = get_icount_el(icount, ino, 0);
300 if (!el) {
301 *ret = 0;
302 return 0;
303 }
304 *ret = el->count;
305 return 0;
306}
307
308errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
309 __u16 *ret)
310{
311 struct ext2_icount_el *el;
312
313 EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
314
315 if (!ino || (ino > icount->num_inodes))
316 return EXT2_ET_INVALID_ARGUMENT;
317
318 if (ext2fs_test_inode_bitmap(icount->single, ino)) {
319 /*
320 * If the existing count is 1, then we know there is
321 * no entry in the list.
322 */
323 el = get_icount_el(icount, ino, 1);
324 if (!el)
325 return EXT2_ET_NO_MEMORY;
326 ext2fs_unmark_inode_bitmap(icount->single, ino);
327 el->count = 2;
328 } else if (icount->multiple) {
329 /*
330 * The count is either zero or greater than 1; if the
331 * inode is set in icount->multiple, then there should
332 * be an entry in the list, so find it using
333 * get_icount_el().
334 */
335 if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
336 el = get_icount_el(icount, ino, 1);
337 if (!el)
338 return EXT2_ET_NO_MEMORY;
339 el->count++;
340 } else {
341 /*
342 * The count was zero; mark the single bitmap
343 * and return.
344 */
345 zero_count:
346 ext2fs_mark_inode_bitmap(icount->single, ino);
347 if (ret)
348 *ret = 1;
349 return 0;
350 }
351 } else {
352 /*
353 * The count is either zero or greater than 1; try to
354 * find an entry in the list to determine which.
355 */
356 el = get_icount_el(icount, ino, 0);
357 if (!el) {
358 /* No entry means the count was zero */
359 goto zero_count;
360 }
361 el = get_icount_el(icount, ino, 1);
362 if (!el)
363 return EXT2_ET_NO_MEMORY;
364 el->count++;
365 }
366 if (icount->multiple)
367 ext2fs_mark_inode_bitmap(icount->multiple, ino);
368 if (ret)
369 *ret = el->count;
370 return 0;
371}
372
373errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
374 __u16 *ret)
375{
376 struct ext2_icount_el *el;
377
378 if (!ino || (ino > icount->num_inodes))
379 return EXT2_ET_INVALID_ARGUMENT;
380
381 EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
382
383 if (ext2fs_test_inode_bitmap(icount->single, ino)) {
384 ext2fs_unmark_inode_bitmap(icount->single, ino);
385 if (icount->multiple)
386 ext2fs_unmark_inode_bitmap(icount->multiple, ino);
387 else {
388 el = get_icount_el(icount, ino, 0);
389 if (el)
390 el->count = 0;
391 }
392 if (ret)
393 *ret = 0;
394 return 0;
395 }
396
397 if (icount->multiple &&
398 !ext2fs_test_inode_bitmap(icount->multiple, ino))
399 return EXT2_ET_INVALID_ARGUMENT;
400
401 el = get_icount_el(icount, ino, 0);
402 if (!el || el->count == 0)
403 return EXT2_ET_INVALID_ARGUMENT;
404
405 el->count--;
406 if (el->count == 1)
407 ext2fs_mark_inode_bitmap(icount->single, ino);
408 if ((el->count == 0) && icount->multiple)
409 ext2fs_unmark_inode_bitmap(icount->multiple, ino);
410
411 if (ret)
412 *ret = el->count;
413 return 0;
414}
415
416errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
417 __u16 count)
418{
419 struct ext2_icount_el *el;
420
421 if (!ino || (ino > icount->num_inodes))
422 return EXT2_ET_INVALID_ARGUMENT;
423
424 EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
425
426 if (count == 1) {
427 ext2fs_mark_inode_bitmap(icount->single, ino);
428 if (icount->multiple)
429 ext2fs_unmark_inode_bitmap(icount->multiple, ino);
430 return 0;
431 }
432 if (count == 0) {
433 ext2fs_unmark_inode_bitmap(icount->single, ino);
434 if (icount->multiple) {
435 /*
436 * If the icount->multiple bitmap is enabled,
437 * we can just clear both bitmaps and we're done
438 */
439 ext2fs_unmark_inode_bitmap(icount->multiple, ino);
440 } else {
441 el = get_icount_el(icount, ino, 0);
442 if (el)
443 el->count = 0;
444 }
445 return 0;
446 }
447
448 /*
449 * Get the icount element
450 */
451 el = get_icount_el(icount, ino, 1);
452 if (!el)
453 return EXT2_ET_NO_MEMORY;
454 el->count = count;
455 ext2fs_unmark_inode_bitmap(icount->single, ino);
456 if (icount->multiple)
457 ext2fs_mark_inode_bitmap(icount->multiple, ino);
458 return 0;
459}
460
461ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount)
462{
463 if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
464 return 0;
465
466 return icount->size;
467}
diff --git a/e2fsprogs/ext2fs/imager.c b/e2fsprogs/ext2fs/imager.c
deleted file mode 100644
index e82321efa..000000000
--- a/e2fsprogs/ext2fs/imager.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * image.c --- writes out the critical parts of the filesystem as a
4 * flat file.
5 *
6 * Copyright (C) 2000 Theodore Ts'o.
7 *
8 * Note: this uses the POSIX IO interfaces, unlike most of the other
9 * functions in this library. So sue me.
10 *
11 * %Begin-Header%
12 * This file may be redistributed under the terms of the GNU Public
13 * License.
14 * %End-Header%
15 */
16
17#include <stdio.h>
18#include <string.h>
19#if HAVE_UNISTD_H
20#include <unistd.h>
21#endif
22#if HAVE_ERRNO_H
23#include <errno.h>
24#endif
25#include <fcntl.h>
26#include <time.h>
27#if HAVE_SYS_STAT_H
28#include <sys/stat.h>
29#endif
30#if HAVE_SYS_TYPES_H
31#include <sys/types.h>
32#endif
33
34#include "ext2_fs.h"
35#include "ext2fs.h"
36
37#ifndef HAVE_TYPE_SSIZE_T
38typedef int ssize_t;
39#endif
40
41/*
42 * This function returns 1 if the specified block is all zeros
43 */
44static int check_zero_block(char *buf, int blocksize)
45{
46 char *cp = buf;
47 int left = blocksize;
48
49 while (left > 0) {
50 if (*cp++)
51 return 0;
52 left--;
53 }
54 return 1;
55}
56
57/*
58 * Write the inode table out as a single block.
59 */
60#define BUF_BLOCKS 32
61
62errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags)
63{
64 unsigned int group, left, c, d;
65 char *buf, *cp;
66 blk_t blk;
67 ssize_t actual;
68 errcode_t retval;
69
70 buf = xmalloc(fs->blocksize * BUF_BLOCKS);
71
72 for (group = 0; group < fs->group_desc_count; group++) {
73 blk = fs->group_desc[(unsigned)group].bg_inode_table;
74 if (!blk)
75 return EXT2_ET_MISSING_INODE_TABLE;
76 left = fs->inode_blocks_per_group;
77 while (left) {
78 c = BUF_BLOCKS;
79 if (c > left)
80 c = left;
81 retval = io_channel_read_blk(fs->io, blk, c, buf);
82 if (retval)
83 goto errout;
84 cp = buf;
85 while (c) {
86 if (!(flags & IMAGER_FLAG_SPARSEWRITE)) {
87 d = c;
88 goto skip_sparse;
89 }
90 /* Skip zero blocks */
91 if (check_zero_block(cp, fs->blocksize)) {
92 c--;
93 blk++;
94 left--;
95 cp += fs->blocksize;
96 lseek(fd, fs->blocksize, SEEK_CUR);
97 continue;
98 }
99 /* Find non-zero blocks */
100 for (d=1; d < c; d++) {
101 if (check_zero_block(cp + d*fs->blocksize, fs->blocksize))
102 break;
103 }
104 skip_sparse:
105 actual = write(fd, cp, fs->blocksize * d);
106 if (actual == -1) {
107 retval = errno;
108 goto errout;
109 }
110 if (actual != (ssize_t) (fs->blocksize * d)) {
111 retval = EXT2_ET_SHORT_WRITE;
112 goto errout;
113 }
114 blk += d;
115 left -= d;
116 cp += fs->blocksize * d;
117 c -= d;
118 }
119 }
120 }
121 retval = 0;
122
123errout:
124 free(buf);
125 return retval;
126}
127
128/*
129 * Read in the inode table and stuff it into place
130 */
131errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd,
132 int flags EXT2FS_ATTR((unused)))
133{
134 unsigned int group, c, left;
135 char *buf;
136 blk_t blk;
137 ssize_t actual;
138 errcode_t retval;
139
140 buf = xmalloc(fs->blocksize * BUF_BLOCKS);
141
142 for (group = 0; group < fs->group_desc_count; group++) {
143 blk = fs->group_desc[(unsigned)group].bg_inode_table;
144 if (!blk) {
145 retval = EXT2_ET_MISSING_INODE_TABLE;
146 goto errout;
147 }
148 left = fs->inode_blocks_per_group;
149 while (left) {
150 c = BUF_BLOCKS;
151 if (c > left)
152 c = left;
153 actual = read(fd, buf, fs->blocksize * c);
154 if (actual == -1) {
155 retval = errno;
156 goto errout;
157 }
158 if (actual != (ssize_t) (fs->blocksize * c)) {
159 retval = EXT2_ET_SHORT_READ;
160 goto errout;
161 }
162 retval = io_channel_write_blk(fs->io, blk, c, buf);
163 if (retval)
164 goto errout;
165
166 blk += c;
167 left -= c;
168 }
169 }
170 retval = ext2fs_flush_icache(fs);
171
172errout:
173 free(buf);
174 return retval;
175}
176
177/*
178 * Write out superblock and group descriptors
179 */
180errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
181 int flags EXT2FS_ATTR((unused)))
182{
183 char *buf, *cp;
184 ssize_t actual;
185 errcode_t retval;
186
187 buf = xmalloc(fs->blocksize);
188
189 /*
190 * Write out the superblock
191 */
192 memset(buf, 0, fs->blocksize);
193 memcpy(buf, fs->super, SUPERBLOCK_SIZE);
194 actual = write(fd, buf, fs->blocksize);
195 if (actual == -1) {
196 retval = errno;
197 goto errout;
198 }
199 if (actual != (ssize_t) fs->blocksize) {
200 retval = EXT2_ET_SHORT_WRITE;
201 goto errout;
202 }
203
204 /*
205 * Now write out the block group descriptors
206 */
207 cp = (char *) fs->group_desc;
208 actual = write(fd, cp, fs->blocksize * fs->desc_blocks);
209 if (actual == -1) {
210 retval = errno;
211 goto errout;
212 }
213 if (actual != (ssize_t) (fs->blocksize * fs->desc_blocks)) {
214 retval = EXT2_ET_SHORT_WRITE;
215 goto errout;
216 }
217
218 retval = 0;
219
220errout:
221 free(buf);
222 return retval;
223}
224
225/*
226 * Read the superblock and group descriptors and overwrite them.
227 */
228errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd,
229 int flags EXT2FS_ATTR((unused)))
230{
231 char *buf;
232 ssize_t actual, size;
233 errcode_t retval;
234
235 size = fs->blocksize * (fs->group_desc_count + 1);
236 buf = xmalloc(size);
237
238 /*
239 * Read it all in.
240 */
241 actual = read(fd, buf, size);
242 if (actual == -1) {
243 retval = errno;
244 goto errout;
245 }
246 if (actual != size) {
247 retval = EXT2_ET_SHORT_READ;
248 goto errout;
249 }
250
251 /*
252 * Now copy in the superblock and group descriptors
253 */
254 memcpy(fs->super, buf, SUPERBLOCK_SIZE);
255
256 memcpy(fs->group_desc, buf + fs->blocksize,
257 fs->blocksize * fs->group_desc_count);
258
259 retval = 0;
260
261errout:
262 free(buf);
263 return retval;
264}
265
266/*
267 * Write the block/inode bitmaps.
268 */
269errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
270{
271 char *ptr;
272 int c, size;
273 char zero_buf[1024];
274 ssize_t actual;
275 errcode_t retval;
276
277 if (flags & IMAGER_FLAG_INODEMAP) {
278 if (!fs->inode_map) {
279 retval = ext2fs_read_inode_bitmap(fs);
280 if (retval)
281 return retval;
282 }
283 ptr = fs->inode_map->bitmap;
284 size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
285 } else {
286 if (!fs->block_map) {
287 retval = ext2fs_read_block_bitmap(fs);
288 if (retval)
289 return retval;
290 }
291 ptr = fs->block_map->bitmap;
292 size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
293 }
294 size = size * fs->group_desc_count;
295
296 actual = write(fd, ptr, size);
297 if (actual == -1) {
298 retval = errno;
299 goto errout;
300 }
301 if (actual != size) {
302 retval = EXT2_ET_SHORT_WRITE;
303 goto errout;
304 }
305 size = size % fs->blocksize;
306 memset(zero_buf, 0, sizeof(zero_buf));
307 if (size) {
308 size = fs->blocksize - size;
309 while (size) {
310 c = size;
311 if (c > (int) sizeof(zero_buf))
312 c = sizeof(zero_buf);
313 actual = write(fd, zero_buf, c);
314 if (actual == -1) {
315 retval = errno;
316 goto errout;
317 }
318 if (actual != c) {
319 retval = EXT2_ET_SHORT_WRITE;
320 goto errout;
321 }
322 size -= c;
323 }
324 }
325 retval = 0;
326errout:
327 return retval;
328}
329
330
331/*
332 * Read the block/inode bitmaps.
333 */
334errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
335{
336 char *ptr, *buf = 0;
337 int size;
338 ssize_t actual;
339 errcode_t retval;
340
341 if (flags & IMAGER_FLAG_INODEMAP) {
342 if (!fs->inode_map) {
343 retval = ext2fs_read_inode_bitmap(fs);
344 if (retval)
345 return retval;
346 }
347 ptr = fs->inode_map->bitmap;
348 size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
349 } else {
350 if (!fs->block_map) {
351 retval = ext2fs_read_block_bitmap(fs);
352 if (retval)
353 return retval;
354 }
355 ptr = fs->block_map->bitmap;
356 size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
357 }
358 size = size * fs->group_desc_count;
359
360 buf = xmalloc(size);
361
362 actual = read(fd, buf, size);
363 if (actual == -1) {
364 retval = errno;
365 goto errout;
366 }
367 if (actual != size) {
368 retval = EXT2_ET_SHORT_WRITE;
369 goto errout;
370 }
371 memcpy(ptr, buf, size);
372
373 retval = 0;
374errout:
375 free(buf);
376 return retval;
377}
diff --git a/e2fsprogs/ext2fs/ind_block.c b/e2fsprogs/ext2fs/ind_block.c
deleted file mode 100644
index c86a1c59a..000000000
--- a/e2fsprogs/ext2fs/ind_block.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ind_block.c --- indirect block I/O routines
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
6 * 2001, 2002, 2003, 2004, 2005 by Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19
20#include "ext2_fs.h"
21#include "ext2fs.h"
22
23errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf)
24{
25 errcode_t retval;
26#if BB_BIG_ENDIAN
27 blk_t *block_nr;
28 int i;
29 int limit = fs->blocksize >> 2;
30#endif
31
32 if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
33 (fs->io != fs->image_io))
34 memset(buf, 0, fs->blocksize);
35 else {
36 retval = io_channel_read_blk(fs->io, blk, 1, buf);
37 if (retval)
38 return retval;
39 }
40#if BB_BIG_ENDIAN
41 if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_READ)) {
42 block_nr = (blk_t *) buf;
43 for (i = 0; i < limit; i++, block_nr++)
44 *block_nr = ext2fs_swab32(*block_nr);
45 }
46#endif
47 return 0;
48}
49
50errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf)
51{
52#if BB_BIG_ENDIAN
53 blk_t *block_nr;
54 int i;
55 int limit = fs->blocksize >> 2;
56#endif
57
58 if (fs->flags & EXT2_FLAG_IMAGE_FILE)
59 return 0;
60
61#if BB_BIG_ENDIAN
62 if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_WRITE)) {
63 block_nr = (blk_t *) buf;
64 for (i = 0; i < limit; i++, block_nr++)
65 *block_nr = ext2fs_swab32(*block_nr);
66 }
67#endif
68 return io_channel_write_blk(fs->io, blk, 1, buf);
69}
70
71
diff --git a/e2fsprogs/ext2fs/initialize.c b/e2fsprogs/ext2fs/initialize.c
deleted file mode 100644
index ef1d34379..000000000
--- a/e2fsprogs/ext2fs/initialize.c
+++ /dev/null
@@ -1,388 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * initialize.c --- initialize a filesystem handle given superblock
4 * parameters. Used by mke2fs when initializing a filesystem.
5 *
6 * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#include <fcntl.h>
20#include <time.h>
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fs.h"
30
31#if defined(__linux__) && defined(EXT2_OS_LINUX)
32#define CREATOR_OS EXT2_OS_LINUX
33#else
34#if defined(__GNU__) && defined(EXT2_OS_HURD)
35#define CREATOR_OS EXT2_OS_HURD
36#else
37#if defined(__FreeBSD__) && defined(EXT2_OS_FREEBSD)
38#define CREATOR_OS EXT2_OS_FREEBSD
39#else
40#if defined(LITES) && defined(EXT2_OS_LITES)
41#define CREATOR_OS EXT2_OS_LITES
42#else
43#define CREATOR_OS EXT2_OS_LINUX /* by default */
44#endif /* defined(LITES) && defined(EXT2_OS_LITES) */
45#endif /* defined(__FreeBSD__) && defined(EXT2_OS_FREEBSD) */
46#endif /* defined(__GNU__) && defined(EXT2_OS_HURD) */
47#endif /* defined(__linux__) && defined(EXT2_OS_LINUX) */
48
49/*
50 * Note we override the kernel include file's idea of what the default
51 * check interval (never) should be. It's a good idea to check at
52 * least *occasionally*, specially since servers will never rarely get
53 * to reboot, since Linux is so robust these days. :-)
54 *
55 * 180 days (six months) seems like a good value.
56 */
57#ifdef EXT2_DFL_CHECKINTERVAL
58#undef EXT2_DFL_CHECKINTERVAL
59#endif
60#define EXT2_DFL_CHECKINTERVAL (86400L * 180L)
61
62/*
63 * Calculate the number of GDT blocks to reserve for online filesystem growth.
64 * The absolute maximum number of GDT blocks we can reserve is determined by
65 * the number of block pointers that can fit into a single block.
66 */
67static int calc_reserved_gdt_blocks(ext2_filsys fs)
68{
69 struct ext2_super_block *sb = fs->super;
70 unsigned long bpg = sb->s_blocks_per_group;
71 unsigned int gdpb = fs->blocksize / sizeof(struct ext2_group_desc);
72 unsigned long max_blocks = 0xffffffff;
73 unsigned long rsv_groups;
74 int rsv_gdb;
75
76 /* We set it at 1024x the current filesystem size, or
77 * the upper block count limit (2^32), whichever is lower.
78 */
79 if (sb->s_blocks_count < max_blocks / 1024)
80 max_blocks = sb->s_blocks_count * 1024;
81 rsv_groups = (max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
82 rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - fs->desc_blocks;
83 if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
84 rsv_gdb = EXT2_ADDR_PER_BLOCK(sb);
85#ifdef RES_GDT_DEBUG
86 printf("max_blocks %lu, rsv_groups = %lu, rsv_gdb = %lu\n",
87 max_blocks, rsv_groups, rsv_gdb);
88#endif
89
90 return rsv_gdb;
91}
92
93errcode_t ext2fs_initialize(const char *name, int flags,
94 struct ext2_super_block *param,
95 io_manager manager, ext2_filsys *ret_fs)
96{
97 ext2_filsys fs;
98 errcode_t retval;
99 struct ext2_super_block *super;
100 int frags_per_block;
101 unsigned int rem;
102 unsigned int overhead = 0;
103 blk_t group_block;
104 unsigned int ipg;
105 dgrp_t i;
106 blk_t numblocks;
107 int rsv_gdt;
108 char *buf;
109
110 if (!param || !param->s_blocks_count)
111 return EXT2_ET_INVALID_ARGUMENT;
112
113 retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
114 if (retval)
115 return retval;
116
117 memset(fs, 0, sizeof(struct struct_ext2_filsys));
118 fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
119 fs->flags = flags | EXT2_FLAG_RW;
120 fs->umask = 022;
121#ifdef WORDS_BIGENDIAN
122 fs->flags |= EXT2_FLAG_SWAP_BYTES;
123#endif
124 retval = manager->open(name, IO_FLAG_RW, &fs->io);
125 if (retval)
126 goto cleanup;
127 fs->image_io = fs->io;
128 fs->io->app_data = fs;
129 retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
130 if (retval)
131 goto cleanup;
132
133 strcpy(fs->device_name, name);
134 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super);
135 if (retval)
136 goto cleanup;
137 fs->super = super;
138
139 memset(super, 0, SUPERBLOCK_SIZE);
140
141#define set_field(field, default) (super->field = param->field ? \
142 param->field : (default))
143
144 super->s_magic = EXT2_SUPER_MAGIC;
145 super->s_state = EXT2_VALID_FS;
146
147 set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */
148 set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
149 set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
150 set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
151 set_field(s_errors, EXT2_ERRORS_DEFAULT);
152 set_field(s_feature_compat, 0);
153 set_field(s_feature_incompat, 0);
154 set_field(s_feature_ro_compat, 0);
155 set_field(s_first_meta_bg, 0);
156 if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
157 retval = EXT2_ET_UNSUPP_FEATURE;
158 goto cleanup;
159 }
160 if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
161 retval = EXT2_ET_RO_UNSUPP_FEATURE;
162 goto cleanup;
163 }
164
165 set_field(s_rev_level, EXT2_GOOD_OLD_REV);
166 if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
167 set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
168 set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
169 }
170
171 set_field(s_checkinterval, EXT2_DFL_CHECKINTERVAL);
172 super->s_mkfs_time = super->s_lastcheck = time(NULL);
173
174 super->s_creator_os = CREATOR_OS;
175
176 fs->blocksize = EXT2_BLOCK_SIZE(super);
177 fs->fragsize = EXT2_FRAG_SIZE(super);
178 frags_per_block = fs->blocksize / fs->fragsize;
179
180 /* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
181 set_field(s_blocks_per_group, fs->blocksize * 8);
182 if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
183 super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
184 super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
185
186 super->s_blocks_count = param->s_blocks_count;
187 super->s_r_blocks_count = param->s_r_blocks_count;
188 if (super->s_r_blocks_count >= param->s_blocks_count) {
189 retval = EXT2_ET_INVALID_ARGUMENT;
190 goto cleanup;
191 }
192
193 /*
194 * If we're creating an external journal device, we don't need
195 * to bother with the rest.
196 */
197 if (super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
198 fs->group_desc_count = 0;
199 ext2fs_mark_super_dirty(fs);
200 *ret_fs = fs;
201 return 0;
202 }
203
204retry:
205 fs->group_desc_count = (super->s_blocks_count -
206 super->s_first_data_block +
207 EXT2_BLOCKS_PER_GROUP(super) - 1)
208 / EXT2_BLOCKS_PER_GROUP(super);
209 if (fs->group_desc_count == 0) {
210 retval = EXT2_ET_TOOSMALL;
211 goto cleanup;
212 }
213 fs->desc_blocks = (fs->group_desc_count +
214 EXT2_DESC_PER_BLOCK(super) - 1)
215 / EXT2_DESC_PER_BLOCK(super);
216
217 i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
218 set_field(s_inodes_count, super->s_blocks_count / i);
219
220 /*
221 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
222 * that we have enough inodes for the filesystem(!)
223 */
224 if (super->s_inodes_count < EXT2_FIRST_INODE(super)+1)
225 super->s_inodes_count = EXT2_FIRST_INODE(super)+1;
226
227 /*
228 * There should be at least as many inodes as the user
229 * requested. Figure out how many inodes per group that
230 * should be. But make sure that we don't allocate more than
231 * one bitmap's worth of inodes each group.
232 */
233 ipg = (super->s_inodes_count + fs->group_desc_count - 1) /
234 fs->group_desc_count;
235 if (ipg > fs->blocksize * 8) {
236 if (super->s_blocks_per_group >= 256) {
237 /* Try again with slightly different parameters */
238 super->s_blocks_per_group -= 8;
239 super->s_blocks_count = param->s_blocks_count;
240 super->s_frags_per_group = super->s_blocks_per_group *
241 frags_per_block;
242 goto retry;
243 } else
244 return EXT2_ET_TOO_MANY_INODES;
245 }
246
247 if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
248 ipg = EXT2_MAX_INODES_PER_GROUP(super);
249
250 super->s_inodes_per_group = ipg;
251 if (super->s_inodes_count > ipg * fs->group_desc_count)
252 super->s_inodes_count = ipg * fs->group_desc_count;
253
254 /*
255 * Make sure the number of inodes per group completely fills
256 * the inode table blocks in the descriptor. If not, add some
257 * additional inodes/group. Waste not, want not...
258 */
259 fs->inode_blocks_per_group = (((super->s_inodes_per_group *
260 EXT2_INODE_SIZE(super)) +
261 EXT2_BLOCK_SIZE(super) - 1) /
262 EXT2_BLOCK_SIZE(super));
263 super->s_inodes_per_group = ((fs->inode_blocks_per_group *
264 EXT2_BLOCK_SIZE(super)) /
265 EXT2_INODE_SIZE(super));
266 /*
267 * Finally, make sure the number of inodes per group is a
268 * multiple of 8. This is needed to simplify the bitmap
269 * splicing code.
270 */
271 super->s_inodes_per_group &= ~7;
272 fs->inode_blocks_per_group = (((super->s_inodes_per_group *
273 EXT2_INODE_SIZE(super)) +
274 EXT2_BLOCK_SIZE(super) - 1) /
275 EXT2_BLOCK_SIZE(super));
276
277 /*
278 * adjust inode count to reflect the adjusted inodes_per_group
279 */
280 super->s_inodes_count = super->s_inodes_per_group *
281 fs->group_desc_count;
282 super->s_free_inodes_count = super->s_inodes_count;
283
284 /*
285 * check the number of reserved group descriptor table blocks
286 */
287 if (super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE)
288 rsv_gdt = calc_reserved_gdt_blocks(fs);
289 else
290 rsv_gdt = 0;
291 set_field(s_reserved_gdt_blocks, rsv_gdt);
292 if (super->s_reserved_gdt_blocks > EXT2_ADDR_PER_BLOCK(super)) {
293 retval = EXT2_ET_RES_GDT_BLOCKS;
294 goto cleanup;
295 }
296
297 /*
298 * Overhead is the number of bookkeeping blocks per group. It
299 * includes the superblock backup, the group descriptor
300 * backups, the inode bitmap, the block bitmap, and the inode
301 * table.
302 */
303
304 overhead = (int) (2 + fs->inode_blocks_per_group);
305
306 if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
307 overhead += 1 + fs->desc_blocks + super->s_reserved_gdt_blocks;
308
309 /* This can only happen if the user requested too many inodes */
310 if (overhead > super->s_blocks_per_group)
311 return EXT2_ET_TOO_MANY_INODES;
312
313 /*
314 * See if the last group is big enough to support the
315 * necessary data structures. If not, we need to get rid of
316 * it.
317 */
318 rem = ((super->s_blocks_count - super->s_first_data_block) %
319 super->s_blocks_per_group);
320 if ((fs->group_desc_count == 1) && rem && (rem < overhead))
321 return EXT2_ET_TOOSMALL;
322 if (rem && (rem < overhead+50)) {
323 super->s_blocks_count -= rem;
324 goto retry;
325 }
326
327 /*
328 * At this point we know how big the filesystem will be. So
329 * we can do any and all allocations that depend on the block
330 * count.
331 */
332
333 retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
334 if (retval)
335 goto cleanup;
336
337 sprintf(buf, "block bitmap for %s", fs->device_name);
338 retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
339 if (retval)
340 goto cleanup;
341
342 sprintf(buf, "inode bitmap for %s", fs->device_name);
343 retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
344 if (retval)
345 goto cleanup;
346
347 ext2fs_free_mem(&buf);
348
349 retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
350 &fs->group_desc);
351 if (retval)
352 goto cleanup;
353
354 memset(fs->group_desc, 0, (size_t) fs->desc_blocks * fs->blocksize);
355
356 /*
357 * Reserve the superblock and group descriptors for each
358 * group, and fill in the correct group statistics for group.
359 * Note that although the block bitmap, inode bitmap, and
360 * inode table have not been allocated (and in fact won't be
361 * by this routine), they are accounted for nevertheless.
362 */
363 group_block = super->s_first_data_block;
364 super->s_free_blocks_count = 0;
365 for (i = 0; i < fs->group_desc_count; i++) {
366 numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
367
368 super->s_free_blocks_count += numblocks;
369 fs->group_desc[i].bg_free_blocks_count = numblocks;
370 fs->group_desc[i].bg_free_inodes_count =
371 fs->super->s_inodes_per_group;
372 fs->group_desc[i].bg_used_dirs_count = 0;
373
374 group_block += super->s_blocks_per_group;
375 }
376
377 ext2fs_mark_super_dirty(fs);
378 ext2fs_mark_bb_dirty(fs);
379 ext2fs_mark_ib_dirty(fs);
380
381 io_channel_set_blksize(fs->io, fs->blocksize);
382
383 *ret_fs = fs;
384 return 0;
385cleanup:
386 ext2fs_free(fs);
387 return retval;
388}
diff --git a/e2fsprogs/ext2fs/inline.c b/e2fsprogs/ext2fs/inline.c
deleted file mode 100644
index 9b620a772..000000000
--- a/e2fsprogs/ext2fs/inline.c
+++ /dev/null
@@ -1,33 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * inline.c --- Includes the inlined functions defined in the header
4 * files as standalone functions, in case the application program
5 * is compiled with inlining turned off.
6 *
7 * Copyright (C) 1993, 1994 Theodore Ts'o.
8 *
9 * %Begin-Header%
10 * This file may be redistributed under the terms of the GNU Public
11 * License.
12 * %End-Header%
13 */
14
15
16#include <stdio.h>
17#include <string.h>
18#if HAVE_UNISTD_H
19#include <unistd.h>
20#endif
21#include <fcntl.h>
22#include <time.h>
23#if HAVE_SYS_STAT_H
24#include <sys/stat.h>
25#endif
26#if HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
29
30#include "ext2_fs.h"
31#define INCLUDE_INLINE_FUNCS
32#include "ext2fs.h"
33
diff --git a/e2fsprogs/ext2fs/inode.c b/e2fsprogs/ext2fs/inode.c
deleted file mode 100644
index 2ff9fe6ca..000000000
--- a/e2fsprogs/ext2fs/inode.c
+++ /dev/null
@@ -1,768 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * inode.c --- utility routines to read and write inodes
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#if HAVE_ERRNO_H
19#include <errno.h>
20#endif
21#if HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#if HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27
28#include "ext2_fs.h"
29#include "ext2fsP.h"
30#include "e2image.h"
31
32struct ext2_struct_inode_scan {
33 errcode_t magic;
34 ext2_filsys fs;
35 ext2_ino_t current_inode;
36 blk_t current_block;
37 dgrp_t current_group;
38 ext2_ino_t inodes_left;
39 blk_t blocks_left;
40 dgrp_t groups_left;
41 blk_t inode_buffer_blocks;
42 char * inode_buffer;
43 int inode_size;
44 char * ptr;
45 int bytes_left;
46 char *temp_buffer;
47 errcode_t (*done_group)(ext2_filsys fs,
48 dgrp_t group,
49 void * priv_data);
50 void * done_group_data;
51 int bad_block_ptr;
52 int scan_flags;
53 int reserved[6];
54};
55
56/*
57 * This routine flushes the icache, if it exists.
58 */
59errcode_t ext2fs_flush_icache(ext2_filsys fs)
60{
61 int i;
62
63 if (!fs->icache)
64 return 0;
65
66 for (i=0; i < fs->icache->cache_size; i++)
67 fs->icache->cache[i].ino = 0;
68
69 fs->icache->buffer_blk = 0;
70 return 0;
71}
72
73static errcode_t create_icache(ext2_filsys fs)
74{
75 errcode_t retval;
76
77 if (fs->icache)
78 return 0;
79 retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache);
80 if (retval)
81 return retval;
82
83 memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
84 retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer);
85 if (retval) {
86 ext2fs_free_mem(&fs->icache);
87 return retval;
88 }
89 fs->icache->buffer_blk = 0;
90 fs->icache->cache_last = -1;
91 fs->icache->cache_size = 4;
92 fs->icache->refcount = 1;
93 retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
94 * fs->icache->cache_size,
95 &fs->icache->cache);
96 if (retval) {
97 ext2fs_free_mem(&fs->icache->buffer);
98 ext2fs_free_mem(&fs->icache);
99 return retval;
100 }
101 ext2fs_flush_icache(fs);
102 return 0;
103}
104
105errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
106 ext2_inode_scan *ret_scan)
107{
108 ext2_inode_scan scan;
109 errcode_t retval;
110 errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks);
111
112 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
113
114 /*
115 * If fs->badblocks isn't set, then set it --- since the inode
116 * scanning functions require it.
117 */
118 if (fs->badblocks == 0) {
119 /*
120 * Temporarly save fs->get_blocks and set it to zero,
121 * for compatibility with old e2fsck's.
122 */
123 save_get_blocks = fs->get_blocks;
124 fs->get_blocks = 0;
125 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
126 if (retval) {
127 ext2fs_badblocks_list_free(fs->badblocks);
128 fs->badblocks = 0;
129 }
130 fs->get_blocks = save_get_blocks;
131 }
132
133 retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan), &scan);
134 if (retval)
135 return retval;
136 memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
137
138 scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
139 scan->fs = fs;
140 scan->inode_size = EXT2_INODE_SIZE(fs->super);
141 scan->bytes_left = 0;
142 scan->current_group = 0;
143 scan->groups_left = fs->group_desc_count - 1;
144 scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
145 scan->current_block = scan->fs->
146 group_desc[scan->current_group].bg_inode_table;
147 scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
148 scan->blocks_left = scan->fs->inode_blocks_per_group;
149 retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks *
150 fs->blocksize),
151 &scan->inode_buffer);
152 scan->done_group = 0;
153 scan->done_group_data = 0;
154 scan->bad_block_ptr = 0;
155 if (retval) {
156 ext2fs_free_mem(&scan);
157 return retval;
158 }
159 retval = ext2fs_get_mem(scan->inode_size, &scan->temp_buffer);
160 if (retval) {
161 ext2fs_free_mem(&scan->inode_buffer);
162 ext2fs_free_mem(&scan);
163 return retval;
164 }
165 if (scan->fs->badblocks && scan->fs->badblocks->num)
166 scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
167 *ret_scan = scan;
168 return 0;
169}
170
171void ext2fs_close_inode_scan(ext2_inode_scan scan)
172{
173 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
174 return;
175
176 ext2fs_free_mem(&scan->inode_buffer);
177 scan->inode_buffer = NULL;
178 ext2fs_free_mem(&scan->temp_buffer);
179 scan->temp_buffer = NULL;
180 ext2fs_free_mem(&scan);
181 return;
182}
183
184void ext2fs_set_inode_callback(ext2_inode_scan scan,
185 errcode_t (*done_group)(ext2_filsys fs,
186 dgrp_t group,
187 void * priv_data),
188 void *done_group_data)
189{
190 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
191 return;
192
193 scan->done_group = done_group;
194 scan->done_group_data = done_group_data;
195}
196
197int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
198 int clear_flags)
199{
200 int old_flags;
201
202 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
203 return 0;
204
205 old_flags = scan->scan_flags;
206 scan->scan_flags &= ~clear_flags;
207 scan->scan_flags |= set_flags;
208 return old_flags;
209}
210
211/*
212 * This function is called by ext2fs_get_next_inode when it needs to
213 * get ready to read in a new blockgroup.
214 */
215static errcode_t get_next_blockgroup(ext2_inode_scan scan)
216{
217 scan->current_group++;
218 scan->groups_left--;
219
220 scan->current_block = scan->fs->
221 group_desc[scan->current_group].bg_inode_table;
222
223 scan->current_inode = scan->current_group *
224 EXT2_INODES_PER_GROUP(scan->fs->super);
225
226 scan->bytes_left = 0;
227 scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
228 scan->blocks_left = scan->fs->inode_blocks_per_group;
229 return 0;
230}
231
232errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
233 int group)
234{
235 scan->current_group = group - 1;
236 scan->groups_left = scan->fs->group_desc_count - group;
237 return get_next_blockgroup(scan);
238}
239
240/*
241 * This function is called by get_next_blocks() to check for bad
242 * blocks in the inode table.
243 *
244 * This function assumes that badblocks_list->list is sorted in
245 * increasing order.
246 */
247static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
248 blk_t *num_blocks)
249{
250 blk_t blk = scan->current_block;
251 badblocks_list bb = scan->fs->badblocks;
252
253 /*
254 * If the inode table is missing, then obviously there are no
255 * bad blocks. :-)
256 */
257 if (blk == 0)
258 return 0;
259
260 /*
261 * If the current block is greater than the bad block listed
262 * in the bad block list, then advance the pointer until this
263 * is no longer the case. If we run out of bad blocks, then
264 * we don't need to do any more checking!
265 */
266 while (blk > bb->list[scan->bad_block_ptr]) {
267 if (++scan->bad_block_ptr >= bb->num) {
268 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
269 return 0;
270 }
271 }
272
273 /*
274 * If the current block is equal to the bad block listed in
275 * the bad block list, then handle that one block specially.
276 * (We could try to handle runs of bad blocks, but that
277 * only increases CPU efficiency by a small amount, at the
278 * expense of a huge expense of code complexity, and for an
279 * uncommon case at that.)
280 */
281 if (blk == bb->list[scan->bad_block_ptr]) {
282 scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
283 *num_blocks = 1;
284 if (++scan->bad_block_ptr >= bb->num)
285 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
286 return 0;
287 }
288
289 /*
290 * If there is a bad block in the range that we're about to
291 * read in, adjust the number of blocks to read so that we we
292 * don't read in the bad block. (Then the next block to read
293 * will be the bad block, which is handled in the above case.)
294 */
295 if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
296 *num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
297
298 return 0;
299}
300
301/*
302 * This function is called by ext2fs_get_next_inode when it needs to
303 * read in more blocks from the current blockgroup's inode table.
304 */
305static errcode_t get_next_blocks(ext2_inode_scan scan)
306{
307 blk_t num_blocks;
308 errcode_t retval;
309
310 /*
311 * Figure out how many blocks to read; we read at most
312 * inode_buffer_blocks, and perhaps less if there aren't that
313 * many blocks left to read.
314 */
315 num_blocks = scan->inode_buffer_blocks;
316 if (num_blocks > scan->blocks_left)
317 num_blocks = scan->blocks_left;
318
319 /*
320 * If the past block "read" was a bad block, then mark the
321 * left-over extra bytes as also being bad.
322 */
323 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
324 if (scan->bytes_left)
325 scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
326 scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
327 }
328
329 /*
330 * Do inode bad block processing, if necessary.
331 */
332 if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
333 retval = check_for_inode_bad_blocks(scan, &num_blocks);
334 if (retval)
335 return retval;
336 }
337
338 if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
339 (scan->current_block == 0)) {
340 memset(scan->inode_buffer, 0,
341 (size_t) num_blocks * scan->fs->blocksize);
342 } else {
343 retval = io_channel_read_blk(scan->fs->io,
344 scan->current_block,
345 (int) num_blocks,
346 scan->inode_buffer);
347 if (retval)
348 return EXT2_ET_NEXT_INODE_READ;
349 }
350 scan->ptr = scan->inode_buffer;
351 scan->bytes_left = num_blocks * scan->fs->blocksize;
352
353 scan->blocks_left -= num_blocks;
354 if (scan->current_block)
355 scan->current_block += num_blocks;
356 return 0;
357}
358
359errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino,
360 struct ext2_inode *inode, int bufsize)
361{
362 errcode_t retval;
363 int extra_bytes = 0;
364
365 EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
366
367 /*
368 * Do we need to start reading a new block group?
369 */
370 if (scan->inodes_left <= 0) {
371 force_new_group:
372 if (scan->done_group) {
373 retval = (scan->done_group)
374 (scan->fs, scan->current_group,
375 scan->done_group_data);
376 if (retval)
377 return retval;
378 }
379 if (scan->groups_left <= 0) {
380 *ino = 0;
381 return 0;
382 }
383 retval = get_next_blockgroup(scan);
384 if (retval)
385 return retval;
386 }
387 /*
388 * This is done outside the above if statement so that the
389 * check can be done for block group #0.
390 */
391 if (scan->current_block == 0) {
392 if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
393 goto force_new_group;
394 } else
395 return EXT2_ET_MISSING_INODE_TABLE;
396 }
397
398
399 /*
400 * Have we run out of space in the inode buffer? If so, we
401 * need to read in more blocks.
402 */
403 if (scan->bytes_left < scan->inode_size) {
404 memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
405 extra_bytes = scan->bytes_left;
406
407 retval = get_next_blocks(scan);
408 if (retval)
409 return retval;
410#if 0
411 /*
412 * XXX test Need check for used inode somehow.
413 * (Note: this is hard.)
414 */
415 if (is_empty_scan(scan))
416 goto force_new_group;
417#endif
418 }
419
420 retval = 0;
421 if (extra_bytes) {
422 memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
423 scan->inode_size - extra_bytes);
424 scan->ptr += scan->inode_size - extra_bytes;
425 scan->bytes_left -= scan->inode_size - extra_bytes;
426
427#if BB_BIG_ENDIAN
428 if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
429 (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
430 ext2fs_swap_inode_full(scan->fs,
431 (struct ext2_inode_large *) inode,
432 (struct ext2_inode_large *) scan->temp_buffer,
433 0, bufsize);
434 else
435#endif
436 *inode = *((struct ext2_inode *) scan->temp_buffer);
437 if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
438 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
439 scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
440 } else {
441#if BB_BIG_ENDIAN
442 if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
443 (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
444 ext2fs_swap_inode_full(scan->fs,
445 (struct ext2_inode_large *) inode,
446 (struct ext2_inode_large *) scan->ptr,
447 0, bufsize);
448 else
449#endif
450 memcpy(inode, scan->ptr, bufsize);
451 scan->ptr += scan->inode_size;
452 scan->bytes_left -= scan->inode_size;
453 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
454 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
455 }
456
457 scan->inodes_left--;
458 scan->current_inode++;
459 *ino = scan->current_inode;
460 return retval;
461}
462
463errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
464 struct ext2_inode *inode)
465{
466 return ext2fs_get_next_inode_full(scan, ino, inode,
467 sizeof(struct ext2_inode));
468}
469
470/*
471 * Functions to read and write a single inode.
472 */
473errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
474 struct ext2_inode * inode, int bufsize)
475{
476 unsigned long group, block, block_nr, offset;
477 char *ptr;
478 errcode_t retval;
479 int clen, i, inodes_per_block, length;
480 io_channel io;
481
482 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
483
484 /* Check to see if user has an override function */
485 if (fs->read_inode) {
486 retval = (fs->read_inode)(fs, ino, inode);
487 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
488 return retval;
489 }
490 /* Create inode cache if not present */
491 if (!fs->icache) {
492 retval = create_icache(fs);
493 if (retval)
494 return retval;
495 }
496 /* Check to see if it's in the inode cache */
497 if (bufsize == sizeof(struct ext2_inode)) {
498 /* only old good inode can be retrieve from the cache */
499 for (i=0; i < fs->icache->cache_size; i++) {
500 if (fs->icache->cache[i].ino == ino) {
501 *inode = fs->icache->cache[i].inode;
502 return 0;
503 }
504 }
505 }
506 if ((ino == 0) || (ino > fs->super->s_inodes_count))
507 return EXT2_ET_BAD_INODE_NUM;
508 if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
509 inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
510 block_nr = fs->image_header->offset_inode / fs->blocksize;
511 block_nr += (ino - 1) / inodes_per_block;
512 offset = ((ino - 1) % inodes_per_block) *
513 EXT2_INODE_SIZE(fs->super);
514 io = fs->image_io;
515 } else {
516 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
517 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
518 EXT2_INODE_SIZE(fs->super);
519 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
520 if (!fs->group_desc[(unsigned)group].bg_inode_table)
521 return EXT2_ET_MISSING_INODE_TABLE;
522 block_nr = fs->group_desc[(unsigned)group].bg_inode_table +
523 block;
524 io = fs->io;
525 }
526 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
527
528 length = EXT2_INODE_SIZE(fs->super);
529 if (bufsize < length)
530 length = bufsize;
531
532 ptr = (char *) inode;
533 while (length) {
534 clen = length;
535 if ((offset + length) > fs->blocksize)
536 clen = fs->blocksize - offset;
537
538 if (block_nr != fs->icache->buffer_blk) {
539 retval = io_channel_read_blk(io, block_nr, 1,
540 fs->icache->buffer);
541 if (retval)
542 return retval;
543 fs->icache->buffer_blk = block_nr;
544 }
545
546 memcpy(ptr, ((char *) fs->icache->buffer) + (unsigned) offset,
547 clen);
548
549 offset = 0;
550 length -= clen;
551 ptr += clen;
552 block_nr++;
553 }
554
555#if BB_BIG_ENDIAN
556 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
557 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
558 ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) inode,
559 (struct ext2_inode_large *) inode,
560 0, length);
561#endif
562
563 /* Update the inode cache */
564 fs->icache->cache_last = (fs->icache->cache_last + 1) %
565 fs->icache->cache_size;
566 fs->icache->cache[fs->icache->cache_last].ino = ino;
567 fs->icache->cache[fs->icache->cache_last].inode = *inode;
568
569 return 0;
570}
571
572errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
573 struct ext2_inode * inode)
574{
575 return ext2fs_read_inode_full(fs, ino, inode,
576 sizeof(struct ext2_inode));
577}
578
579errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
580 struct ext2_inode * inode, int bufsize)
581{
582 unsigned long group, block, block_nr, offset;
583 errcode_t retval = 0;
584 struct ext2_inode_large temp_inode, *w_inode;
585 char *ptr;
586 int clen, i, length;
587
588 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
589
590 /* Check to see if user provided an override function */
591 if (fs->write_inode) {
592 retval = (fs->write_inode)(fs, ino, inode);
593 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
594 return retval;
595 }
596
597 /* Check to see if the inode cache needs to be updated */
598 if (fs->icache) {
599 for (i=0; i < fs->icache->cache_size; i++) {
600 if (fs->icache->cache[i].ino == ino) {
601 fs->icache->cache[i].inode = *inode;
602 break;
603 }
604 }
605 } else {
606 retval = create_icache(fs);
607 if (retval)
608 return retval;
609 }
610
611 if (!(fs->flags & EXT2_FLAG_RW))
612 return EXT2_ET_RO_FILSYS;
613
614 if ((ino == 0) || (ino > fs->super->s_inodes_count))
615 return EXT2_ET_BAD_INODE_NUM;
616
617 length = bufsize;
618 if (length < EXT2_INODE_SIZE(fs->super))
619 length = EXT2_INODE_SIZE(fs->super);
620
621 if (length > (int) sizeof(struct ext2_inode_large)) {
622 w_inode = xmalloc(length);
623 } else
624 w_inode = &temp_inode;
625 memset(w_inode, 0, length);
626
627#if BB_BIG_ENDIAN
628 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
629 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
630 ext2fs_swap_inode_full(fs, w_inode,
631 (struct ext2_inode_large *) inode,
632 1, bufsize);
633 else
634#endif
635 memcpy(w_inode, inode, bufsize);
636
637 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
638 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
639 EXT2_INODE_SIZE(fs->super);
640 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
641 if (!fs->group_desc[(unsigned) group].bg_inode_table)
642 return EXT2_ET_MISSING_INODE_TABLE;
643 block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
644
645 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
646
647 length = EXT2_INODE_SIZE(fs->super);
648 if (length > bufsize)
649 length = bufsize;
650
651 ptr = (char *) w_inode;
652
653 while (length) {
654 clen = length;
655 if ((offset + length) > fs->blocksize)
656 clen = fs->blocksize - offset;
657
658 if (fs->icache->buffer_blk != block_nr) {
659 retval = io_channel_read_blk(fs->io, block_nr, 1,
660 fs->icache->buffer);
661 if (retval)
662 goto errout;
663 fs->icache->buffer_blk = block_nr;
664 }
665
666
667 memcpy((char *) fs->icache->buffer + (unsigned) offset,
668 ptr, clen);
669
670 retval = io_channel_write_blk(fs->io, block_nr, 1,
671 fs->icache->buffer);
672 if (retval)
673 goto errout;
674
675 offset = 0;
676 ptr += clen;
677 length -= clen;
678 block_nr++;
679 }
680
681 fs->flags |= EXT2_FLAG_CHANGED;
682errout:
683 if (w_inode && w_inode != &temp_inode)
684 free(w_inode);
685 return retval;
686}
687
688errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
689 struct ext2_inode *inode)
690{
691 return ext2fs_write_inode_full(fs, ino, inode,
692 sizeof(struct ext2_inode));
693}
694
695/*
696 * This function should be called when writing a new inode. It makes
697 * sure that extra part of large inodes is initialized properly.
698 */
699errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
700 struct ext2_inode *inode)
701{
702 struct ext2_inode *buf;
703 int size = EXT2_INODE_SIZE(fs->super);
704 struct ext2_inode_large *large_inode;
705
706 if (size == sizeof(struct ext2_inode))
707 return ext2fs_write_inode_full(fs, ino, inode,
708 sizeof(struct ext2_inode));
709
710 buf = xmalloc(size);
711
712 memset(buf, 0, size);
713 *buf = *inode;
714
715 large_inode = (struct ext2_inode_large *) buf;
716 large_inode->i_extra_isize = sizeof(struct ext2_inode_large) -
717 EXT2_GOOD_OLD_INODE_SIZE;
718
719 return ext2fs_write_inode_full(fs, ino, buf, size);
720}
721
722
723errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
724{
725 struct ext2_inode inode;
726 int i;
727 errcode_t retval;
728
729 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
730
731 if (ino > fs->super->s_inodes_count)
732 return EXT2_ET_BAD_INODE_NUM;
733
734 if (fs->get_blocks) {
735 if (!(*fs->get_blocks)(fs, ino, blocks))
736 return 0;
737 }
738 retval = ext2fs_read_inode(fs, ino, &inode);
739 if (retval)
740 return retval;
741 for (i=0; i < EXT2_N_BLOCKS; i++)
742 blocks[i] = inode.i_block[i];
743 return 0;
744}
745
746errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
747{
748 struct ext2_inode inode;
749 errcode_t retval;
750
751 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
752
753 if (ino > fs->super->s_inodes_count)
754 return EXT2_ET_BAD_INODE_NUM;
755
756 if (fs->check_directory) {
757 retval = (fs->check_directory)(fs, ino);
758 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
759 return retval;
760 }
761 retval = ext2fs_read_inode(fs, ino, &inode);
762 if (retval)
763 return retval;
764 if (!LINUX_S_ISDIR(inode.i_mode))
765 return EXT2_ET_NO_DIRECTORY;
766 return 0;
767}
768
diff --git a/e2fsprogs/ext2fs/inode_io.c b/e2fsprogs/ext2fs/inode_io.c
deleted file mode 100644
index 4bfa93aef..000000000
--- a/e2fsprogs/ext2fs/inode_io.c
+++ /dev/null
@@ -1,271 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * inode_io.c --- This is allows an inode in an ext2 filesystem image
4 * to be accessed via the I/O manager interface.
5 *
6 * Copyright (C) 2002 Theodore Ts'o.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#if HAVE_ERRNO_H
20#include <errno.h>
21#endif
22#include <time.h>
23
24#include "ext2_fs.h"
25#include "ext2fs.h"
26
27/*
28 * For checking structure magic numbers...
29 */
30
31#define EXT2_CHECK_MAGIC(struct, code) \
32 if ((struct)->magic != (code)) return (code)
33
34struct inode_private_data {
35 int magic;
36 char name[32];
37 ext2_file_t file;
38 ext2_filsys fs;
39 ext2_ino_t ino;
40 struct ext2_inode inode;
41 int flags;
42 struct inode_private_data *next;
43};
44
45#define CHANNEL_HAS_INODE 0x8000
46
47static struct inode_private_data *top_intern;
48static int ino_unique = 0;
49
50static errcode_t inode_open(const char *name, int flags, io_channel *channel);
51static errcode_t inode_close(io_channel channel);
52static errcode_t inode_set_blksize(io_channel channel, int blksize);
53static errcode_t inode_read_blk(io_channel channel, unsigned long block,
54 int count, void *data);
55static errcode_t inode_write_blk(io_channel channel, unsigned long block,
56 int count, const void *data);
57static errcode_t inode_flush(io_channel channel);
58static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
59 int size, const void *data);
60
61static struct struct_io_manager struct_inode_manager = {
62 EXT2_ET_MAGIC_IO_MANAGER,
63 "Inode I/O Manager",
64 inode_open,
65 inode_close,
66 inode_set_blksize,
67 inode_read_blk,
68 inode_write_blk,
69 inode_flush,
70 inode_write_byte
71};
72
73io_manager inode_io_manager = &struct_inode_manager;
74
75errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
76 struct ext2_inode *inode,
77 char **name)
78{
79 struct inode_private_data *data;
80 errcode_t retval;
81
82 if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
83 &data)))
84 return retval;
85 data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
86 sprintf(data->name, "%u:%d", ino, ino_unique++);
87 data->file = 0;
88 data->fs = fs;
89 data->ino = ino;
90 data->flags = 0;
91 if (inode) {
92 memcpy(&data->inode, inode, sizeof(struct ext2_inode));
93 data->flags |= CHANNEL_HAS_INODE;
94 }
95 data->next = top_intern;
96 top_intern = data;
97 *name = data->name;
98 return 0;
99}
100
101errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
102 char **name)
103{
104 return ext2fs_inode_io_intern2(fs, ino, NULL, name);
105}
106
107
108static errcode_t inode_open(const char *name, int flags, io_channel *channel)
109{
110 io_channel io = NULL;
111 struct inode_private_data *prev, *data = NULL;
112 errcode_t retval;
113 int open_flags;
114
115 if (name == 0)
116 return EXT2_ET_BAD_DEVICE_NAME;
117
118 for (data = top_intern, prev = NULL; data;
119 prev = data, data = data->next)
120 if (strcmp(name, data->name) == 0)
121 break;
122 if (!data)
123 return ENOENT;
124 if (prev)
125 prev->next = data->next;
126 else
127 top_intern = data->next;
128
129 retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
130 if (retval)
131 goto cleanup;
132 memset(io, 0, sizeof(struct struct_io_channel));
133
134 io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
135 io->manager = inode_io_manager;
136 retval = ext2fs_get_mem(strlen(name)+1, &io->name);
137 if (retval)
138 goto cleanup;
139
140 strcpy(io->name, name);
141 io->private_data = data;
142 io->block_size = 1024;
143 io->read_error = 0;
144 io->write_error = 0;
145 io->refcount = 1;
146
147 open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
148 retval = ext2fs_file_open2(data->fs, data->ino,
149 (data->flags & CHANNEL_HAS_INODE) ?
150 &data->inode : 0, open_flags,
151 &data->file);
152 if (retval)
153 goto cleanup;
154
155 *channel = io;
156 return 0;
157
158cleanup:
159 if (data) {
160 ext2fs_free_mem(&data);
161 }
162 if (io)
163 ext2fs_free_mem(&io);
164 return retval;
165}
166
167static errcode_t inode_close(io_channel channel)
168{
169 struct inode_private_data *data;
170 errcode_t retval = 0;
171
172 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
173 data = (struct inode_private_data *) channel->private_data;
174 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
175
176 if (--channel->refcount > 0)
177 return 0;
178
179 retval = ext2fs_file_close(data->file);
180
181 ext2fs_free_mem(&channel->private_data);
182 if (channel->name)
183 ext2fs_free_mem(&channel->name);
184 ext2fs_free_mem(&channel);
185 return retval;
186}
187
188static errcode_t inode_set_blksize(io_channel channel, int blksize)
189{
190 struct inode_private_data *data;
191
192 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
193 data = (struct inode_private_data *) channel->private_data;
194 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
195
196 channel->block_size = blksize;
197 return 0;
198}
199
200
201static errcode_t inode_read_blk(io_channel channel, unsigned long block,
202 int count, void *buf)
203{
204 struct inode_private_data *data;
205 errcode_t retval;
206
207 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
208 data = (struct inode_private_data *) channel->private_data;
209 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
210
211 if ((retval = ext2fs_file_lseek(data->file,
212 block * channel->block_size,
213 EXT2_SEEK_SET, 0)))
214 return retval;
215
216 count = (count < 0) ? -count : (count * channel->block_size);
217
218 return ext2fs_file_read(data->file, buf, count, 0);
219}
220
221static errcode_t inode_write_blk(io_channel channel, unsigned long block,
222 int count, const void *buf)
223{
224 struct inode_private_data *data;
225 errcode_t retval;
226
227 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
228 data = (struct inode_private_data *) channel->private_data;
229 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
230
231 if ((retval = ext2fs_file_lseek(data->file,
232 block * channel->block_size,
233 EXT2_SEEK_SET, 0)))
234 return retval;
235
236 count = (count < 0) ? -count : (count * channel->block_size);
237
238 return ext2fs_file_write(data->file, buf, count, 0);
239}
240
241static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
242 int size, const void *buf)
243{
244 struct inode_private_data *data;
245 errcode_t retval = 0;
246
247 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
248 data = (struct inode_private_data *) channel->private_data;
249 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
250
251 if ((retval = ext2fs_file_lseek(data->file, offset,
252 EXT2_SEEK_SET, 0)))
253 return retval;
254
255 return ext2fs_file_write(data->file, buf, size, 0);
256}
257
258/*
259 * Flush data buffers to disk.
260 */
261static errcode_t inode_flush(io_channel channel)
262{
263 struct inode_private_data *data;
264
265 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
266 data = (struct inode_private_data *) channel->private_data;
267 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
268
269 return ext2fs_file_flush(data->file);
270}
271
diff --git a/e2fsprogs/ext2fs/io_manager.c b/e2fsprogs/ext2fs/io_manager.c
deleted file mode 100644
index b47038602..000000000
--- a/e2fsprogs/ext2fs/io_manager.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * io_manager.c --- the I/O manager abstraction
4 */
5
6#include <stdio.h>
7#include <string.h>
8#if HAVE_UNISTD_H
9#include <unistd.h>
10#endif
11#include <fcntl.h>
12#include <time.h>
13#if HAVE_SYS_STAT_H
14#include <sys/stat.h>
15#endif
16#if HAVE_SYS_TYPES_H
17#include <sys/types.h>
18#endif
19
20#include "ext2_fs.h"
21#include "ext2fs.h"
22
23errcode_t io_channel_set_options(io_channel channel, const char *opts)
24{
25 errcode_t retval = 0;
26 char *next, *ptr, *options, *arg;
27
28 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
29
30 if (!opts)
31 return 0;
32
33 if (!channel->manager->set_option)
34 return EXT2_ET_INVALID_ARGUMENT;
35
36 options = malloc(strlen(opts)+1);
37 if (!options)
38 return EXT2_ET_NO_MEMORY;
39 strcpy(options, opts);
40 ptr = options;
41
42 while (ptr && *ptr) {
43 next = strchr(ptr, '&');
44 if (next)
45 *next++ = 0;
46
47 arg = strchr(ptr, '=');
48 if (arg)
49 *arg++ = 0;
50
51 retval = (channel->manager->set_option)(channel, ptr, arg);
52 if (retval)
53 break;
54 ptr = next;
55 }
56 free(options);
57 return retval;
58}
59
60errcode_t io_channel_write_byte(io_channel channel, unsigned long offset,
61 int count, const void *data)
62{
63 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
64
65 if (channel->manager->write_byte)
66 return channel->manager->write_byte(channel, offset,
67 count, data);
68
69 return EXT2_ET_UNIMPLEMENTED;
70}
diff --git a/e2fsprogs/ext2fs/irel.h b/e2fsprogs/ext2fs/irel.h
deleted file mode 100644
index 91d1d89d5..000000000
--- a/e2fsprogs/ext2fs/irel.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * irel.h
4 *
5 * Copyright (C) 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13struct ext2_inode_reference {
14 blk_t block;
15 __u16 offset;
16};
17
18struct ext2_inode_relocate_entry {
19 ext2_ino_t new;
20 ext2_ino_t orig;
21 __u16 flags;
22 __u16 max_refs;
23};
24
25typedef struct ext2_inode_relocation_table *ext2_irel;
26
27struct ext2_inode_relocation_table {
28 __u32 magic;
29 char *name;
30 ext2_ino_t current;
31 void *priv_data;
32
33 /*
34 * Add an inode relocation entry.
35 */
36 errcode_t (*put)(ext2_irel irel, ext2_ino_t old,
37 struct ext2_inode_relocate_entry *ent);
38 /*
39 * Get an inode relocation entry.
40 */
41 errcode_t (*get)(ext2_irel irel, ext2_ino_t old,
42 struct ext2_inode_relocate_entry *ent);
43
44 /*
45 * Get an inode relocation entry by its original inode number
46 */
47 errcode_t (*get_by_orig)(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
48 struct ext2_inode_relocate_entry *ent);
49
50 /*
51 * Initialize for iterating over the inode relocation entries.
52 */
53 errcode_t (*start_iter)(ext2_irel irel);
54
55 /*
56 * The iterator function for the inode relocation entries.
57 * Returns an inode number of 0 when out of entries.
58 */
59 errcode_t (*next)(ext2_irel irel, ext2_ino_t *old,
60 struct ext2_inode_relocate_entry *ent);
61
62 /*
63 * Add an inode reference (i.e., note the fact that a
64 * particular block/offset contains a reference to an inode)
65 */
66 errcode_t (*add_ref)(ext2_irel irel, ext2_ino_t ino,
67 struct ext2_inode_reference *ref);
68
69 /*
70 * Initialize for iterating over the inode references for a
71 * particular inode.
72 */
73 errcode_t (*start_iter_ref)(ext2_irel irel, ext2_ino_t ino);
74
75 /*
76 * The iterator function for the inode references for an
77 * inode. The references for only one inode can be interator
78 * over at a time, as the iterator state is stored in ext2_irel.
79 */
80 errcode_t (*next_ref)(ext2_irel irel,
81 struct ext2_inode_reference *ref);
82
83 /*
84 * Move the inode relocation table from one inode number to
85 * another. Note that the inode references also must move.
86 */
87 errcode_t (*move)(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
88
89 /*
90 * Remove an inode relocation entry, along with all of the
91 * inode references.
92 */
93 errcode_t (*delete)(ext2_irel irel, ext2_ino_t old);
94
95 /*
96 * Free the inode relocation table.
97 */
98 errcode_t (*free)(ext2_irel irel);
99};
100
101errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
102 ext2_irel *irel);
103
104#define ext2fs_irel_put(irel, old, ent) ((irel)->put((irel), old, ent))
105#define ext2fs_irel_get(irel, old, ent) ((irel)->get((irel), old, ent))
106#define ext2fs_irel_get_by_orig(irel, orig, old, ent) \
107 ((irel)->get_by_orig((irel), orig, old, ent))
108#define ext2fs_irel_start_iter(irel) ((irel)->start_iter((irel)))
109#define ext2fs_irel_next(irel, old, ent) ((irel)->next((irel), old, ent))
110#define ext2fs_irel_add_ref(irel, ino, ref) ((irel)->add_ref((irel), ino, ref))
111#define ext2fs_irel_start_iter_ref(irel, ino) ((irel)->start_iter_ref((irel), ino))
112#define ext2fs_irel_next_ref(irel, ref) ((irel)->next_ref((irel), ref))
113#define ext2fs_irel_move(irel, old, new) ((irel)->move((irel), old, new))
114#define ext2fs_irel_delete(irel, old) ((irel)->delete((irel), old))
115#define ext2fs_irel_free(irel) ((irel)->free((irel)))
diff --git a/e2fsprogs/ext2fs/irel_ma.c b/e2fsprogs/ext2fs/irel_ma.c
deleted file mode 100644
index c871b1891..000000000
--- a/e2fsprogs/ext2fs/irel_ma.c
+++ /dev/null
@@ -1,367 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * irel_ma.c
4 *
5 * Copyright (C) 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <fcntl.h>
14#include <stdio.h>
15#include <string.h>
16#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#if HAVE_ERRNO_H
20#include <errno.h>
21#endif
22
23#include "ext2_fs.h"
24#include "ext2fs.h"
25#include "irel.h"
26
27static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
28 struct ext2_inode_relocate_entry *ent);
29static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
30 struct ext2_inode_relocate_entry *ent);
31static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
32 struct ext2_inode_relocate_entry *ent);
33static errcode_t ima_start_iter(ext2_irel irel);
34static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
35 struct ext2_inode_relocate_entry *ent);
36static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
37 struct ext2_inode_reference *ref);
38static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino);
39static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref);
40static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
41static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old);
42static errcode_t ima_free(ext2_irel irel);
43
44/*
45 * This data structure stores the array of inode references; there is
46 * a structure for each inode.
47 */
48struct inode_reference_entry {
49 __u16 num;
50 struct ext2_inode_reference *refs;
51};
52
53struct irel_ma {
54 __u32 magic;
55 ext2_ino_t max_inode;
56 ext2_ino_t ref_current;
57 int ref_iter;
58 ext2_ino_t *orig_map;
59 struct ext2_inode_relocate_entry *entries;
60 struct inode_reference_entry *ref_entries;
61};
62
63errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
64 ext2_irel *new_irel)
65{
66 ext2_irel irel = 0;
67 errcode_t retval;
68 struct irel_ma *ma = 0;
69 size_t size;
70
71 *new_irel = 0;
72
73 /*
74 * Allocate memory structures
75 */
76 retval = ext2fs_get_mem(sizeof(struct ext2_inode_relocation_table),
77 &irel);
78 if (retval)
79 goto errout;
80 memset(irel, 0, sizeof(struct ext2_inode_relocation_table));
81
82 retval = ext2fs_get_mem(strlen(name)+1, &irel->name);
83 if (retval)
84 goto errout;
85 strcpy(irel->name, name);
86
87 retval = ext2fs_get_mem(sizeof(struct irel_ma), &ma);
88 if (retval)
89 goto errout;
90 memset(ma, 0, sizeof(struct irel_ma));
91 irel->priv_data = ma;
92
93 size = (size_t) (sizeof(ext2_ino_t) * (max_inode+1));
94 retval = ext2fs_get_mem(size, &ma->orig_map);
95 if (retval)
96 goto errout;
97 memset(ma->orig_map, 0, size);
98
99 size = (size_t) (sizeof(struct ext2_inode_relocate_entry) *
100 (max_inode+1));
101 retval = ext2fs_get_mem(size, &ma->entries);
102 if (retval)
103 goto errout;
104 memset(ma->entries, 0, size);
105
106 size = (size_t) (sizeof(struct inode_reference_entry) *
107 (max_inode+1));
108 retval = ext2fs_get_mem(size, &ma->ref_entries);
109 if (retval)
110 goto errout;
111 memset(ma->ref_entries, 0, size);
112 ma->max_inode = max_inode;
113
114 /*
115 * Fill in the irel data structure
116 */
117 irel->put = ima_put;
118 irel->get = ima_get;
119 irel->get_by_orig = ima_get_by_orig;
120 irel->start_iter = ima_start_iter;
121 irel->next = ima_next;
122 irel->add_ref = ima_add_ref;
123 irel->start_iter_ref = ima_start_iter_ref;
124 irel->next_ref = ima_next_ref;
125 irel->move = ima_move;
126 irel->delete = ima_delete;
127 irel->free = ima_free;
128
129 *new_irel = irel;
130 return 0;
131
132errout:
133 ima_free(irel);
134 return retval;
135}
136
137static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
138 struct ext2_inode_relocate_entry *ent)
139{
140 struct inode_reference_entry *ref_ent;
141 struct irel_ma *ma;
142 errcode_t retval;
143 size_t size, old_size;
144
145 ma = irel->priv_data;
146 if (old > ma->max_inode)
147 return EXT2_ET_INVALID_ARGUMENT;
148
149 /*
150 * Force the orig field to the correct value; the application
151 * program shouldn't be messing with this field.
152 */
153 if (ma->entries[(unsigned) old].new == 0)
154 ent->orig = old;
155 else
156 ent->orig = ma->entries[(unsigned) old].orig;
157
158 /*
159 * If max_refs has changed, reallocate the refs array
160 */
161 ref_ent = ma->ref_entries + (unsigned) old;
162 if (ref_ent->refs && ent->max_refs !=
163 ma->entries[(unsigned) old].max_refs) {
164 size = (sizeof(struct ext2_inode_reference) * ent->max_refs);
165 old_size = (sizeof(struct ext2_inode_reference) *
166 ma->entries[(unsigned) old].max_refs);
167 retval = ext2fs_resize_mem(old_size, size, &ref_ent->refs);
168 if (retval)
169 return retval;
170 }
171
172 ma->entries[(unsigned) old] = *ent;
173 ma->orig_map[(unsigned) ent->orig] = old;
174 return 0;
175}
176
177static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
178 struct ext2_inode_relocate_entry *ent)
179{
180 struct irel_ma *ma;
181
182 ma = irel->priv_data;
183 if (old > ma->max_inode)
184 return EXT2_ET_INVALID_ARGUMENT;
185 if (ma->entries[(unsigned) old].new == 0)
186 return ENOENT;
187 *ent = ma->entries[(unsigned) old];
188 return 0;
189}
190
191static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
192 struct ext2_inode_relocate_entry *ent)
193{
194 struct irel_ma *ma;
195 ext2_ino_t ino;
196
197 ma = irel->priv_data;
198 if (orig > ma->max_inode)
199 return EXT2_ET_INVALID_ARGUMENT;
200 ino = ma->orig_map[(unsigned) orig];
201 if (ino == 0)
202 return ENOENT;
203 *old = ino;
204 *ent = ma->entries[(unsigned) ino];
205 return 0;
206}
207
208static errcode_t ima_start_iter(ext2_irel irel)
209{
210 irel->current = 0;
211 return 0;
212}
213
214static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
215 struct ext2_inode_relocate_entry *ent)
216{
217 struct irel_ma *ma;
218
219 ma = irel->priv_data;
220 while (++irel->current < ma->max_inode) {
221 if (ma->entries[(unsigned) irel->current].new == 0)
222 continue;
223 *old = irel->current;
224 *ent = ma->entries[(unsigned) irel->current];
225 return 0;
226 }
227 *old = 0;
228 return 0;
229}
230
231static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
232 struct ext2_inode_reference *ref)
233{
234 struct irel_ma *ma;
235 size_t size;
236 struct inode_reference_entry *ref_ent;
237 struct ext2_inode_relocate_entry *ent;
238 errcode_t retval;
239
240 ma = irel->priv_data;
241 if (ino > ma->max_inode)
242 return EXT2_ET_INVALID_ARGUMENT;
243
244 ref_ent = ma->ref_entries + (unsigned) ino;
245 ent = ma->entries + (unsigned) ino;
246
247 /*
248 * If the inode reference array doesn't exist, create it.
249 */
250 if (ref_ent->refs == 0) {
251 size = (size_t) ((sizeof(struct ext2_inode_reference) *
252 ent->max_refs));
253 retval = ext2fs_get_mem(size, &ref_ent->refs);
254 if (retval)
255 return retval;
256 memset(ref_ent->refs, 0, size);
257 ref_ent->num = 0;
258 }
259
260 if (ref_ent->num >= ent->max_refs)
261 return EXT2_ET_TOO_MANY_REFS;
262
263 ref_ent->refs[(unsigned) ref_ent->num++] = *ref;
264 return 0;
265}
266
267static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino)
268{
269 struct irel_ma *ma;
270
271 ma = irel->priv_data;
272 if (ino > ma->max_inode)
273 return EXT2_ET_INVALID_ARGUMENT;
274 if (ma->entries[(unsigned) ino].new == 0)
275 return ENOENT;
276 ma->ref_current = ino;
277 ma->ref_iter = 0;
278 return 0;
279}
280
281static errcode_t ima_next_ref(ext2_irel irel,
282 struct ext2_inode_reference *ref)
283{
284 struct irel_ma *ma;
285 struct inode_reference_entry *ref_ent;
286
287 ma = irel->priv_data;
288
289 ref_ent = ma->ref_entries + ma->ref_current;
290
291 if ((ref_ent->refs == NULL) ||
292 (ma->ref_iter >= ref_ent->num)) {
293 ref->block = 0;
294 ref->offset = 0;
295 return 0;
296 }
297 *ref = ref_ent->refs[ma->ref_iter++];
298 return 0;
299}
300
301
302static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new)
303{
304 struct irel_ma *ma;
305
306 ma = irel->priv_data;
307 if ((old > ma->max_inode) || (new > ma->max_inode))
308 return EXT2_ET_INVALID_ARGUMENT;
309 if (ma->entries[(unsigned) old].new == 0)
310 return ENOENT;
311
312 ma->entries[(unsigned) new] = ma->entries[(unsigned) old];
313 ext2fs_free_mem(&ma->ref_entries[(unsigned) new].refs);
314 ma->ref_entries[(unsigned) new] = ma->ref_entries[(unsigned) old];
315
316 ma->entries[(unsigned) old].new = 0;
317 ma->ref_entries[(unsigned) old].num = 0;
318 ma->ref_entries[(unsigned) old].refs = 0;
319
320 ma->orig_map[ma->entries[new].orig] = new;
321 return 0;
322}
323
324static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old)
325{
326 struct irel_ma *ma;
327
328 ma = irel->priv_data;
329 if (old > ma->max_inode)
330 return EXT2_ET_INVALID_ARGUMENT;
331 if (ma->entries[(unsigned) old].new == 0)
332 return ENOENT;
333
334 ma->entries[old].new = 0;
335 ext2fs_free_mem(&ma->ref_entries[(unsigned) old].refs);
336 ma->orig_map[ma->entries[(unsigned) old].orig] = 0;
337
338 ma->ref_entries[(unsigned) old].num = 0;
339 ma->ref_entries[(unsigned) old].refs = 0;
340 return 0;
341}
342
343static errcode_t ima_free(ext2_irel irel)
344{
345 struct irel_ma *ma;
346 ext2_ino_t ino;
347
348 if (!irel)
349 return 0;
350
351 ma = irel->priv_data;
352
353 if (ma) {
354 ext2fs_free_mem(&ma->orig_map);
355 ext2fs_free_mem(&ma->entries);
356 if (ma->ref_entries) {
357 for (ino = 0; ino <= ma->max_inode; ino++) {
358 ext2fs_free_mem(&ma->ref_entries[(unsigned) ino].refs);
359 }
360 ext2fs_free_mem(&ma->ref_entries);
361 }
362 ext2fs_free_mem(&ma);
363 }
364 ext2fs_free_mem(&irel->name);
365 ext2fs_free_mem(&irel);
366 return 0;
367}
diff --git a/e2fsprogs/ext2fs/ismounted.c b/e2fsprogs/ext2fs/ismounted.c
deleted file mode 100644
index d943f1185..000000000
--- a/e2fsprogs/ext2fs/ismounted.c
+++ /dev/null
@@ -1,357 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ismounted.c --- Check to see if the filesystem was mounted
4 *
5 * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17#if HAVE_ERRNO_H
18#include <errno.h>
19#endif
20#include <fcntl.h>
21#ifdef HAVE_LINUX_FD_H
22#include <linux/fd.h>
23#endif
24#ifdef HAVE_MNTENT_H
25#include <mntent.h>
26#endif
27#ifdef HAVE_GETMNTINFO
28#include <paths.h>
29#include <sys/param.h>
30#include <sys/mount.h>
31#endif /* HAVE_GETMNTINFO */
32#include <string.h>
33#include <sys/stat.h>
34
35#include "ext2_fs.h"
36#include "ext2fs.h"
37
38#ifdef HAVE_MNTENT_H
39/*
40 * Helper function which checks a file in /etc/mtab format to see if a
41 * filesystem is mounted. Returns an error if the file doesn't exist
42 * or can't be opened.
43 */
44static errcode_t check_mntent_file(const char *mtab_file, const char *file,
45 int *mount_flags, char *mtpt, int mtlen)
46{
47 struct mntent *mnt;
48 struct stat st_buf;
49 errcode_t retval = 0;
50 dev_t file_dev=0, file_rdev=0;
51 ino_t file_ino=0;
52 FILE *f;
53 int fd;
54
55 *mount_flags = 0;
56 if ((f = setmntent (mtab_file, "r")) == NULL)
57 return errno;
58 if (stat(file, &st_buf) == 0) {
59 if (S_ISBLK(st_buf.st_mode)) {
60#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
61 file_rdev = st_buf.st_rdev;
62#endif /* __GNU__ */
63 } else {
64 file_dev = st_buf.st_dev;
65 file_ino = st_buf.st_ino;
66 }
67 }
68 while ((mnt = getmntent (f)) != NULL) {
69 if (strcmp(file, mnt->mnt_fsname) == 0)
70 break;
71 if (stat(mnt->mnt_fsname, &st_buf) == 0) {
72 if (S_ISBLK(st_buf.st_mode)) {
73#ifndef __GNU__
74 if (file_rdev && (file_rdev == st_buf.st_rdev))
75 break;
76#endif /* __GNU__ */
77 } else {
78 if (file_dev && ((file_dev == st_buf.st_dev) &&
79 (file_ino == st_buf.st_ino)))
80 break;
81 }
82 }
83 }
84
85 if (mnt == 0) {
86#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
87 /*
88 * Do an extra check to see if this is the root device. We
89 * can't trust /etc/mtab, and /proc/mounts will only list
90 * /dev/root for the root filesystem. Argh. Instead we
91 * check if the given device has the same major/minor number
92 * as the device that the root directory is on.
93 */
94 if (file_rdev && stat("/", &st_buf) == 0) {
95 if (st_buf.st_dev == file_rdev) {
96 *mount_flags = EXT2_MF_MOUNTED;
97 if (mtpt)
98 strncpy(mtpt, "/", mtlen);
99 goto is_root;
100 }
101 }
102#endif /* __GNU__ */
103 goto errout;
104 }
105#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
106 /* Validate the entry in case /etc/mtab is out of date */
107 /*
108 * We need to be paranoid, because some broken distributions
109 * (read: Slackware) don't initialize /etc/mtab before checking
110 * all of the non-root filesystems on the disk.
111 */
112 if (stat(mnt->mnt_dir, &st_buf) < 0) {
113 retval = errno;
114 if (retval == ENOENT) {
115#ifdef DEBUG
116 printf("Bogus entry in %s! (%s does not exist)\n",
117 mtab_file, mnt->mnt_dir);
118#endif /* DEBUG */
119 retval = 0;
120 }
121 goto errout;
122 }
123 if (file_rdev && (st_buf.st_dev != file_rdev)) {
124#ifdef DEBUG
125 printf("Bogus entry in %s! (%s not mounted on %s)\n",
126 mtab_file, file, mnt->mnt_dir);
127#endif /* DEBUG */
128 goto errout;
129 }
130#endif /* __GNU__ */
131 *mount_flags = EXT2_MF_MOUNTED;
132
133#ifdef MNTOPT_RO
134 /* Check to see if the ro option is set */
135 if (hasmntopt(mnt, MNTOPT_RO))
136 *mount_flags |= EXT2_MF_READONLY;
137#endif
138
139 if (mtpt)
140 strncpy(mtpt, mnt->mnt_dir, mtlen);
141 /*
142 * Check to see if we're referring to the root filesystem.
143 * If so, do a manual check to see if we can open /etc/mtab
144 * read/write, since if the root is mounted read/only, the
145 * contents of /etc/mtab may not be accurate.
146 */
147 if (LONE_CHAR(mnt->mnt_dir, '/')) {
148is_root:
149#define TEST_FILE "/.ismount-test-file"
150 *mount_flags |= EXT2_MF_ISROOT;
151 fd = open(TEST_FILE, O_RDWR|O_CREAT);
152 if (fd < 0) {
153 if (errno == EROFS)
154 *mount_flags |= EXT2_MF_READONLY;
155 } else
156 close(fd);
157 (void) unlink(TEST_FILE);
158 }
159 retval = 0;
160errout:
161 endmntent (f);
162 return retval;
163}
164
165static errcode_t check_mntent(const char *file, int *mount_flags,
166 char *mtpt, int mtlen)
167{
168 errcode_t retval;
169
170#ifdef DEBUG
171 retval = check_mntent_file("/tmp/mtab", file, mount_flags,
172 mtpt, mtlen);
173 if (retval == 0)
174 return 0;
175#endif /* DEBUG */
176#ifdef __linux__
177 retval = check_mntent_file("/proc/mounts", file, mount_flags,
178 mtpt, mtlen);
179 if (retval == 0 && (*mount_flags != 0))
180 return 0;
181#endif /* __linux__ */
182#if defined(MOUNTED) || defined(_PATH_MOUNTED)
183#ifndef MOUNTED
184#define MOUNTED _PATH_MOUNTED
185#endif /* MOUNTED */
186 retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
187 return retval;
188#else
189 *mount_flags = 0;
190 return 0;
191#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
192}
193
194#else
195#if defined(HAVE_GETMNTINFO)
196
197static errcode_t check_getmntinfo(const char *file, int *mount_flags,
198 char *mtpt, int mtlen)
199{
200 struct statfs *mp;
201 int len, n;
202 const char *s1;
203 char *s2;
204
205 n = getmntinfo(&mp, MNT_NOWAIT);
206 if (n == 0)
207 return errno;
208
209 len = sizeof(_PATH_DEV) - 1;
210 s1 = file;
211 if (strncmp(_PATH_DEV, s1, len) == 0)
212 s1 += len;
213
214 *mount_flags = 0;
215 while (--n >= 0) {
216 s2 = mp->f_mntfromname;
217 if (strncmp(_PATH_DEV, s2, len) == 0) {
218 s2 += len - 1;
219 *s2 = 'r';
220 }
221 if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
222 *mount_flags = EXT2_MF_MOUNTED;
223 break;
224 }
225 ++mp;
226 }
227 if (mtpt)
228 strncpy(mtpt, mp->f_mntonname, mtlen);
229 return 0;
230}
231#endif /* HAVE_GETMNTINFO */
232#endif /* HAVE_MNTENT_H */
233
234/*
235 * Check to see if we're dealing with the swap device.
236 */
237static int is_swap_device(const char *file)
238{
239 FILE *f;
240 char buf[1024], *cp;
241 dev_t file_dev;
242 struct stat st_buf;
243 int ret = 0;
244
245 file_dev = 0;
246#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
247 if ((stat(file, &st_buf) == 0) &&
248 S_ISBLK(st_buf.st_mode))
249 file_dev = st_buf.st_rdev;
250#endif /* __GNU__ */
251
252 if (!(f = fopen("/proc/swaps", "r")))
253 return 0;
254 /* Skip the first line */
255 fgets(buf, sizeof(buf), f);
256 while (!feof(f)) {
257 if (!fgets(buf, sizeof(buf), f))
258 break;
259 if ((cp = strchr(buf, ' ')) != NULL)
260 *cp = 0;
261 if ((cp = strchr(buf, '\t')) != NULL)
262 *cp = 0;
263 if (strcmp(buf, file) == 0) {
264 ret++;
265 break;
266 }
267#ifndef __GNU__
268 if (file_dev && (stat(buf, &st_buf) == 0) &&
269 S_ISBLK(st_buf.st_mode) &&
270 file_dev == st_buf.st_rdev) {
271 ret++;
272 break;
273 }
274#endif /* __GNU__ */
275 }
276 fclose(f);
277 return ret;
278}
279
280
281/*
282 * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
283 * otherwise. If mtpt is non-NULL, the directory where the device is
284 * mounted is copied to where mtpt is pointing, up to mtlen
285 * characters.
286 */
287#ifdef __TURBOC__
288# pragma argsused
289#endif
290errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
291 char *mtpt, int mtlen)
292{
293 if (is_swap_device(device)) {
294 *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
295 strncpy(mtpt, "<swap>", mtlen);
296 return 0;
297 }
298#ifdef HAVE_MNTENT_H
299 return check_mntent(device, mount_flags, mtpt, mtlen);
300#else
301#ifdef HAVE_GETMNTINFO
302 return check_getmntinfo(device, mount_flags, mtpt, mtlen);
303#else
304#ifdef __GNUC__
305 #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
306#endif
307 *mount_flags = 0;
308 return 0;
309#endif /* HAVE_GETMNTINFO */
310#endif /* HAVE_MNTENT_H */
311}
312
313/*
314 * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED,
315 * EXT2_MF_READONLY, and EXT2_MF_ROOT
316 *
317 */
318errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
319{
320 return ext2fs_check_mount_point(file, mount_flags, NULL, 0);
321}
322
323#ifdef DEBUG
324int main(int argc, char **argv)
325{
326 int retval, mount_flags;
327 char mntpt[80];
328
329 if (argc < 2) {
330 fprintf(stderr, "Usage: %s device\n", argv[0]);
331 exit(1);
332 }
333
334 mntpt[0] = 0;
335 retval = ext2fs_check_mount_point(argv[1], &mount_flags,
336 mntpt, sizeof(mntpt));
337 if (retval) {
338 com_err(argv[0], retval,
339 "while calling ext2fs_check_if_mounted");
340 exit(1);
341 }
342 printf("Device %s reports flags %02x\n", argv[1], mount_flags);
343 if (mount_flags & EXT2_MF_BUSY)
344 printf("\t%s is apparently in use.\n", argv[1]);
345 if (mount_flags & EXT2_MF_MOUNTED)
346 printf("\t%s is mounted.\n", argv[1]);
347 if (mount_flags & EXT2_MF_SWAP)
348 printf("\t%s is a swap device.\n", argv[1]);
349 if (mount_flags & EXT2_MF_READONLY)
350 printf("\t%s is read-only.\n", argv[1]);
351 if (mount_flags & EXT2_MF_ISROOT)
352 printf("\t%s is the root filesystem.\n", argv[1]);
353 if (mntpt[0])
354 printf("\t%s is mounted on %s.\n", argv[1], mntpt);
355 exit(0);
356}
357#endif /* DEBUG */
diff --git a/e2fsprogs/ext2fs/jfs_dat.h b/e2fsprogs/ext2fs/jfs_dat.h
deleted file mode 100644
index 136635de0..000000000
--- a/e2fsprogs/ext2fs/jfs_dat.h
+++ /dev/null
@@ -1,65 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * jfs_dat.h --- stripped down header file which only contains the JFS
4 * on-disk data structures
5 */
6
7#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
8
9/*
10 * On-disk structures
11 */
12
13/*
14 * Descriptor block types:
15 */
16
17#define JFS_DESCRIPTOR_BLOCK 1
18#define JFS_COMMIT_BLOCK 2
19#define JFS_SUPERBLOCK 3
20
21/*
22 * Standard header for all descriptor blocks:
23 */
24typedef struct journal_header_s
25{
26 __u32 h_magic;
27 __u32 h_blocktype;
28 __u32 h_sequence;
29} journal_header_t;
30
31
32/*
33 * The block tag: used to describe a single buffer in the journal
34 */
35typedef struct journal_block_tag_s
36{
37 __u32 t_blocknr; /* The on-disk block number */
38 __u32 t_flags; /* See below */
39} journal_block_tag_t;
40
41/* Definitions for the journal tag flags word: */
42#define JFS_FLAG_ESCAPE 1 /* on-disk block is escaped */
43#define JFS_FLAG_SAME_UUID 2 /* block has same uuid as previous */
44#define JFS_FLAG_DELETED 4 /* block deleted by this transaction */
45#define JFS_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
46
47
48/*
49 * The journal superblock
50 */
51typedef struct journal_superblock_s
52{
53 journal_header_t s_header;
54
55 /* Static information describing the journal */
56 __u32 s_blocksize; /* journal device blocksize */
57 __u32 s_maxlen; /* total blocks in journal file */
58 __u32 s_first; /* first block of log information */
59
60 /* Dynamic information describing the current state of the log */
61 __u32 s_sequence; /* first commit ID expected in log */
62 __u32 s_start; /* blocknr of start of log */
63
64} journal_superblock_t;
65
diff --git a/e2fsprogs/ext2fs/kernel-jbd.h b/e2fsprogs/ext2fs/kernel-jbd.h
deleted file mode 100644
index 4c6c7dedd..000000000
--- a/e2fsprogs/ext2fs/kernel-jbd.h
+++ /dev/null
@@ -1,236 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * linux/include/linux/jbd.h
4 *
5 * Written by Stephen C. Tweedie <sct@redhat.com>
6 *
7 * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
8 *
9 * This file is part of the Linux kernel and is made available under
10 * the terms of the GNU General Public License, version 2, or at your
11 * option, any later version, incorporated herein by reference.
12 *
13 * Definitions for transaction data structures for the buffer cache
14 * filesystem journaling support.
15 */
16
17#ifndef _LINUX_JBD_H
18#define _LINUX_JBD_H
19
20#include <sys/types.h>
21#include <linux/types.h>
22#include "ext2fs.h"
23
24/*
25 * Standard header for all descriptor blocks:
26 */
27
28typedef struct journal_header_s
29{
30 __u32 h_magic;
31 __u32 h_blocktype;
32 __u32 h_sequence;
33} journal_header_t;
34
35/*
36 * This is the global e2fsck structure.
37 */
38typedef struct e2fsck_struct *e2fsck_t;
39
40
41struct inode {
42 e2fsck_t i_ctx;
43 ext2_ino_t i_ino;
44 struct ext2_inode i_ext2;
45};
46
47
48/*
49 * The journal superblock. All fields are in big-endian byte order.
50 */
51typedef struct journal_superblock_s
52{
53/* 0x0000 */
54 journal_header_t s_header;
55
56/* 0x000C */
57 /* Static information describing the journal */
58 __u32 s_blocksize; /* journal device blocksize */
59 __u32 s_maxlen; /* total blocks in journal file */
60 __u32 s_first; /* first block of log information */
61
62/* 0x0018 */
63 /* Dynamic information describing the current state of the log */
64 __u32 s_sequence; /* first commit ID expected in log */
65 __u32 s_start; /* blocknr of start of log */
66
67/* 0x0020 */
68 /* Error value, as set by journal_abort(). */
69 __s32 s_errno;
70
71/* 0x0024 */
72 /* Remaining fields are only valid in a version-2 superblock */
73 __u32 s_feature_compat; /* compatible feature set */
74 __u32 s_feature_incompat; /* incompatible feature set */
75 __u32 s_feature_ro_compat; /* readonly-compatible feature set */
76/* 0x0030 */
77 __u8 s_uuid[16]; /* 128-bit uuid for journal */
78
79/* 0x0040 */
80 __u32 s_nr_users; /* Nr of filesystems sharing log */
81
82 __u32 s_dynsuper; /* Blocknr of dynamic superblock copy*/
83
84/* 0x0048 */
85 __u32 s_max_transaction; /* Limit of journal blocks per trans.*/
86 __u32 s_max_trans_data; /* Limit of data blocks per trans. */
87
88/* 0x0050 */
89 __u32 s_padding[44];
90
91/* 0x0100 */
92 __u8 s_users[16*48]; /* ids of all fs'es sharing the log */
93/* 0x0400 */
94} journal_superblock_t;
95
96
97extern int journal_blocks_per_page(struct inode *inode);
98extern int jbd_blocks_per_page(struct inode *inode);
99
100#define JFS_MIN_JOURNAL_BLOCKS 1024
101
102
103/*
104 * Internal structures used by the logging mechanism:
105 */
106
107#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
108
109/*
110 * Descriptor block types:
111 */
112
113#define JFS_DESCRIPTOR_BLOCK 1
114#define JFS_COMMIT_BLOCK 2
115#define JFS_SUPERBLOCK_V1 3
116#define JFS_SUPERBLOCK_V2 4
117#define JFS_REVOKE_BLOCK 5
118
119/*
120 * The block tag: used to describe a single buffer in the journal
121 */
122typedef struct journal_block_tag_s
123{
124 __u32 t_blocknr; /* The on-disk block number */
125 __u32 t_flags; /* See below */
126} journal_block_tag_t;
127
128/*
129 * The revoke descriptor: used on disk to describe a series of blocks to
130 * be revoked from the log
131 */
132typedef struct journal_revoke_header_s
133{
134 journal_header_t r_header;
135 int r_count; /* Count of bytes used in the block */
136} journal_revoke_header_t;
137
138
139/* Definitions for the journal tag flags word: */
140#define JFS_FLAG_ESCAPE 1 /* on-disk block is escaped */
141#define JFS_FLAG_SAME_UUID 2 /* block has same uuid as previous */
142#define JFS_FLAG_DELETED 4 /* block deleted by this transaction */
143#define JFS_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
144
145
146
147
148#define JFS_HAS_COMPAT_FEATURE(j,mask) \
149 ((j)->j_format_version >= 2 && \
150 ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
151#define JFS_HAS_RO_COMPAT_FEATURE(j,mask) \
152 ((j)->j_format_version >= 2 && \
153 ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
154#define JFS_HAS_INCOMPAT_FEATURE(j,mask) \
155 ((j)->j_format_version >= 2 && \
156 ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
157
158#define JFS_FEATURE_INCOMPAT_REVOKE 0x00000001
159
160/* Features known to this kernel version: */
161#define JFS_KNOWN_COMPAT_FEATURES 0
162#define JFS_KNOWN_ROCOMPAT_FEATURES 0
163#define JFS_KNOWN_INCOMPAT_FEATURES JFS_FEATURE_INCOMPAT_REVOKE
164
165/* Comparison functions for transaction IDs: perform comparisons using
166 * modulo arithmetic so that they work over sequence number wraps. */
167
168
169/*
170 * Definitions which augment the buffer_head layer
171 */
172
173/* journaling buffer types */
174#define BJ_None 0 /* Not journaled */
175#define BJ_SyncData 1 /* Normal data: flush before commit */
176#define BJ_AsyncData 2 /* writepage data: wait on it before commit */
177#define BJ_Metadata 3 /* Normal journaled metadata */
178#define BJ_Forget 4 /* Buffer superceded by this transaction */
179#define BJ_IO 5 /* Buffer is for temporary IO use */
180#define BJ_Shadow 6 /* Buffer contents being shadowed to the log */
181#define BJ_LogCtl 7 /* Buffer contains log descriptors */
182#define BJ_Reserved 8 /* Buffer is reserved for access by journal */
183#define BJ_Types 9
184
185
186struct kdev_s {
187 e2fsck_t k_ctx;
188 int k_dev;
189};
190
191typedef struct kdev_s *kdev_t;
192typedef unsigned int tid_t;
193
194struct journal_s
195{
196 unsigned long j_flags;
197 int j_errno;
198 struct buffer_head * j_sb_buffer;
199 struct journal_superblock_s *j_superblock;
200 int j_format_version;
201 unsigned long j_head;
202 unsigned long j_tail;
203 unsigned long j_free;
204 unsigned long j_first, j_last;
205 kdev_t j_dev;
206 kdev_t j_fs_dev;
207 int j_blocksize;
208 unsigned int j_blk_offset;
209 unsigned int j_maxlen;
210 struct inode * j_inode;
211 tid_t j_tail_sequence;
212 tid_t j_transaction_sequence;
213 __u8 j_uuid[16];
214 struct jbd_revoke_table_s *j_revoke;
215};
216
217typedef struct journal_s journal_t;
218
219extern int journal_recover (journal_t *journal);
220extern int journal_skip_recovery (journal_t *);
221
222/* Primary revoke support */
223extern int journal_init_revoke(journal_t *, int);
224extern void journal_destroy_revoke_caches(void);
225extern int journal_init_revoke_caches(void);
226
227/* Recovery revoke support */
228extern int journal_set_revoke(journal_t *, unsigned long, tid_t);
229extern int journal_test_revoke(journal_t *, unsigned long, tid_t);
230extern void journal_clear_revoke(journal_t *);
231extern void journal_brelse_array(struct buffer_head *b[], int n);
232
233extern void journal_destroy_revoke(journal_t *);
234
235
236#endif /* _LINUX_JBD_H */
diff --git a/e2fsprogs/ext2fs/kernel-list.h b/e2fsprogs/ext2fs/kernel-list.h
deleted file mode 100644
index 3392596ca..000000000
--- a/e2fsprogs/ext2fs/kernel-list.h
+++ /dev/null
@@ -1,113 +0,0 @@
1/* vi: set sw=4 ts=4: */
2#ifndef _LINUX_LIST_H
3#define _LINUX_LIST_H
4
5/*
6 * Simple doubly linked list implementation.
7 *
8 * Some of the internal functions ("__xxx") are useful when
9 * manipulating whole lists rather than single entries, as
10 * sometimes we already know the next/prev entries and we can
11 * generate better code by using them directly rather than
12 * using the generic single-entry routines.
13 */
14
15struct list_head {
16 struct list_head *next, *prev;
17};
18
19#define LIST_HEAD_INIT(name) { &(name), &(name) }
20
21#define LIST_HEAD(name) \
22 struct list_head name = { &name, &name }
23
24#define INIT_LIST_HEAD(ptr) do { \
25 (ptr)->next = (ptr); (ptr)->prev = (ptr); \
26} while (0)
27
28#if (!defined(__GNUC__) && !defined(__WATCOMC__))
29#define __inline__
30#endif
31
32/*
33 * Insert a new entry between two known consecutive entries.
34 *
35 * This is only for internal list manipulation where we know
36 * the prev/next entries already!
37 */
38static __inline__ void __list_add(struct list_head * new,
39 struct list_head * prev,
40 struct list_head * next)
41{
42 next->prev = new;
43 new->next = next;
44 new->prev = prev;
45 prev->next = new;
46}
47
48/*
49 * Insert a new entry after the specified head..
50 */
51static __inline__ void list_add(struct list_head *new, struct list_head *head)
52{
53 __list_add(new, head, head->next);
54}
55
56/*
57 * Insert a new entry at the tail
58 */
59static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
60{
61 __list_add(new, head->prev, head);
62}
63
64/*
65 * Delete a list entry by making the prev/next entries
66 * point to each other.
67 *
68 * This is only for internal list manipulation where we know
69 * the prev/next entries already!
70 */
71static __inline__ void __list_del(struct list_head * prev,
72 struct list_head * next)
73{
74 next->prev = prev;
75 prev->next = next;
76}
77
78static __inline__ void list_del(struct list_head *entry)
79{
80 __list_del(entry->prev, entry->next);
81}
82
83static __inline__ int list_empty(struct list_head *head)
84{
85 return head->next == head;
86}
87
88/*
89 * Splice in "list" into "head"
90 */
91static __inline__ void list_splice(struct list_head *list, struct list_head *head)
92{
93 struct list_head *first = list->next;
94
95 if (first != list) {
96 struct list_head *last = list->prev;
97 struct list_head *at = head->next;
98
99 first->prev = head;
100 head->next = first;
101
102 last->next = at;
103 at->prev = last;
104 }
105}
106
107#define list_entry(ptr, type, member) \
108 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
109
110#define list_for_each(pos, head) \
111 for (pos = (head)->next; pos != (head); pos = pos->next)
112
113#endif
diff --git a/e2fsprogs/ext2fs/link.c b/e2fsprogs/ext2fs/link.c
deleted file mode 100644
index 08b2e9673..000000000
--- a/e2fsprogs/ext2fs/link.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * link.c --- create links in a ext2fs directory
4 *
5 * Copyright (C) 1993, 1994 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct link_struct {
23 const char *name;
24 int namelen;
25 ext2_ino_t inode;
26 int flags;
27 int done;
28 struct ext2_super_block *sb;
29};
30
31static int link_proc(struct ext2_dir_entry *dirent,
32 int offset,
33 int blocksize,
34 char *buf,
35 void *priv_data)
36{
37 struct link_struct *ls = (struct link_struct *) priv_data;
38 struct ext2_dir_entry *next;
39 int rec_len, min_rec_len;
40 int ret = 0;
41
42 rec_len = EXT2_DIR_REC_LEN(ls->namelen);
43
44 /*
45 * See if the following directory entry (if any) is unused;
46 * if so, absorb it into this one.
47 */
48 next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
49 if ((offset + dirent->rec_len < blocksize - 8) &&
50 (next->inode == 0) &&
51 (offset + dirent->rec_len + next->rec_len <= blocksize)) {
52 dirent->rec_len += next->rec_len;
53 ret = DIRENT_CHANGED;
54 }
55
56 /*
57 * If the directory entry is used, see if we can split the
58 * directory entry to make room for the new name. If so,
59 * truncate it and return.
60 */
61 if (dirent->inode) {
62 min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
63 if (dirent->rec_len < (min_rec_len + rec_len))
64 return ret;
65 rec_len = dirent->rec_len - min_rec_len;
66 dirent->rec_len = min_rec_len;
67 next = (struct ext2_dir_entry *) (buf + offset +
68 dirent->rec_len);
69 next->inode = 0;
70 next->name_len = 0;
71 next->rec_len = rec_len;
72 return DIRENT_CHANGED;
73 }
74
75 /*
76 * If we get this far, then the directory entry is not used.
77 * See if we can fit the request entry in. If so, do it.
78 */
79 if (dirent->rec_len < rec_len)
80 return ret;
81 dirent->inode = ls->inode;
82 dirent->name_len = ls->namelen;
83 strncpy(dirent->name, ls->name, ls->namelen);
84 if (ls->sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
85 dirent->name_len |= (ls->flags & 0x7) << 8;
86
87 ls->done++;
88 return DIRENT_ABORT|DIRENT_CHANGED;
89}
90
91/*
92 * Note: the low 3 bits of the flags field are used as the directory
93 * entry filetype.
94 */
95#ifdef __TURBOC__
96# pragma argsused
97#endif
98errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
99 ext2_ino_t ino, int flags)
100{
101 errcode_t retval;
102 struct link_struct ls;
103 struct ext2_inode inode;
104
105 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
106
107 if (!(fs->flags & EXT2_FLAG_RW))
108 return EXT2_ET_RO_FILSYS;
109
110 ls.name = name;
111 ls.namelen = name ? strlen(name) : 0;
112 ls.inode = ino;
113 ls.flags = flags;
114 ls.done = 0;
115 ls.sb = fs->super;
116
117 retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
118 0, link_proc, &ls);
119 if (retval)
120 return retval;
121
122 if (!ls.done)
123 return EXT2_ET_DIR_NO_SPACE;
124
125 if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
126 return retval;
127
128 if (inode.i_flags & EXT2_INDEX_FL) {
129 inode.i_flags &= ~EXT2_INDEX_FL;
130 if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
131 return retval;
132 }
133
134 return 0;
135}
diff --git a/e2fsprogs/ext2fs/lookup.c b/e2fsprogs/ext2fs/lookup.c
deleted file mode 100644
index 31b30a182..000000000
--- a/e2fsprogs/ext2fs/lookup.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * lookup.c --- ext2fs directory lookup operations
4 *
5 * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct lookup_struct {
23 const char *name;
24 int len;
25 ext2_ino_t *inode;
26 int found;
27};
28
29#ifdef __TURBOC__
30# pragma argsused
31#endif
32static int lookup_proc(struct ext2_dir_entry *dirent,
33 int offset EXT2FS_ATTR((unused)),
34 int blocksize EXT2FS_ATTR((unused)),
35 char *buf EXT2FS_ATTR((unused)),
36 void *priv_data)
37{
38 struct lookup_struct *ls = (struct lookup_struct *) priv_data;
39
40 if (ls->len != (dirent->name_len & 0xFF))
41 return 0;
42 if (strncmp(ls->name, dirent->name, (dirent->name_len & 0xFF)))
43 return 0;
44 *ls->inode = dirent->inode;
45 ls->found++;
46 return DIRENT_ABORT;
47}
48
49
50errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
51 int namelen, char *buf, ext2_ino_t *inode)
52{
53 errcode_t retval;
54 struct lookup_struct ls;
55
56 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
57
58 ls.name = name;
59 ls.len = namelen;
60 ls.inode = inode;
61 ls.found = 0;
62
63 retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
64 if (retval)
65 return retval;
66
67 return (ls.found) ? 0 : EXT2_ET_FILE_NOT_FOUND;
68}
69
70
diff --git a/e2fsprogs/ext2fs/mkdir.c b/e2fsprogs/ext2fs/mkdir.c
deleted file mode 100644
index b63c5d7a6..000000000
--- a/e2fsprogs/ext2fs/mkdir.c
+++ /dev/null
@@ -1,142 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * mkdir.c --- make a directory in the filesystem
4 *
5 * Copyright (C) 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30#ifndef EXT2_FT_DIR
31#define EXT2_FT_DIR 2
32#endif
33
34errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
35 const char *name)
36{
37 errcode_t retval;
38 struct ext2_inode parent_inode, inode;
39 ext2_ino_t ino = inum;
40 ext2_ino_t scratch_ino;
41 blk_t blk;
42 char *block = 0;
43
44 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
45
46 /*
47 * Allocate an inode, if necessary
48 */
49 if (!ino) {
50 retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755,
51 0, &ino);
52 if (retval)
53 goto cleanup;
54 }
55
56 /*
57 * Allocate a data block for the directory
58 */
59 retval = ext2fs_new_block(fs, 0, 0, &blk);
60 if (retval)
61 goto cleanup;
62
63 /*
64 * Create a scratch template for the directory
65 */
66 retval = ext2fs_new_dir_block(fs, ino, parent, &block);
67 if (retval)
68 goto cleanup;
69
70 /*
71 * Get the parent's inode, if necessary
72 */
73 if (parent != ino) {
74 retval = ext2fs_read_inode(fs, parent, &parent_inode);
75 if (retval)
76 goto cleanup;
77 } else
78 memset(&parent_inode, 0, sizeof(parent_inode));
79
80 /*
81 * Create the inode structure....
82 */
83 memset(&inode, 0, sizeof(struct ext2_inode));
84 inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
85 inode.i_uid = inode.i_gid = 0;
86 inode.i_blocks = fs->blocksize / 512;
87 inode.i_block[0] = blk;
88 inode.i_links_count = 2;
89 inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
90 inode.i_size = fs->blocksize;
91
92 /*
93 * Write out the inode and inode data block
94 */
95 retval = ext2fs_write_dir_block(fs, blk, block);
96 if (retval)
97 goto cleanup;
98 retval = ext2fs_write_new_inode(fs, ino, &inode);
99 if (retval)
100 goto cleanup;
101
102 /*
103 * Link the directory into the filesystem hierarchy
104 */
105 if (name) {
106 retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
107 &scratch_ino);
108 if (!retval) {
109 retval = EXT2_ET_DIR_EXISTS;
110 name = 0;
111 goto cleanup;
112 }
113 if (retval != EXT2_ET_FILE_NOT_FOUND)
114 goto cleanup;
115 retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR);
116 if (retval)
117 goto cleanup;
118 }
119
120 /*
121 * Update parent inode's counts
122 */
123 if (parent != ino) {
124 parent_inode.i_links_count++;
125 retval = ext2fs_write_inode(fs, parent, &parent_inode);
126 if (retval)
127 goto cleanup;
128 }
129
130 /*
131 * Update accounting....
132 */
133 ext2fs_block_alloc_stats(fs, blk, +1);
134 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
135
136cleanup:
137 ext2fs_free_mem(&block);
138 return retval;
139
140}
141
142
diff --git a/e2fsprogs/ext2fs/mkjournal.c b/e2fsprogs/ext2fs/mkjournal.c
deleted file mode 100644
index 5bdd34682..000000000
--- a/e2fsprogs/ext2fs/mkjournal.c
+++ /dev/null
@@ -1,428 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * mkjournal.c --- make a journal for a filesystem
4 *
5 * Copyright (C) 2000 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#if HAVE_ERRNO_H
19#include <errno.h>
20#endif
21#include <fcntl.h>
22#include <time.h>
23#if HAVE_SYS_STAT_H
24#include <sys/stat.h>
25#endif
26#if HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
29#if HAVE_SYS_IOCTL_H
30#include <sys/ioctl.h>
31#endif
32#if HAVE_NETINET_IN_H
33#include <netinet/in.h>
34#endif
35
36#include "ext2_fs.h"
37#include "../e2p/e2p.h"
38#include "../e2fsck.h"
39#include "ext2fs.h"
40#include "kernel-jbd.h"
41
42/*
43 * This function automatically sets up the journal superblock and
44 * returns it as an allocated block.
45 */
46errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
47 __u32 size, int flags,
48 char **ret_jsb)
49{
50 errcode_t retval;
51 journal_superblock_t *jsb;
52
53 if (size < 1024)
54 return EXT2_ET_JOURNAL_TOO_SMALL;
55
56 if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
57 return retval;
58
59 memset (jsb, 0, fs->blocksize);
60
61 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
62 if (flags & EXT2_MKJOURNAL_V1_SUPER)
63 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1);
64 else
65 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
66 jsb->s_blocksize = htonl(fs->blocksize);
67 jsb->s_maxlen = htonl(size);
68 jsb->s_nr_users = htonl(1);
69 jsb->s_first = htonl(1);
70 jsb->s_sequence = htonl(1);
71 memcpy(jsb->s_uuid, fs->super->s_uuid, sizeof(fs->super->s_uuid));
72 /*
73 * If we're creating an external journal device, we need to
74 * adjust these fields.
75 */
76 if (fs->super->s_feature_incompat &
77 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
78 jsb->s_nr_users = 0;
79 if (fs->blocksize == 1024)
80 jsb->s_first = htonl(3);
81 else
82 jsb->s_first = htonl(2);
83 }
84
85 *ret_jsb = (char *) jsb;
86 return 0;
87}
88
89/*
90 * This function writes a journal using POSIX routines. It is used
91 * for creating external journals and creating journals on live
92 * filesystems.
93 */
94static errcode_t write_journal_file(ext2_filsys fs, char *filename,
95 blk_t size, int flags)
96{
97 errcode_t retval;
98 char *buf = 0;
99 int fd, ret_size;
100 blk_t i;
101
102 if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
103 return retval;
104
105 /* Open the device or journal file */
106 if ((fd = open(filename, O_WRONLY)) < 0) {
107 retval = errno;
108 goto errout;
109 }
110
111 /* Write the superblock out */
112 retval = EXT2_ET_SHORT_WRITE;
113 ret_size = write(fd, buf, fs->blocksize);
114 if (ret_size < 0) {
115 retval = errno;
116 goto errout;
117 }
118 if (ret_size != (int) fs->blocksize)
119 goto errout;
120 memset(buf, 0, fs->blocksize);
121
122 for (i = 1; i < size; i++) {
123 ret_size = write(fd, buf, fs->blocksize);
124 if (ret_size < 0) {
125 retval = errno;
126 goto errout;
127 }
128 if (ret_size != (int) fs->blocksize)
129 goto errout;
130 }
131 close(fd);
132
133 retval = 0;
134errout:
135 ext2fs_free_mem(&buf);
136 return retval;
137}
138
139/*
140 * Helper function for creating the journal using direct I/O routines
141 */
142struct mkjournal_struct {
143 int num_blocks;
144 int newblocks;
145 char *buf;
146 errcode_t err;
147};
148
149static int mkjournal_proc(ext2_filsys fs,
150 blk_t *blocknr,
151 e2_blkcnt_t blockcnt,
152 blk_t ref_block EXT2FS_ATTR((unused)),
153 int ref_offset EXT2FS_ATTR((unused)),
154 void *priv_data)
155{
156 struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data;
157 blk_t new_blk;
158 static blk_t last_blk = 0;
159 errcode_t retval;
160
161 if (*blocknr) {
162 last_blk = *blocknr;
163 return 0;
164 }
165 retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
166 if (retval) {
167 es->err = retval;
168 return BLOCK_ABORT;
169 }
170 if (blockcnt > 0)
171 es->num_blocks--;
172
173 es->newblocks++;
174 retval = io_channel_write_blk(fs->io, new_blk, 1, es->buf);
175
176 if (blockcnt == 0)
177 memset(es->buf, 0, fs->blocksize);
178
179 if (retval) {
180 es->err = retval;
181 return BLOCK_ABORT;
182 }
183 *blocknr = new_blk;
184 last_blk = new_blk;
185 ext2fs_block_alloc_stats(fs, new_blk, +1);
186
187 if (es->num_blocks == 0)
188 return (BLOCK_CHANGED | BLOCK_ABORT);
189 else
190 return BLOCK_CHANGED;
191
192}
193
194/*
195 * This function creates a journal using direct I/O routines.
196 */
197static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
198 blk_t size, int flags)
199{
200 char *buf;
201 errcode_t retval;
202 struct ext2_inode inode;
203 struct mkjournal_struct es;
204
205 if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
206 return retval;
207
208 if ((retval = ext2fs_read_bitmaps(fs)))
209 return retval;
210
211 if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
212 return retval;
213
214 if (inode.i_blocks > 0)
215 return EEXIST;
216
217 es.num_blocks = size;
218 es.newblocks = 0;
219 es.buf = buf;
220 es.err = 0;
221
222 retval = ext2fs_block_iterate2(fs, journal_ino, BLOCK_FLAG_APPEND,
223 0, mkjournal_proc, &es);
224 if (es.err) {
225 retval = es.err;
226 goto errout;
227 }
228
229 if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
230 goto errout;
231
232 inode.i_size += fs->blocksize * size;
233 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
234 inode.i_mtime = inode.i_ctime = time(0);
235 inode.i_links_count = 1;
236 inode.i_mode = LINUX_S_IFREG | 0600;
237
238 if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
239 goto errout;
240 retval = 0;
241
242 memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
243 fs->super->s_jnl_blocks[16] = inode.i_size;
244 fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
245 ext2fs_mark_super_dirty(fs);
246
247errout:
248 ext2fs_free_mem(&buf);
249 return retval;
250}
251
252/*
253 * This function adds a journal device to a filesystem
254 */
255errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
256{
257 struct stat st;
258 errcode_t retval;
259 char buf[1024];
260 journal_superblock_t *jsb;
261 int start;
262 __u32 i, nr_users;
263
264 /* Make sure the device exists and is a block device */
265 if (stat(journal_dev->device_name, &st) < 0)
266 return errno;
267
268 if (!S_ISBLK(st.st_mode))
269 return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */
270
271 /* Get the journal superblock */
272 start = 1;
273 if (journal_dev->blocksize == 1024)
274 start++;
275 if ((retval = io_channel_read_blk(journal_dev->io, start, -1024, buf)))
276 return retval;
277
278 jsb = (journal_superblock_t *) buf;
279 if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
280 (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2)))
281 return EXT2_ET_NO_JOURNAL_SB;
282
283 if (ntohl(jsb->s_blocksize) != (unsigned long) fs->blocksize)
284 return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
285
286 /* Check and see if this filesystem has already been added */
287 nr_users = ntohl(jsb->s_nr_users);
288 for (i=0; i < nr_users; i++) {
289 if (memcmp(fs->super->s_uuid,
290 &jsb->s_users[i*16], 16) == 0)
291 break;
292 }
293 if (i >= nr_users) {
294 memcpy(&jsb->s_users[nr_users*16],
295 fs->super->s_uuid, 16);
296 jsb->s_nr_users = htonl(nr_users+1);
297 }
298
299 /* Writeback the journal superblock */
300 if ((retval = io_channel_write_blk(journal_dev->io, start, -1024, buf)))
301 return retval;
302
303 fs->super->s_journal_inum = 0;
304 fs->super->s_journal_dev = st.st_rdev;
305 memcpy(fs->super->s_journal_uuid, jsb->s_uuid,
306 sizeof(fs->super->s_journal_uuid));
307 fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
308 ext2fs_mark_super_dirty(fs);
309 return 0;
310}
311
312/*
313 * This function adds a journal inode to a filesystem, using either
314 * POSIX routines if the filesystem is mounted, or using direct I/O
315 * functions if it is not.
316 */
317errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags)
318{
319 errcode_t retval;
320 ext2_ino_t journal_ino;
321 struct stat st;
322 char jfile[1024];
323 int fd, mount_flags, f;
324
325 retval = ext2fs_check_mount_point(fs->device_name, &mount_flags,
326 jfile, sizeof(jfile)-10);
327 if (retval)
328 return retval;
329
330 if (mount_flags & EXT2_MF_MOUNTED) {
331 strcat(jfile, "/.journal");
332
333 /*
334 * If .../.journal already exists, make sure any
335 * immutable or append-only flags are cleared.
336 */
337#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
338 (void) chflags (jfile, 0);
339#else
340#if HAVE_EXT2_IOCTLS
341 fd = open(jfile, O_RDONLY);
342 if (fd >= 0) {
343 f = 0;
344 ioctl(fd, EXT2_IOC_SETFLAGS, &f);
345 close(fd);
346 }
347#endif
348#endif
349
350 /* Create the journal file */
351 if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0)
352 return errno;
353
354 if ((retval = write_journal_file(fs, jfile, size, flags)))
355 goto errout;
356
357 /* Get inode number of the journal file */
358 if (fstat(fd, &st) < 0)
359 goto errout;
360
361#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
362 retval = fchflags (fd, UF_NODUMP|UF_IMMUTABLE);
363#else
364#if HAVE_EXT2_IOCTLS
365 f = EXT2_NODUMP_FL | EXT2_IMMUTABLE_FL;
366 retval = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
367#endif
368#endif
369 if (retval)
370 goto errout;
371
372 close(fd);
373 journal_ino = st.st_ino;
374 } else {
375 journal_ino = EXT2_JOURNAL_INO;
376 if ((retval = write_journal_inode(fs, journal_ino,
377 size, flags)))
378 return retval;
379 }
380
381 fs->super->s_journal_inum = journal_ino;
382 fs->super->s_journal_dev = 0;
383 memset(fs->super->s_journal_uuid, 0,
384 sizeof(fs->super->s_journal_uuid));
385 fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
386
387 ext2fs_mark_super_dirty(fs);
388 return 0;
389errout:
390 close(fd);
391 return retval;
392}
393
394#ifdef DEBUG
395main(int argc, char **argv)
396{
397 errcode_t retval;
398 char *device_name;
399 ext2_filsys fs;
400
401 if (argc < 2) {
402 fprintf(stderr, "Usage: %s filesystem\n", argv[0]);
403 exit(1);
404 }
405 device_name = argv[1];
406
407 retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
408 unix_io_manager, &fs);
409 if (retval) {
410 com_err(argv[0], retval, "while opening %s", device_name);
411 exit(1);
412 }
413
414 retval = ext2fs_add_journal_inode(fs, 1024);
415 if (retval) {
416 com_err(argv[0], retval, "while adding journal to %s",
417 device_name);
418 exit(1);
419 }
420 retval = ext2fs_flush(fs);
421 if (retval) {
422 printf("Warning, had trouble writing out superblocks.\n");
423 }
424 ext2fs_close(fs);
425 exit(0);
426
427}
428#endif
diff --git a/e2fsprogs/ext2fs/namei.c b/e2fsprogs/ext2fs/namei.c
deleted file mode 100644
index 988967009..000000000
--- a/e2fsprogs/ext2fs/namei.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * namei.c --- ext2fs directory lookup operations
4 *
5 * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19/* #define NAMEI_DEBUG */
20
21#include "ext2_fs.h"
22#include "ext2fs.h"
23
24static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
25 const char *pathname, size_t pathlen, int follow,
26 int link_count, char *buf, ext2_ino_t *res_inode);
27
28static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
29 ext2_ino_t inode, int link_count,
30 char *buf, ext2_ino_t *res_inode)
31{
32 char *pathname;
33 char *buffer = 0;
34 errcode_t retval;
35 struct ext2_inode ei;
36
37#ifdef NAMEI_DEBUG
38 printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
39 root, dir, inode, link_count);
40
41#endif
42 retval = ext2fs_read_inode (fs, inode, &ei);
43 if (retval) return retval;
44 if (!LINUX_S_ISLNK (ei.i_mode)) {
45 *res_inode = inode;
46 return 0;
47 }
48 if (link_count++ > 5) {
49 return EXT2_ET_SYMLINK_LOOP;
50 }
51 if (ext2fs_inode_data_blocks(fs,&ei)) {
52 retval = ext2fs_get_mem(fs->blocksize, &buffer);
53 if (retval)
54 return retval;
55 retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
56 if (retval) {
57 ext2fs_free_mem(&buffer);
58 return retval;
59 }
60 pathname = buffer;
61 } else
62 pathname = (char *)&(ei.i_block[0]);
63 retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
64 link_count, buf, res_inode);
65 ext2fs_free_mem(&buffer);
66 return retval;
67}
68
69/*
70 * This routine interprets a pathname in the context of the current
71 * directory and the root directory, and returns the inode of the
72 * containing directory, and a pointer to the filename of the file
73 * (pointing into the pathname) and the length of the filename.
74 */
75static errcode_t dir_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
76 const char *pathname, int pathlen,
77 int link_count, char *buf,
78 const char **name, int *namelen,
79 ext2_ino_t *res_inode)
80{
81 char c;
82 const char *thisname;
83 int len;
84 ext2_ino_t inode;
85 errcode_t retval;
86
87 if ((c = *pathname) == '/') {
88 dir = root;
89 pathname++;
90 pathlen--;
91 }
92 while (1) {
93 thisname = pathname;
94 for (len=0; --pathlen >= 0;len++) {
95 c = *(pathname++);
96 if (c == '/')
97 break;
98 }
99 if (pathlen < 0)
100 break;
101 retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
102 if (retval) return retval;
103 retval = follow_link (fs, root, dir, inode,
104 link_count, buf, &dir);
105 if (retval) return retval;
106 }
107 *name = thisname;
108 *namelen = len;
109 *res_inode = dir;
110 return 0;
111}
112
113static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
114 const char *pathname, size_t pathlen, int follow,
115 int link_count, char *buf, ext2_ino_t *res_inode)
116{
117 const char *basename;
118 int namelen;
119 ext2_ino_t dir, inode;
120 errcode_t retval;
121
122#ifdef NAMEI_DEBUG
123 printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
124 root, base, pathlen, pathname, link_count);
125#endif
126 retval = dir_namei(fs, root, base, pathname, pathlen,
127 link_count, buf, &basename, &namelen, &dir);
128 if (retval) return retval;
129 if (!namelen) { /* special case: '/usr/' etc */
130 *res_inode=dir;
131 return 0;
132 }
133 retval = ext2fs_lookup (fs, dir, basename, namelen, buf, &inode);
134 if (retval)
135 return retval;
136 if (follow) {
137 retval = follow_link(fs, root, dir, inode, link_count,
138 buf, &inode);
139 if (retval)
140 return retval;
141 }
142#ifdef NAMEI_DEBUG
143 printf("open_namei: (link_count=%d) returns %lu\n",
144 link_count, inode);
145#endif
146 *res_inode = inode;
147 return 0;
148}
149
150errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
151 const char *name, ext2_ino_t *inode)
152{
153 char *buf;
154 errcode_t retval;
155
156 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
157
158 retval = ext2fs_get_mem(fs->blocksize, &buf);
159 if (retval)
160 return retval;
161
162 retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
163 buf, inode);
164
165 ext2fs_free_mem(&buf);
166 return retval;
167}
168
169errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
170 const char *name, ext2_ino_t *inode)
171{
172 char *buf;
173 errcode_t retval;
174
175 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
176
177 retval = ext2fs_get_mem(fs->blocksize, &buf);
178 if (retval)
179 return retval;
180
181 retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
182 buf, inode);
183
184 ext2fs_free_mem(&buf);
185 return retval;
186}
187
188errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
189 ext2_ino_t inode, ext2_ino_t *res_inode)
190{
191 char *buf;
192 errcode_t retval;
193
194 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
195
196 retval = ext2fs_get_mem(fs->blocksize, &buf);
197 if (retval)
198 return retval;
199
200 retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
201
202 ext2fs_free_mem(&buf);
203 return retval;
204}
205
diff --git a/e2fsprogs/ext2fs/newdir.c b/e2fsprogs/ext2fs/newdir.c
deleted file mode 100644
index 9470e7f56..000000000
--- a/e2fsprogs/ext2fs/newdir.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * newdir.c --- create a new directory block
4 *
5 * Copyright (C) 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22#ifndef EXT2_FT_DIR
23#define EXT2_FT_DIR 2
24#endif
25
26/*
27 * Create new directory block
28 */
29errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
30 ext2_ino_t parent_ino, char **block)
31{
32 struct ext2_dir_entry *dir = NULL;
33 errcode_t retval;
34 char *buf;
35 int rec_len;
36 int filetype = 0;
37
38 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
39
40 retval = ext2fs_get_mem(fs->blocksize, &buf);
41 if (retval)
42 return retval;
43 memset(buf, 0, fs->blocksize);
44 dir = (struct ext2_dir_entry *) buf;
45 dir->rec_len = fs->blocksize;
46
47 if (dir_ino) {
48 if (fs->super->s_feature_incompat &
49 EXT2_FEATURE_INCOMPAT_FILETYPE)
50 filetype = EXT2_FT_DIR << 8;
51 /*
52 * Set up entry for '.'
53 */
54 dir->inode = dir_ino;
55 dir->name_len = 1 | filetype;
56 dir->name[0] = '.';
57 rec_len = dir->rec_len - EXT2_DIR_REC_LEN(1);
58 dir->rec_len = EXT2_DIR_REC_LEN(1);
59
60 /*
61 * Set up entry for '..'
62 */
63 dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
64 dir->rec_len = rec_len;
65 dir->inode = parent_ino;
66 dir->name_len = 2 | filetype;
67 dir->name[0] = '.';
68 dir->name[1] = '.';
69
70 }
71 *block = buf;
72 return 0;
73}
diff --git a/e2fsprogs/ext2fs/openfs.c b/e2fsprogs/ext2fs/openfs.c
deleted file mode 100644
index 716be060f..000000000
--- a/e2fsprogs/ext2fs/openfs.c
+++ /dev/null
@@ -1,330 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * openfs.c --- open an ext2 filesystem
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28
29
30#include "ext2fs.h"
31#include "e2image.h"
32
33blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
34{
35 int bg;
36 int has_super = 0;
37 int ret_blk;
38
39 if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
40 (i < fs->super->s_first_meta_bg))
41 return (group_block + i + 1);
42
43 bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
44 if (ext2fs_bg_has_super(fs, bg))
45 has_super = 1;
46 ret_blk = (fs->super->s_first_data_block + has_super +
47 (bg * fs->super->s_blocks_per_group));
48 /*
49 * If group_block is not the normal value, we're trying to use
50 * the backup group descriptors and superblock --- so use the
51 * alternate location of the second block group in the
52 * metablock group. Ideally we should be testing each bg
53 * descriptor block individually for correctness, but we don't
54 * have the infrastructure in place to do that.
55 */
56 if (group_block != fs->super->s_first_data_block &&
57 ((ret_blk + fs->super->s_blocks_per_group) <
58 fs->super->s_blocks_count))
59 ret_blk += fs->super->s_blocks_per_group;
60 return ret_blk;
61}
62
63errcode_t ext2fs_open(const char *name, int flags, int superblock,
64 unsigned int block_size, io_manager manager,
65 ext2_filsys *ret_fs)
66{
67 return ext2fs_open2(name, 0, flags, superblock, block_size,
68 manager, ret_fs);
69}
70
71/*
72 * Note: if superblock is non-zero, block-size must also be non-zero.
73 * Superblock and block_size can be zero to use the default size.
74 *
75 * Valid flags for ext2fs_open()
76 *
77 * EXT2_FLAG_RW - Open the filesystem for read/write.
78 * EXT2_FLAG_FORCE - Open the filesystem even if some of the
79 * features aren't supported.
80 * EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
81 */
82errcode_t ext2fs_open2(const char *name, const char *io_options,
83 int flags, int superblock,
84 unsigned int block_size, io_manager manager,
85 ext2_filsys *ret_fs)
86{
87 ext2_filsys fs;
88 errcode_t retval;
89 unsigned long i;
90 int groups_per_block, blocks_per_group;
91 blk_t group_block, blk;
92 char *dest, *cp;
93#if BB_BIG_ENDIAN
94 int j;
95 struct ext2_group_desc *gdp;
96#endif
97
98 EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
99
100 retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
101 if (retval)
102 return retval;
103
104 memset(fs, 0, sizeof(struct struct_ext2_filsys));
105 fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
106 fs->flags = flags;
107 fs->umask = 022;
108 retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
109 if (retval)
110 goto cleanup;
111 strcpy(fs->device_name, name);
112 cp = strchr(fs->device_name, '?');
113 if (!io_options && cp) {
114 *cp++ = 0;
115 io_options = cp;
116 }
117
118 retval = manager->open(fs->device_name,
119 (flags & EXT2_FLAG_RW) ? IO_FLAG_RW : 0,
120 &fs->io);
121 if (retval)
122 goto cleanup;
123 if (io_options &&
124 (retval = io_channel_set_options(fs->io, io_options)))
125 goto cleanup;
126 fs->image_io = fs->io;
127 fs->io->app_data = fs;
128 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
129 if (retval)
130 goto cleanup;
131 if (flags & EXT2_FLAG_IMAGE_FILE) {
132 retval = ext2fs_get_mem(sizeof(struct ext2_image_hdr),
133 &fs->image_header);
134 if (retval)
135 goto cleanup;
136 retval = io_channel_read_blk(fs->io, 0,
137 -(int)sizeof(struct ext2_image_hdr),
138 fs->image_header);
139 if (retval)
140 goto cleanup;
141 if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
142 return EXT2_ET_MAGIC_E2IMAGE;
143 superblock = 1;
144 block_size = fs->image_header->fs_blocksize;
145 }
146
147 /*
148 * If the user specifies a specific block # for the
149 * superblock, then he/she must also specify the block size!
150 * Otherwise, read the master superblock located at offset
151 * SUPERBLOCK_OFFSET from the start of the partition.
152 *
153 * Note: we only save a backup copy of the superblock if we
154 * are reading the superblock from the primary superblock location.
155 */
156 if (superblock) {
157 if (!block_size) {
158 retval = EXT2_ET_INVALID_ARGUMENT;
159 goto cleanup;
160 }
161 io_channel_set_blksize(fs->io, block_size);
162 group_block = superblock;
163 fs->orig_super = 0;
164 } else {
165 io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
166 superblock = 1;
167 group_block = 0;
168 retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
169 if (retval)
170 goto cleanup;
171 }
172 retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
173 fs->super);
174 if (retval)
175 goto cleanup;
176 if (fs->orig_super)
177 memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);
178
179#if BB_BIG_ENDIAN
180 if ((fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) ||
181 (fs->flags & EXT2_FLAG_SWAP_BYTES)) {
182 fs->flags |= EXT2_FLAG_SWAP_BYTES;
183
184 ext2fs_swap_super(fs->super);
185 }
186#endif
187
188 if (fs->super->s_magic != EXT2_SUPER_MAGIC) {
189 retval = EXT2_ET_BAD_MAGIC;
190 goto cleanup;
191 }
192 if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
193 retval = EXT2_ET_REV_TOO_HIGH;
194 goto cleanup;
195 }
196
197 /*
198 * Check for feature set incompatibility
199 */
200 if (!(flags & EXT2_FLAG_FORCE)) {
201 if (fs->super->s_feature_incompat &
202 ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
203 retval = EXT2_ET_UNSUPP_FEATURE;
204 goto cleanup;
205 }
206 if ((flags & EXT2_FLAG_RW) &&
207 (fs->super->s_feature_ro_compat &
208 ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
209 retval = EXT2_ET_RO_UNSUPP_FEATURE;
210 goto cleanup;
211 }
212 if (!(flags & EXT2_FLAG_JOURNAL_DEV_OK) &&
213 (fs->super->s_feature_incompat &
214 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
215 retval = EXT2_ET_UNSUPP_FEATURE;
216 goto cleanup;
217 }
218 }
219
220 fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
221 if (fs->blocksize == 0) {
222 retval = EXT2_ET_CORRUPT_SUPERBLOCK;
223 goto cleanup;
224 }
225 fs->fragsize = EXT2_FRAG_SIZE(fs->super);
226 fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
227 EXT2_INODE_SIZE(fs->super) +
228 EXT2_BLOCK_SIZE(fs->super) - 1) /
229 EXT2_BLOCK_SIZE(fs->super));
230 if (block_size) {
231 if (block_size != fs->blocksize) {
232 retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
233 goto cleanup;
234 }
235 }
236 /*
237 * Set the blocksize to the filesystem's blocksize.
238 */
239 io_channel_set_blksize(fs->io, fs->blocksize);
240
241 /*
242 * If this is an external journal device, don't try to read
243 * the group descriptors, because they're not there.
244 */
245 if (fs->super->s_feature_incompat &
246 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
247 fs->group_desc_count = 0;
248 *ret_fs = fs;
249 return 0;
250 }
251
252 /*
253 * Read group descriptors
254 */
255 blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
256 if (blocks_per_group == 0 ||
257 blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
258 fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
259 retval = EXT2_ET_CORRUPT_SUPERBLOCK;
260 goto cleanup;
261 }
262 fs->group_desc_count = (fs->super->s_blocks_count -
263 fs->super->s_first_data_block +
264 blocks_per_group - 1) / blocks_per_group;
265 fs->desc_blocks = (fs->group_desc_count +
266 EXT2_DESC_PER_BLOCK(fs->super) - 1)
267 / EXT2_DESC_PER_BLOCK(fs->super);
268 retval = ext2fs_get_mem(fs->desc_blocks * fs->blocksize,
269 &fs->group_desc);
270 if (retval)
271 goto cleanup;
272 if (!group_block)
273 group_block = fs->super->s_first_data_block;
274 dest = (char *) fs->group_desc;
275 groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
276 for (i=0 ; i < fs->desc_blocks; i++) {
277 blk = ext2fs_descriptor_block_loc(fs, group_block, i);
278 retval = io_channel_read_blk(fs->io, blk, 1, dest);
279 if (retval)
280 goto cleanup;
281#if BB_BIG_ENDIAN
282 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
283 gdp = (struct ext2_group_desc *) dest;
284 for (j=0; j < groups_per_block; j++)
285 ext2fs_swap_group_desc(gdp++);
286 }
287#endif
288 dest += fs->blocksize;
289 }
290
291 *ret_fs = fs;
292 return 0;
293cleanup:
294 ext2fs_free(fs);
295 return retval;
296}
297
298/*
299 * Set/get the filesystem data I/O channel.
300 *
301 * These functions are only valid if EXT2_FLAG_IMAGE_FILE is true.
302 */
303errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io)
304{
305 if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
306 return EXT2_ET_NOT_IMAGE_FILE;
307 if (old_io) {
308 *old_io = (fs->image_io == fs->io) ? 0 : fs->io;
309 }
310 return 0;
311}
312
313errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io)
314{
315 if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
316 return EXT2_ET_NOT_IMAGE_FILE;
317 fs->io = new_io ? new_io : fs->image_io;
318 return 0;
319}
320
321errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io)
322{
323 if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
324 return EXT2_ET_NOT_IMAGE_FILE;
325 fs->io = fs->image_io = new_io;
326 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_RW |
327 EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
328 fs->flags &= ~EXT2_FLAG_IMAGE_FILE;
329 return 0;
330}
diff --git a/e2fsprogs/ext2fs/read_bb.c b/e2fsprogs/ext2fs/read_bb.c
deleted file mode 100644
index 4766157c2..000000000
--- a/e2fsprogs/ext2fs/read_bb.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * read_bb --- read the bad blocks inode
4 *
5 * Copyright (C) 1994 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30struct read_bb_record {
31 ext2_badblocks_list bb_list;
32 errcode_t err;
33};
34
35/*
36 * Helper function for ext2fs_read_bb_inode()
37 */
38#ifdef __TURBOC__
39# pragma argsused
40#endif
41static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
42 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
43 blk_t ref_block EXT2FS_ATTR((unused)),
44 int ref_offset EXT2FS_ATTR((unused)),
45 void *priv_data)
46{
47 struct read_bb_record *rb = (struct read_bb_record *) priv_data;
48
49 if (blockcnt < 0)
50 return 0;
51
52 if ((*block_nr < fs->super->s_first_data_block) ||
53 (*block_nr >= fs->super->s_blocks_count))
54 return 0; /* Ignore illegal blocks */
55
56 rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
57 if (rb->err)
58 return BLOCK_ABORT;
59 return 0;
60}
61
62/*
63 * Reads the current bad blocks from the bad blocks inode.
64 */
65errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
66{
67 errcode_t retval;
68 struct read_bb_record rb;
69 struct ext2_inode inode;
70 blk_t numblocks;
71
72 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
73
74 if (!*bb_list) {
75 retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
76 if (retval)
77 return retval;
78 if (inode.i_blocks < 500)
79 numblocks = (inode.i_blocks /
80 (fs->blocksize / 512)) + 20;
81 else
82 numblocks = 500;
83 retval = ext2fs_badblocks_list_create(bb_list, numblocks);
84 if (retval)
85 return retval;
86 }
87
88 rb.bb_list = *bb_list;
89 rb.err = 0;
90 retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, 0, 0,
91 mark_bad_block, &rb);
92 if (retval)
93 return retval;
94
95 return rb.err;
96}
97
98
diff --git a/e2fsprogs/ext2fs/read_bb_file.c b/e2fsprogs/ext2fs/read_bb_file.c
deleted file mode 100644
index 831adcc3a..000000000
--- a/e2fsprogs/ext2fs/read_bb_file.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * read_bb_file.c --- read a list of bad blocks from a FILE *
4 *
5 * Copyright (C) 1994, 1995, 2000 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30/*
31 * Reads a list of bad blocks from a FILE *
32 */
33errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
34 ext2_badblocks_list *bb_list,
35 void *priv_data,
36 void (*invalid)(ext2_filsys fs,
37 blk_t blk,
38 char *badstr,
39 void *priv_data))
40{
41 errcode_t retval;
42 blk_t blockno;
43 int count;
44 char buf[128];
45
46 if (fs)
47 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
48
49 if (!*bb_list) {
50 retval = ext2fs_badblocks_list_create(bb_list, 10);
51 if (retval)
52 return retval;
53 }
54
55 while (!feof (f)) {
56 if (fgets(buf, sizeof(buf), f) == NULL)
57 break;
58 count = sscanf(buf, "%u", &blockno);
59 if (count <= 0)
60 continue;
61 if (fs &&
62 ((blockno < fs->super->s_first_data_block) ||
63 (blockno >= fs->super->s_blocks_count))) {
64 if (invalid)
65 (invalid)(fs, blockno, buf, priv_data);
66 continue;
67 }
68 retval = ext2fs_badblocks_list_add(*bb_list, blockno);
69 if (retval)
70 return retval;
71 }
72 return 0;
73}
74
75static void call_compat_invalid(ext2_filsys fs, blk_t blk,
76 char *badstr EXT2FS_ATTR((unused)),
77 void *priv_data)
78{
79 void (*invalid)(ext2_filsys, blk_t);
80
81 invalid = (void (*)(ext2_filsys, blk_t)) priv_data;
82 if (invalid)
83 invalid(fs, blk);
84}
85
86
87/*
88 * Reads a list of bad blocks from a FILE *
89 */
90errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
91 ext2_badblocks_list *bb_list,
92 void (*invalid)(ext2_filsys fs, blk_t blk))
93{
94 return ext2fs_read_bb_FILE2(fs, f, bb_list, (void *) invalid,
95 call_compat_invalid);
96}
97
98
diff --git a/e2fsprogs/ext2fs/res_gdt.c b/e2fsprogs/ext2fs/res_gdt.c
deleted file mode 100644
index f7ee8b1fb..000000000
--- a/e2fsprogs/ext2fs/res_gdt.c
+++ /dev/null
@@ -1,221 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * res_gdt.c --- reserve blocks for growing the group descriptor table
4 * during online resizing.
5 *
6 * Copyright (C) 2002 Andreas Dilger
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15#include <string.h>
16#include <time.h>
17#include "ext2_fs.h"
18#include "ext2fs.h"
19
20/*
21 * Iterate through the groups which hold BACKUP superblock/GDT copies in an
22 * ext3 filesystem. The counters should be initialized to 1, 5, and 7 before
23 * calling this for the first time. In a sparse filesystem it will be the
24 * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
25 * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
26 */
27static unsigned int list_backups(ext2_filsys fs, unsigned int *three,
28 unsigned int *five, unsigned int *seven)
29{
30 unsigned int *min = three;
31 int mult = 3;
32 unsigned int ret;
33
34 if (!(fs->super->s_feature_ro_compat &
35 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
36 ret = *min;
37 *min += 1;
38 return ret;
39 }
40
41 if (*five < *min) {
42 min = five;
43 mult = 5;
44 }
45 if (*seven < *min) {
46 min = seven;
47 mult = 7;
48 }
49
50 ret = *min;
51 *min *= mult;
52
53 return ret;
54}
55
56/*
57 * This code assumes that the reserved blocks have already been marked in-use
58 * during ext2fs_initialize(), so that they are not allocated for other
59 * uses before we can add them to the resize inode (which has to come
60 * after the creation of the inode table).
61 */
62errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
63{
64 errcode_t retval, retval2;
65 struct ext2_super_block *sb;
66 struct ext2_inode inode;
67 __u32 *dindir_buf, *gdt_buf;
68 int rsv_add;
69 unsigned long long apb, inode_size;
70 blk_t dindir_blk, rsv_off, gdt_off, gdt_blk;
71 int dindir_dirty = 0, inode_dirty = 0;
72
73 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
74
75 sb = fs->super;
76
77 retval = ext2fs_get_mem(2 * fs->blocksize, (void *)&dindir_buf);
78 if (retval)
79 goto out_free;
80 gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
81
82 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
83 if (retval)
84 goto out_free;
85
86 /* Maximum possible file size (we donly use the dindirect blocks) */
87 apb = EXT2_ADDR_PER_BLOCK(sb);
88 rsv_add = fs->blocksize / 512;
89 if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
90#ifdef RES_GDT_DEBUG
91 printf("reading GDT dindir %u\n", dindir_blk);
92#endif
93 retval = ext2fs_read_ind_block(fs, dindir_blk, dindir_buf);
94 if (retval)
95 goto out_inode;
96 } else {
97 blk_t goal = 3 + sb->s_reserved_gdt_blocks +
98 fs->desc_blocks + fs->inode_blocks_per_group;
99
100 retval = ext2fs_alloc_block(fs, goal, 0, &dindir_blk);
101 if (retval)
102 goto out_free;
103 inode.i_mode = LINUX_S_IFREG | 0600;
104 inode.i_links_count = 1;
105 inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
106 inode.i_blocks = rsv_add;
107 memset(dindir_buf, 0, fs->blocksize);
108#ifdef RES_GDT_DEBUG
109 printf("allocated GDT dindir %u\n", dindir_blk);
110#endif
111 dindir_dirty = inode_dirty = 1;
112 inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
113 inode_size *= fs->blocksize;
114 inode.i_size = inode_size & 0xFFFFFFFF;
115 inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
116 if(inode.i_size_high) {
117 sb->s_feature_ro_compat |=
118 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
119 }
120 inode.i_ctime = time(0);
121 }
122
123 for (rsv_off = 0, gdt_off = fs->desc_blocks,
124 gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks;
125 rsv_off < sb->s_reserved_gdt_blocks;
126 rsv_off++, gdt_off++, gdt_blk++) {
127 unsigned int three = 1, five = 5, seven = 7;
128 unsigned int grp, last = 0;
129 int gdt_dirty = 0;
130
131 gdt_off %= apb;
132 if (!dindir_buf[gdt_off]) {
133 /* FIXME XXX XXX
134 blk_t new_blk;
135
136 retval = ext2fs_new_block(fs, gdt_blk, 0, &new_blk);
137 if (retval)
138 goto out_free;
139 if (new_blk != gdt_blk) {
140 // XXX free block
141 retval = -1; // XXX
142 }
143 */
144 gdt_dirty = dindir_dirty = inode_dirty = 1;
145 memset(gdt_buf, 0, fs->blocksize);
146 dindir_buf[gdt_off] = gdt_blk;
147 inode.i_blocks += rsv_add;
148#ifdef RES_GDT_DEBUG
149 printf("added primary GDT block %u at %u[%u]\n",
150 gdt_blk, dindir_blk, gdt_off);
151#endif
152 } else if (dindir_buf[gdt_off] == gdt_blk) {
153#ifdef RES_GDT_DEBUG
154 printf("reading primary GDT block %u\n", gdt_blk);
155#endif
156 retval = ext2fs_read_ind_block(fs, gdt_blk, gdt_buf);
157 if (retval)
158 goto out_dindir;
159 } else {
160#ifdef RES_GDT_DEBUG
161 printf("bad primary GDT %u != %u at %u[%u]\n",
162 dindir_buf[gdt_off], gdt_blk,dindir_blk,gdt_off);
163#endif
164 retval = EXT2_ET_RESIZE_INODE_CORRUPT;
165 goto out_dindir;
166 }
167
168 while ((grp = list_backups(fs, &three, &five, &seven)) <
169 fs->group_desc_count) {
170 blk_t expect = gdt_blk + grp * sb->s_blocks_per_group;
171
172 if (!gdt_buf[last]) {
173#ifdef RES_GDT_DEBUG
174 printf("added backup GDT %u grp %u@%u[%u]\n",
175 expect, grp, gdt_blk, last);
176#endif
177 gdt_buf[last] = expect;
178 inode.i_blocks += rsv_add;
179 gdt_dirty = inode_dirty = 1;
180 } else if (gdt_buf[last] != expect) {
181#ifdef RES_GDT_DEBUG
182 printf("bad backup GDT %u != %u at %u[%u]\n",
183 gdt_buf[last], expect, gdt_blk, last);
184#endif
185 retval = EXT2_ET_RESIZE_INODE_CORRUPT;
186 goto out_dindir;
187 }
188 last++;
189 }
190 if (gdt_dirty) {
191#ifdef RES_GDT_DEBUG
192 printf("writing primary GDT block %u\n", gdt_blk);
193#endif
194 retval = ext2fs_write_ind_block(fs, gdt_blk, gdt_buf);
195 if (retval)
196 goto out_dindir;
197 }
198 }
199
200out_dindir:
201 if (dindir_dirty) {
202 retval2 = ext2fs_write_ind_block(fs, dindir_blk, dindir_buf);
203 if (!retval)
204 retval = retval2;
205 }
206out_inode:
207#ifdef RES_GDT_DEBUG
208 printf("inode.i_blocks = %u, i_size = %u\n", inode.i_blocks,
209 inode.i_size);
210#endif
211 if (inode_dirty) {
212 inode.i_atime = inode.i_mtime = time(0);
213 retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
214 if (!retval)
215 retval = retval2;
216 }
217out_free:
218 ext2fs_free_mem((void *)&dindir_buf);
219 return retval;
220}
221
diff --git a/e2fsprogs/ext2fs/rs_bitmap.c b/e2fsprogs/ext2fs/rs_bitmap.c
deleted file mode 100644
index e932b3c9d..000000000
--- a/e2fsprogs/ext2fs/rs_bitmap.c
+++ /dev/null
@@ -1,107 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * rs_bitmap.c --- routine for changing the size of a bitmap
4 *
5 * Copyright (C) 1996, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#ifdef HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#ifdef HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30errcode_t ext2fs_resize_generic_bitmap(__u32 new_end, __u32 new_real_end,
31 ext2fs_generic_bitmap bmap)
32{
33 errcode_t retval;
34 size_t size, new_size;
35 __u32 bitno;
36
37 if (!bmap)
38 return EXT2_ET_INVALID_ARGUMENT;
39
40 EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_GENERIC_BITMAP);
41
42 /*
43 * If we're expanding the bitmap, make sure all of the new
44 * parts of the bitmap are zero.
45 */
46 if (new_end > bmap->end) {
47 bitno = bmap->real_end;
48 if (bitno > new_end)
49 bitno = new_end;
50 for (; bitno > bmap->end; bitno--)
51 ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
52 }
53 if (new_real_end == bmap->real_end) {
54 bmap->end = new_end;
55 return 0;
56 }
57
58 size = ((bmap->real_end - bmap->start) / 8) + 1;
59 new_size = ((new_real_end - bmap->start) / 8) + 1;
60
61 if (size != new_size) {
62 retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
63 if (retval)
64 return retval;
65 }
66 if (new_size > size)
67 memset(bmap->bitmap + size, 0, new_size - size);
68
69 bmap->end = new_end;
70 bmap->real_end = new_real_end;
71 return 0;
72}
73
74errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
75 ext2fs_inode_bitmap bmap)
76{
77 errcode_t retval;
78
79 if (!bmap)
80 return EXT2_ET_INVALID_ARGUMENT;
81
82 EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_INODE_BITMAP);
83
84 bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
85 retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
86 bmap);
87 bmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
88 return retval;
89}
90
91errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
92 ext2fs_block_bitmap bmap)
93{
94 errcode_t retval;
95
96 if (!bmap)
97 return EXT2_ET_INVALID_ARGUMENT;
98
99 EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
100
101 bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
102 retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
103 bmap);
104 bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
105 return retval;
106}
107
diff --git a/e2fsprogs/ext2fs/rw_bitmaps.c b/e2fsprogs/ext2fs/rw_bitmaps.c
deleted file mode 100644
index a5782db95..000000000
--- a/e2fsprogs/ext2fs/rw_bitmaps.c
+++ /dev/null
@@ -1,296 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * rw_bitmaps.c --- routines to read and write the inode and block bitmaps.
4 *
5 * Copyright (C) 1993, 1994, 1994, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#ifdef HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#ifdef HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29#include "e2image.h"
30
31#if defined(__powerpc__) && BB_BIG_ENDIAN
32/*
33 * On the PowerPC, the big-endian variant of the ext2 filesystem
34 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
35 * of each word. Thus a bitmap with only bit 0 set would be, as
36 * a string of bytes, 00 00 00 01 00 ...
37 * To cope with this, we byte-reverse each word of a bitmap if
38 * we have a big-endian filesystem, that is, if we are *not*
39 * byte-swapping other word-sized numbers.
40 */
41#define EXT2_BIG_ENDIAN_BITMAPS
42#endif
43
44#ifdef EXT2_BIG_ENDIAN_BITMAPS
45static void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
46{
47 __u32 *p = (__u32 *) bitmap;
48 int n;
49
50 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
51 *p = ext2fs_swab32(*p);
52}
53#endif
54
55errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
56{
57 dgrp_t i;
58 size_t nbytes;
59 errcode_t retval;
60 char * inode_bitmap = fs->inode_map->bitmap;
61 char * bitmap_block = NULL;
62 blk_t blk;
63
64 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
65
66 if (!(fs->flags & EXT2_FLAG_RW))
67 return EXT2_ET_RO_FILSYS;
68 if (!inode_bitmap)
69 return 0;
70 nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
71
72 retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
73 if (retval)
74 return retval;
75 memset(bitmap_block, 0xff, fs->blocksize);
76 for (i = 0; i < fs->group_desc_count; i++) {
77 memcpy(bitmap_block, inode_bitmap, nbytes);
78 blk = fs->group_desc[i].bg_inode_bitmap;
79 if (blk) {
80#ifdef EXT2_BIG_ENDIAN_BITMAPS
81 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
82 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
83 ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
84#endif
85 retval = io_channel_write_blk(fs->io, blk, 1,
86 bitmap_block);
87 if (retval)
88 return EXT2_ET_INODE_BITMAP_WRITE;
89 }
90 inode_bitmap += nbytes;
91 }
92 fs->flags &= ~EXT2_FLAG_IB_DIRTY;
93 ext2fs_free_mem(&bitmap_block);
94 return 0;
95}
96
97errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
98{
99 dgrp_t i;
100 unsigned int j;
101 int nbytes;
102 unsigned int nbits;
103 errcode_t retval;
104 char * block_bitmap = fs->block_map->bitmap;
105 char * bitmap_block = NULL;
106 blk_t blk;
107
108 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
109
110 if (!(fs->flags & EXT2_FLAG_RW))
111 return EXT2_ET_RO_FILSYS;
112 if (!block_bitmap)
113 return 0;
114 nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
115 retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
116 if (retval)
117 return retval;
118 memset(bitmap_block, 0xff, fs->blocksize);
119 for (i = 0; i < fs->group_desc_count; i++) {
120 memcpy(bitmap_block, block_bitmap, nbytes);
121 if (i == fs->group_desc_count - 1) {
122 /* Force bitmap padding for the last group */
123 nbits = ((fs->super->s_blocks_count
124 - fs->super->s_first_data_block)
125 % EXT2_BLOCKS_PER_GROUP(fs->super));
126 if (nbits)
127 for (j = nbits; j < fs->blocksize * 8; j++)
128 ext2fs_set_bit(j, bitmap_block);
129 }
130 blk = fs->group_desc[i].bg_block_bitmap;
131 if (blk) {
132#ifdef EXT2_BIG_ENDIAN_BITMAPS
133 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
134 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
135 ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
136#endif
137 retval = io_channel_write_blk(fs->io, blk, 1,
138 bitmap_block);
139 if (retval)
140 return EXT2_ET_BLOCK_BITMAP_WRITE;
141 }
142 block_bitmap += nbytes;
143 }
144 fs->flags &= ~EXT2_FLAG_BB_DIRTY;
145 ext2fs_free_mem(&bitmap_block);
146 return 0;
147}
148
149static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
150{
151 dgrp_t i;
152 char *block_bitmap = 0, *inode_bitmap = 0;
153 char *buf;
154 errcode_t retval;
155 int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
156 int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
157 blk_t blk;
158
159 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
160
161 fs->write_bitmaps = ext2fs_write_bitmaps;
162
163 retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
164 if (retval)
165 return retval;
166 if (do_block) {
167 ext2fs_free_block_bitmap(fs->block_map);
168 sprintf(buf, "block bitmap for %s", fs->device_name);
169 retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
170 if (retval)
171 goto cleanup;
172 block_bitmap = fs->block_map->bitmap;
173 }
174 if (do_inode) {
175 ext2fs_free_inode_bitmap(fs->inode_map);
176 sprintf(buf, "inode bitmap for %s", fs->device_name);
177 retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
178 if (retval)
179 goto cleanup;
180 inode_bitmap = fs->inode_map->bitmap;
181 }
182 ext2fs_free_mem(&buf);
183
184 if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
185 if (inode_bitmap) {
186 blk = (fs->image_header->offset_inodemap /
187 fs->blocksize);
188 retval = io_channel_read_blk(fs->image_io, blk,
189 -(inode_nbytes * fs->group_desc_count),
190 inode_bitmap);
191 if (retval)
192 goto cleanup;
193 }
194 if (block_bitmap) {
195 blk = (fs->image_header->offset_blockmap /
196 fs->blocksize);
197 retval = io_channel_read_blk(fs->image_io, blk,
198 -(block_nbytes * fs->group_desc_count),
199 block_bitmap);
200 if (retval)
201 goto cleanup;
202 }
203 return 0;
204 }
205
206 for (i = 0; i < fs->group_desc_count; i++) {
207 if (block_bitmap) {
208 blk = fs->group_desc[i].bg_block_bitmap;
209 if (blk) {
210 retval = io_channel_read_blk(fs->io, blk,
211 -block_nbytes, block_bitmap);
212 if (retval) {
213 retval = EXT2_ET_BLOCK_BITMAP_READ;
214 goto cleanup;
215 }
216#ifdef EXT2_BIG_ENDIAN_BITMAPS
217 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
218 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
219 ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes);
220#endif
221 } else
222 memset(block_bitmap, 0, block_nbytes);
223 block_bitmap += block_nbytes;
224 }
225 if (inode_bitmap) {
226 blk = fs->group_desc[i].bg_inode_bitmap;
227 if (blk) {
228 retval = io_channel_read_blk(fs->io, blk,
229 -inode_nbytes, inode_bitmap);
230 if (retval) {
231 retval = EXT2_ET_INODE_BITMAP_READ;
232 goto cleanup;
233 }
234#ifdef EXT2_BIG_ENDIAN_BITMAPS
235 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
236 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
237 ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes);
238#endif
239 } else
240 memset(inode_bitmap, 0, inode_nbytes);
241 inode_bitmap += inode_nbytes;
242 }
243 }
244 return 0;
245
246cleanup:
247 if (do_block) {
248 ext2fs_free_mem(&fs->block_map);
249 }
250 if (do_inode) {
251 ext2fs_free_mem(&fs->inode_map);
252 }
253 ext2fs_free_mem(&buf);
254 return retval;
255}
256
257errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs)
258{
259 return read_bitmaps(fs, 1, 0);
260}
261
262errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
263{
264 return read_bitmaps(fs, 0, 1);
265}
266
267errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
268{
269
270 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
271
272 if (fs->inode_map && fs->block_map)
273 return 0;
274
275 return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
276}
277
278errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
279{
280 errcode_t retval;
281
282 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
283
284 if (fs->block_map && ext2fs_test_bb_dirty(fs)) {
285 retval = ext2fs_write_block_bitmap(fs);
286 if (retval)
287 return retval;
288 }
289 if (fs->inode_map && ext2fs_test_ib_dirty(fs)) {
290 retval = ext2fs_write_inode_bitmap(fs);
291 if (retval)
292 return retval;
293 }
294 return 0;
295}
296
diff --git a/e2fsprogs/ext2fs/sparse.c b/e2fsprogs/ext2fs/sparse.c
deleted file mode 100644
index b3d3071e9..000000000
--- a/e2fsprogs/ext2fs/sparse.c
+++ /dev/null
@@ -1,79 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * sparse.c --- find the groups in an ext2 filesystem with metadata backups
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6 * Copyright (C) 2002 Andreas Dilger.
7 *
8 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Public
10 * License.
11 * %End-Header%
12 */
13
14#include <stdio.h>
15
16#include "ext2_fs.h"
17#include "ext2fsP.h"
18
19static int test_root(int a, int b)
20{
21 if (a == 0)
22 return 1;
23 while (1) {
24 if (a == 1)
25 return 1;
26 if (a % b)
27 return 0;
28 a = a / b;
29 }
30}
31
32int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
33{
34 if (!(fs->super->s_feature_ro_compat &
35 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
36 return 1;
37
38 if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
39 test_root(group_block, 7))
40 return 1;
41
42 return 0;
43}
44
45/*
46 * Iterate through the groups which hold BACKUP superblock/GDT copies in an
47 * ext3 filesystem. The counters should be initialized to 1, 5, and 7 before
48 * calling this for the first time. In a sparse filesystem it will be the
49 * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
50 * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
51 */
52unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three,
53 unsigned int *five, unsigned int *seven)
54{
55 unsigned int *min = three;
56 int mult = 3;
57 unsigned int ret;
58
59 if (!(fs->super->s_feature_ro_compat &
60 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
61 ret = *min;
62 *min += 1;
63 return ret;
64 }
65
66 if (*five < *min) {
67 min = five;
68 mult = 5;
69 }
70 if (*seven < *min) {
71 min = seven;
72 mult = 7;
73 }
74
75 ret = *min;
76 *min *= mult;
77
78 return ret;
79}
diff --git a/e2fsprogs/ext2fs/swapfs.c b/e2fsprogs/ext2fs/swapfs.c
deleted file mode 100644
index 2fca3cfbb..000000000
--- a/e2fsprogs/ext2fs/swapfs.c
+++ /dev/null
@@ -1,236 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * swapfs.c --- swap ext2 filesystem data structures
4 *
5 * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <unistd.h>
15#include <string.h>
16#include <time.h>
17
18#include "ext2_fs.h"
19#include "ext2fs.h"
20#include "ext2_ext_attr.h"
21
22#if BB_BIG_ENDIAN
23void ext2fs_swap_super(struct ext2_super_block * sb)
24{
25 int i;
26 sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
27 sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
28 sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
29 sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
30 sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
31 sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
32 sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
33 sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
34 sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
35 sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
36 sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
37 sb->s_mtime = ext2fs_swab32(sb->s_mtime);
38 sb->s_wtime = ext2fs_swab32(sb->s_wtime);
39 sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
40 sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
41 sb->s_magic = ext2fs_swab16(sb->s_magic);
42 sb->s_state = ext2fs_swab16(sb->s_state);
43 sb->s_errors = ext2fs_swab16(sb->s_errors);
44 sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
45 sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
46 sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
47 sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
48 sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
49 sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
50 sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
51 sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
52 sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
53 sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
54 sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
55 sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
56 sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
57 sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
58 sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
59 sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
60 sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
61 sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
62 sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
63 sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
64 sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
65 for (i=0; i < 4; i++)
66 sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
67 for (i=0; i < 17; i++)
68 sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
69
70}
71
72void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
73{
74 gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
75 gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
76 gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
77 gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
78 gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
79 gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
80}
81
82void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
83{
84 struct ext2_ext_attr_header *from_header =
85 (struct ext2_ext_attr_header *)from;
86 struct ext2_ext_attr_header *to_header =
87 (struct ext2_ext_attr_header *)to;
88 struct ext2_ext_attr_entry *from_entry, *to_entry;
89 char *from_end = (char *)from_header + bufsize;
90 int n;
91
92 if (to_header != from_header)
93 memcpy(to_header, from_header, bufsize);
94
95 from_entry = (struct ext2_ext_attr_entry *)from_header;
96 to_entry = (struct ext2_ext_attr_entry *)to_header;
97
98 if (has_header) {
99 to_header->h_magic = ext2fs_swab32(from_header->h_magic);
100 to_header->h_blocks = ext2fs_swab32(from_header->h_blocks);
101 to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
102 for (n=0; n<4; n++)
103 to_header->h_reserved[n] =
104 ext2fs_swab32(from_header->h_reserved[n]);
105 from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
106 to_entry = (struct ext2_ext_attr_entry *)(to_header+1);
107 }
108
109 while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
110 to_entry->e_value_offs =
111 ext2fs_swab16(from_entry->e_value_offs);
112 to_entry->e_value_block =
113 ext2fs_swab32(from_entry->e_value_block);
114 to_entry->e_value_size =
115 ext2fs_swab32(from_entry->e_value_size);
116 from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
117 to_entry = EXT2_EXT_ATTR_NEXT(to_entry);
118 }
119}
120
121void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
122 struct ext2_inode_large *f, int hostorder,
123 int bufsize)
124{
125 unsigned i;
126 int islnk = 0;
127 __u32 *eaf, *eat;
128
129 if (hostorder && LINUX_S_ISLNK(f->i_mode))
130 islnk = 1;
131 t->i_mode = ext2fs_swab16(f->i_mode);
132 if (!hostorder && LINUX_S_ISLNK(t->i_mode))
133 islnk = 1;
134 t->i_uid = ext2fs_swab16(f->i_uid);
135 t->i_size = ext2fs_swab32(f->i_size);
136 t->i_atime = ext2fs_swab32(f->i_atime);
137 t->i_ctime = ext2fs_swab32(f->i_ctime);
138 t->i_mtime = ext2fs_swab32(f->i_mtime);
139 t->i_dtime = ext2fs_swab32(f->i_dtime);
140 t->i_gid = ext2fs_swab16(f->i_gid);
141 t->i_links_count = ext2fs_swab16(f->i_links_count);
142 t->i_blocks = ext2fs_swab32(f->i_blocks);
143 t->i_flags = ext2fs_swab32(f->i_flags);
144 t->i_file_acl = ext2fs_swab32(f->i_file_acl);
145 t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
146 if (!islnk || ext2fs_inode_data_blocks(fs, (struct ext2_inode *)t)) {
147 for (i = 0; i < EXT2_N_BLOCKS; i++)
148 t->i_block[i] = ext2fs_swab32(f->i_block[i]);
149 } else if (t != f) {
150 for (i = 0; i < EXT2_N_BLOCKS; i++)
151 t->i_block[i] = f->i_block[i];
152 }
153 t->i_generation = ext2fs_swab32(f->i_generation);
154 t->i_faddr = ext2fs_swab32(f->i_faddr);
155
156 switch (fs->super->s_creator_os) {
157 case EXT2_OS_LINUX:
158 t->osd1.linux1.l_i_reserved1 =
159 ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
160 t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
161 t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
162 t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
163 t->osd2.linux2.l_i_uid_high =
164 ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
165 t->osd2.linux2.l_i_gid_high =
166 ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
167 t->osd2.linux2.l_i_reserved2 =
168 ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
169 break;
170 case EXT2_OS_HURD:
171 t->osd1.hurd1.h_i_translator =
172 ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
173 t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
174 t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
175 t->osd2.hurd2.h_i_mode_high =
176 ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
177 t->osd2.hurd2.h_i_uid_high =
178 ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
179 t->osd2.hurd2.h_i_gid_high =
180 ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
181 t->osd2.hurd2.h_i_author =
182 ext2fs_swab32 (f->osd2.hurd2.h_i_author);
183 break;
184 case EXT2_OS_MASIX:
185 t->osd1.masix1.m_i_reserved1 =
186 ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
187 t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
188 t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
189 t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
190 t->osd2.masix2.m_i_reserved2[0] =
191 ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
192 t->osd2.masix2.m_i_reserved2[1] =
193 ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
194 break;
195 }
196
197 if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
198 return; /* no i_extra_isize field */
199
200 t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
201 if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) -
202 sizeof(struct ext2_inode)) {
203 /* this is error case: i_extra_size is too large */
204 return;
205 }
206
207 i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32);
208 if (bufsize < (int) i)
209 return; /* no space for EA magic */
210
211 eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
212 f->i_extra_isize);
213
214 if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC)
215 return; /* it seems no magic here */
216
217 eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
218 f->i_extra_isize);
219 *eat = ext2fs_swab32(*eaf);
220
221 /* convert EA(s) */
222 ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
223 bufsize - sizeof(struct ext2_inode) -
224 t->i_extra_isize - sizeof(__u32), 0);
225
226}
227
228void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
229 struct ext2_inode *f, int hostorder)
230{
231 ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t,
232 (struct ext2_inode_large *) f, hostorder,
233 sizeof(struct ext2_inode));
234}
235
236#endif
diff --git a/e2fsprogs/ext2fs/test_io.c b/e2fsprogs/ext2fs/test_io.c
deleted file mode 100644
index bd74225c0..000000000
--- a/e2fsprogs/ext2fs/test_io.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * test_io.c --- This is the Test I/O interface.
4 *
5 * Copyright (C) 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <fcntl.h>
19#include <time.h>
20#if HAVE_SYS_STAT_H
21#include <sys/stat.h>
22#endif
23#if HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif
26
27#include "ext2_fs.h"
28#include "ext2fs.h"
29
30/*
31 * For checking structure magic numbers...
32 */
33
34#define EXT2_CHECK_MAGIC(struct, code) \
35 if ((struct)->magic != (code)) return (code)
36
37struct test_private_data {
38 int magic;
39 io_channel real;
40 int flags;
41 FILE *outfile;
42 unsigned long block;
43 int read_abort_count, write_abort_count;
44 void (*read_blk)(unsigned long block, int count, errcode_t err);
45 void (*write_blk)(unsigned long block, int count, errcode_t err);
46 void (*set_blksize)(int blksize, errcode_t err);
47 void (*write_byte)(unsigned long block, int count, errcode_t err);
48};
49
50static errcode_t test_open(const char *name, int flags, io_channel *channel);
51static errcode_t test_close(io_channel channel);
52static errcode_t test_set_blksize(io_channel channel, int blksize);
53static errcode_t test_read_blk(io_channel channel, unsigned long block,
54 int count, void *data);
55static errcode_t test_write_blk(io_channel channel, unsigned long block,
56 int count, const void *data);
57static errcode_t test_flush(io_channel channel);
58static errcode_t test_write_byte(io_channel channel, unsigned long offset,
59 int count, const void *buf);
60static errcode_t test_set_option(io_channel channel, const char *option,
61 const char *arg);
62
63static struct struct_io_manager struct_test_manager = {
64 EXT2_ET_MAGIC_IO_MANAGER,
65 "Test I/O Manager",
66 test_open,
67 test_close,
68 test_set_blksize,
69 test_read_blk,
70 test_write_blk,
71 test_flush,
72 test_write_byte,
73 test_set_option
74};
75
76io_manager test_io_manager = &struct_test_manager;
77
78/*
79 * These global variable can be set by the test program as
80 * necessary *before* calling test_open
81 */
82io_manager test_io_backing_manager = 0;
83void (*test_io_cb_read_blk)
84 (unsigned long block, int count, errcode_t err) = 0;
85void (*test_io_cb_write_blk)
86 (unsigned long block, int count, errcode_t err) = 0;
87void (*test_io_cb_set_blksize)
88 (int blksize, errcode_t err) = 0;
89void (*test_io_cb_write_byte)
90 (unsigned long block, int count, errcode_t err) = 0;
91
92/*
93 * Test flags
94 */
95#define TEST_FLAG_READ 0x01
96#define TEST_FLAG_WRITE 0x02
97#define TEST_FLAG_SET_BLKSIZE 0x04
98#define TEST_FLAG_FLUSH 0x08
99#define TEST_FLAG_DUMP 0x10
100#define TEST_FLAG_SET_OPTION 0x20
101
102static void test_dump_block(io_channel channel,
103 struct test_private_data *data,
104 unsigned long block, const void *buf)
105{
106 const unsigned char *cp;
107 FILE *f = data->outfile;
108 int i;
109 unsigned long cksum = 0;
110
111 for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
112 cksum += *cp;
113 }
114 fprintf(f, "Contents of block %lu, checksum %08lu:\n", block, cksum);
115 for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
116 if ((i % 16) == 0)
117 fprintf(f, "%04x: ", i);
118 fprintf(f, "%02x%c", *cp, ((i % 16) == 15) ? '\n' : ' ');
119 }
120}
121
122static void test_abort(io_channel channel, unsigned long block)
123{
124 struct test_private_data *data;
125 FILE *f;
126
127 data = (struct test_private_data *) channel->private_data;
128 f = data->outfile;
129 test_flush(channel);
130
131 fprintf(f, "Aborting due to I/O to block %lu\n", block);
132 fflush(f);
133 abort();
134}
135
136static errcode_t test_open(const char *name, int flags, io_channel *channel)
137{
138 io_channel io = NULL;
139 struct test_private_data *data = NULL;
140 errcode_t retval;
141 char *value;
142
143 if (name == 0)
144 return EXT2_ET_BAD_DEVICE_NAME;
145 retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
146 if (retval)
147 return retval;
148 memset(io, 0, sizeof(struct struct_io_channel));
149 io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
150 retval = ext2fs_get_mem(sizeof(struct test_private_data), &data);
151 if (retval) {
152 retval = EXT2_ET_NO_MEMORY;
153 goto cleanup;
154 }
155 io->manager = test_io_manager;
156 retval = ext2fs_get_mem(strlen(name)+1, &io->name);
157 if (retval)
158 goto cleanup;
159
160 strcpy(io->name, name);
161 io->private_data = data;
162 io->block_size = 1024;
163 io->read_error = 0;
164 io->write_error = 0;
165 io->refcount = 1;
166
167 memset(data, 0, sizeof(struct test_private_data));
168 data->magic = EXT2_ET_MAGIC_TEST_IO_CHANNEL;
169 if (test_io_backing_manager) {
170 retval = test_io_backing_manager->open(name, flags,
171 &data->real);
172 if (retval)
173 goto cleanup;
174 } else
175 data->real = 0;
176 data->read_blk = test_io_cb_read_blk;
177 data->write_blk = test_io_cb_write_blk;
178 data->set_blksize = test_io_cb_set_blksize;
179 data->write_byte = test_io_cb_write_byte;
180
181 data->outfile = NULL;
182 if ((value = getenv("TEST_IO_LOGFILE")) != NULL)
183 data->outfile = fopen(value, "w");
184 if (!data->outfile)
185 data->outfile = stderr;
186
187 data->flags = 0;
188 if ((value = getenv("TEST_IO_FLAGS")) != NULL)
189 data->flags = strtoul(value, NULL, 0);
190
191 data->block = 0;
192 if ((value = getenv("TEST_IO_BLOCK")) != NULL)
193 data->block = strtoul(value, NULL, 0);
194
195 data->read_abort_count = 0;
196 if ((value = getenv("TEST_IO_READ_ABORT")) != NULL)
197 data->read_abort_count = strtoul(value, NULL, 0);
198
199 data->write_abort_count = 0;
200 if ((value = getenv("TEST_IO_WRITE_ABORT")) != NULL)
201 data->write_abort_count = strtoul(value, NULL, 0);
202
203 *channel = io;
204 return 0;
205
206cleanup:
207 ext2fs_free_mem(&io);
208 ext2fs_free_mem(&data);
209 return retval;
210}
211
212static errcode_t test_close(io_channel channel)
213{
214 struct test_private_data *data;
215 errcode_t retval = 0;
216
217 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
218 data = (struct test_private_data *) channel->private_data;
219 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
220
221 if (--channel->refcount > 0)
222 return 0;
223
224 if (data->real)
225 retval = io_channel_close(data->real);
226
227 if (data->outfile && data->outfile != stderr)
228 fclose(data->outfile);
229
230 ext2fs_free_mem(&channel->private_data);
231 ext2fs_free_mem(&channel->name);
232 ext2fs_free_mem(&channel);
233 return retval;
234}
235
236static errcode_t test_set_blksize(io_channel channel, int blksize)
237{
238 struct test_private_data *data;
239 errcode_t retval = 0;
240
241 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
242 data = (struct test_private_data *) channel->private_data;
243 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
244
245 if (data->real)
246 retval = io_channel_set_blksize(data->real, blksize);
247 if (data->set_blksize)
248 data->set_blksize(blksize, retval);
249 if (data->flags & TEST_FLAG_SET_BLKSIZE)
250 fprintf(data->outfile,
251 "Test_io: set_blksize(%d) returned %s\n",
252 blksize, retval ? error_message(retval) : "OK");
253 channel->block_size = blksize;
254 return retval;
255}
256
257
258static errcode_t test_read_blk(io_channel channel, unsigned long block,
259 int count, void *buf)
260{
261 struct test_private_data *data;
262 errcode_t retval = 0;
263
264 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
265 data = (struct test_private_data *) channel->private_data;
266 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
267
268 if (data->real)
269 retval = io_channel_read_blk(data->real, block, count, buf);
270 if (data->read_blk)
271 data->read_blk(block, count, retval);
272 if (data->flags & TEST_FLAG_READ)
273 fprintf(data->outfile,
274 "Test_io: read_blk(%lu, %d) returned %s\n",
275 block, count, retval ? error_message(retval) : "OK");
276 if (data->block && data->block == block) {
277 if (data->flags & TEST_FLAG_DUMP)
278 test_dump_block(channel, data, block, buf);
279 if (--data->read_abort_count == 0)
280 test_abort(channel, block);
281 }
282 return retval;
283}
284
285static errcode_t test_write_blk(io_channel channel, unsigned long block,
286 int count, const void *buf)
287{
288 struct test_private_data *data;
289 errcode_t retval = 0;
290
291 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
292 data = (struct test_private_data *) channel->private_data;
293 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
294
295 if (data->real)
296 retval = io_channel_write_blk(data->real, block, count, buf);
297 if (data->write_blk)
298 data->write_blk(block, count, retval);
299 if (data->flags & TEST_FLAG_WRITE)
300 fprintf(data->outfile,
301 "Test_io: write_blk(%lu, %d) returned %s\n",
302 block, count, retval ? error_message(retval) : "OK");
303 if (data->block && data->block == block) {
304 if (data->flags & TEST_FLAG_DUMP)
305 test_dump_block(channel, data, block, buf);
306 if (--data->write_abort_count == 0)
307 test_abort(channel, block);
308 }
309 return retval;
310}
311
312static errcode_t test_write_byte(io_channel channel, unsigned long offset,
313 int count, const void *buf)
314{
315 struct test_private_data *data;
316 errcode_t retval = 0;
317
318 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
319 data = (struct test_private_data *) channel->private_data;
320 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
321
322 if (data->real && data->real->manager->write_byte)
323 retval = io_channel_write_byte(data->real, offset, count, buf);
324 if (data->write_byte)
325 data->write_byte(offset, count, retval);
326 if (data->flags & TEST_FLAG_WRITE)
327 fprintf(data->outfile,
328 "Test_io: write_byte(%lu, %d) returned %s\n",
329 offset, count, retval ? error_message(retval) : "OK");
330 return retval;
331}
332
333/*
334 * Flush data buffers to disk.
335 */
336static errcode_t test_flush(io_channel channel)
337{
338 struct test_private_data *data;
339 errcode_t retval = 0;
340
341 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
342 data = (struct test_private_data *) channel->private_data;
343 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
344
345 if (data->real)
346 retval = io_channel_flush(data->real);
347
348 if (data->flags & TEST_FLAG_FLUSH)
349 fprintf(data->outfile, "Test_io: flush() returned %s\n",
350 retval ? error_message(retval) : "OK");
351
352 return retval;
353}
354
355static errcode_t test_set_option(io_channel channel, const char *option,
356 const char *arg)
357{
358 struct test_private_data *data;
359 errcode_t retval = 0;
360
361 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
362 data = (struct test_private_data *) channel->private_data;
363 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
364
365
366 if (data->flags & TEST_FLAG_SET_OPTION)
367 fprintf(data->outfile, "Test_io: set_option(%s, %s) ",
368 option, arg);
369 if (data->real && data->real->manager->set_option) {
370 retval = (data->real->manager->set_option)(data->real,
371 option, arg);
372 if (data->flags & TEST_FLAG_SET_OPTION)
373 fprintf(data->outfile, "returned %s\n",
374 retval ? error_message(retval) : "OK");
375 } else {
376 if (data->flags & TEST_FLAG_SET_OPTION)
377 fprintf(data->outfile, "not implemented\n");
378 }
379 return retval;
380}
diff --git a/e2fsprogs/ext2fs/unix_io.c b/e2fsprogs/ext2fs/unix_io.c
deleted file mode 100644
index 474f07340..000000000
--- a/e2fsprogs/ext2fs/unix_io.c
+++ /dev/null
@@ -1,703 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * unix_io.c --- This is the Unix (well, really POSIX) implementation
4 * of the I/O manager.
5 *
6 * Implements a one-block write-through cache.
7 *
8 * Includes support for Windows NT support under Cygwin.
9 *
10 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
11 * 2002 by Theodore Ts'o.
12 *
13 * %Begin-Header%
14 * This file may be redistributed under the terms of the GNU Public
15 * License.
16 * %End-Header%
17 */
18
19#include <stdio.h>
20#include <string.h>
21#if HAVE_UNISTD_H
22#include <unistd.h>
23#endif
24#if HAVE_ERRNO_H
25#include <errno.h>
26#endif
27#include <fcntl.h>
28#include <time.h>
29#ifdef __linux__
30#include <sys/utsname.h>
31#endif
32#if HAVE_SYS_STAT_H
33#include <sys/stat.h>
34#endif
35#if HAVE_SYS_TYPES_H
36#include <sys/types.h>
37#endif
38#include <sys/resource.h>
39
40#include "ext2_fs.h"
41#include "ext2fs.h"
42
43/*
44 * For checking structure magic numbers...
45 */
46
47#define EXT2_CHECK_MAGIC(struct, code) \
48 if ((struct)->magic != (code)) return (code)
49
50struct unix_cache {
51 char *buf;
52 unsigned long block;
53 int access_time;
54 unsigned dirty:1;
55 unsigned in_use:1;
56};
57
58#define CACHE_SIZE 8
59#define WRITE_DIRECT_SIZE 4 /* Must be smaller than CACHE_SIZE */
60#define READ_DIRECT_SIZE 4 /* Should be smaller than CACHE_SIZE */
61
62struct unix_private_data {
63 int magic;
64 int dev;
65 int flags;
66 int access_time;
67 ext2_loff_t offset;
68 struct unix_cache cache[CACHE_SIZE];
69};
70
71static errcode_t unix_open(const char *name, int flags, io_channel *channel);
72static errcode_t unix_close(io_channel channel);
73static errcode_t unix_set_blksize(io_channel channel, int blksize);
74static errcode_t unix_read_blk(io_channel channel, unsigned long block,
75 int count, void *data);
76static errcode_t unix_write_blk(io_channel channel, unsigned long block,
77 int count, const void *data);
78static errcode_t unix_flush(io_channel channel);
79static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
80 int size, const void *data);
81static errcode_t unix_set_option(io_channel channel, const char *option,
82 const char *arg);
83
84static void reuse_cache(io_channel channel, struct unix_private_data *data,
85 struct unix_cache *cache, unsigned long block);
86
87/* __FreeBSD_kernel__ is defined by GNU/kFreeBSD - the FreeBSD kernel
88 * does not know buffered block devices - everything is raw. */
89#if defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
90#define NEED_BOUNCE_BUFFER
91#else
92#undef NEED_BOUNCE_BUFFER
93#endif
94
95static struct struct_io_manager struct_unix_manager = {
96 EXT2_ET_MAGIC_IO_MANAGER,
97 "Unix I/O Manager",
98 unix_open,
99 unix_close,
100 unix_set_blksize,
101 unix_read_blk,
102 unix_write_blk,
103 unix_flush,
104#ifdef NEED_BOUNCE_BUFFER
105 0,
106#else
107 unix_write_byte,
108#endif
109 unix_set_option
110};
111
112io_manager unix_io_manager = &struct_unix_manager;
113
114/*
115 * Here are the raw I/O functions
116 */
117#ifndef NEED_BOUNCE_BUFFER
118static errcode_t raw_read_blk(io_channel channel,
119 struct unix_private_data *data,
120 unsigned long block,
121 int count, void *buf)
122{
123 errcode_t retval;
124 ssize_t size;
125 ext2_loff_t location;
126 int actual = 0;
127
128 size = (count < 0) ? -count : count * channel->block_size;
129 location = ((ext2_loff_t) block * channel->block_size) + data->offset;
130 if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
131 retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
132 goto error_out;
133 }
134 actual = read(data->dev, buf, size);
135 if (actual != size) {
136 if (actual < 0)
137 actual = 0;
138 retval = EXT2_ET_SHORT_READ;
139 goto error_out;
140 }
141 return 0;
142
143error_out:
144 memset((char *) buf+actual, 0, size-actual);
145 if (channel->read_error)
146 retval = (channel->read_error)(channel, block, count, buf,
147 size, actual, retval);
148 return retval;
149}
150#else /* NEED_BOUNCE_BUFFER */
151/*
152 * Windows and FreeBSD block devices only allow sector alignment IO in offset and size
153 */
154static errcode_t raw_read_blk(io_channel channel,
155 struct unix_private_data *data,
156 unsigned long block,
157 int count, void *buf)
158{
159 errcode_t retval;
160 size_t size, alignsize, fragment;
161 ext2_loff_t location;
162 int total = 0, actual;
163#define BLOCKALIGN 512
164 char sector[BLOCKALIGN];
165
166 size = (count < 0) ? -count : count * channel->block_size;
167 location = ((ext2_loff_t) block * channel->block_size) + data->offset;
168#ifdef DEBUG
169 printf("count=%d, size=%d, block=%d, blk_size=%d, location=%lx\n",
170 count, size, block, channel->block_size, location);
171#endif
172 if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
173 retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
174 goto error_out;
175 }
176 fragment = size % BLOCKALIGN;
177 alignsize = size - fragment;
178 if (alignsize) {
179 actual = read(data->dev, buf, alignsize);
180 if (actual != alignsize)
181 goto short_read;
182 }
183 if (fragment) {
184 actual = read(data->dev, sector, BLOCKALIGN);
185 if (actual != BLOCKALIGN)
186 goto short_read;
187 memcpy(buf+alignsize, sector, fragment);
188 }
189 return 0;
190
191short_read:
192 if (actual>0)
193 total += actual;
194 retval = EXT2_ET_SHORT_READ;
195
196error_out:
197 memset((char *) buf+total, 0, size-actual);
198 if (channel->read_error)
199 retval = (channel->read_error)(channel, block, count, buf,
200 size, actual, retval);
201 return retval;
202}
203#endif
204
205static errcode_t raw_write_blk(io_channel channel,
206 struct unix_private_data *data,
207 unsigned long block,
208 int count, const void *buf)
209{
210 ssize_t size;
211 ext2_loff_t location;
212 int actual = 0;
213 errcode_t retval;
214
215 if (count == 1)
216 size = channel->block_size;
217 else {
218 if (count < 0)
219 size = -count;
220 else
221 size = count * channel->block_size;
222 }
223
224 location = ((ext2_loff_t) block * channel->block_size) + data->offset;
225 if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
226 retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
227 goto error_out;
228 }
229
230 actual = write(data->dev, buf, size);
231 if (actual != size) {
232 retval = EXT2_ET_SHORT_WRITE;
233 goto error_out;
234 }
235 return 0;
236
237error_out:
238 if (channel->write_error)
239 retval = (channel->write_error)(channel, block, count, buf,
240 size, actual, retval);
241 return retval;
242}
243
244
245/*
246 * Here we implement the cache functions
247 */
248
249/* Allocate the cache buffers */
250static errcode_t alloc_cache(io_channel channel,
251 struct unix_private_data *data)
252{
253 errcode_t retval;
254 struct unix_cache *cache;
255 int i;
256
257 data->access_time = 0;
258 for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
259 cache->block = 0;
260 cache->access_time = 0;
261 cache->dirty = 0;
262 cache->in_use = 0;
263 if ((retval = ext2fs_get_mem(channel->block_size,
264 &cache->buf)))
265 return retval;
266 }
267 return 0;
268}
269
270/* Free the cache buffers */
271static void free_cache(struct unix_private_data *data)
272{
273 struct unix_cache *cache;
274 int i;
275
276 data->access_time = 0;
277 for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
278 cache->block = 0;
279 cache->access_time = 0;
280 cache->dirty = 0;
281 cache->in_use = 0;
282 ext2fs_free_mem(&cache->buf);
283 cache->buf = 0;
284 }
285}
286
287#ifndef NO_IO_CACHE
288/*
289 * Try to find a block in the cache. If the block is not found, and
290 * eldest is a non-zero pointer, then fill in eldest with the cache
291 * entry to that should be reused.
292 */
293static struct unix_cache *find_cached_block(struct unix_private_data *data,
294 unsigned long block,
295 struct unix_cache **eldest)
296{
297 struct unix_cache *cache, *unused_cache, *oldest_cache;
298 int i;
299
300 unused_cache = oldest_cache = 0;
301 for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
302 if (!cache->in_use) {
303 if (!unused_cache)
304 unused_cache = cache;
305 continue;
306 }
307 if (cache->block == block) {
308 cache->access_time = ++data->access_time;
309 return cache;
310 }
311 if (!oldest_cache ||
312 (cache->access_time < oldest_cache->access_time))
313 oldest_cache = cache;
314 }
315 if (eldest)
316 *eldest = (unused_cache) ? unused_cache : oldest_cache;
317 return 0;
318}
319
320/*
321 * Reuse a particular cache entry for another block.
322 */
323static void reuse_cache(io_channel channel, struct unix_private_data *data,
324 struct unix_cache *cache, unsigned long block)
325{
326 if (cache->dirty && cache->in_use)
327 raw_write_blk(channel, data, cache->block, 1, cache->buf);
328
329 cache->in_use = 1;
330 cache->dirty = 0;
331 cache->block = block;
332 cache->access_time = ++data->access_time;
333}
334
335/*
336 * Flush all of the blocks in the cache
337 */
338static errcode_t flush_cached_blocks(io_channel channel,
339 struct unix_private_data *data,
340 int invalidate)
341
342{
343 struct unix_cache *cache;
344 errcode_t retval, retval2;
345 int i;
346
347 retval2 = 0;
348 for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
349 if (!cache->in_use)
350 continue;
351
352 if (invalidate)
353 cache->in_use = 0;
354
355 if (!cache->dirty)
356 continue;
357
358 retval = raw_write_blk(channel, data,
359 cache->block, 1, cache->buf);
360 if (retval)
361 retval2 = retval;
362 else
363 cache->dirty = 0;
364 }
365 return retval2;
366}
367#endif /* NO_IO_CACHE */
368
369static errcode_t unix_open(const char *name, int flags, io_channel *channel)
370{
371 io_channel io = NULL;
372 struct unix_private_data *data = NULL;
373 errcode_t retval;
374 int open_flags;
375 struct stat st;
376#ifdef __linux__
377 struct utsname ut;
378#endif
379
380 if (name == 0)
381 return EXT2_ET_BAD_DEVICE_NAME;
382 retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
383 if (retval)
384 return retval;
385 memset(io, 0, sizeof(struct struct_io_channel));
386 io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
387 retval = ext2fs_get_mem(sizeof(struct unix_private_data), &data);
388 if (retval)
389 goto cleanup;
390
391 io->manager = unix_io_manager;
392 retval = ext2fs_get_mem(strlen(name)+1, &io->name);
393 if (retval)
394 goto cleanup;
395
396 strcpy(io->name, name);
397 io->private_data = data;
398 io->block_size = 1024;
399 io->read_error = 0;
400 io->write_error = 0;
401 io->refcount = 1;
402
403 memset(data, 0, sizeof(struct unix_private_data));
404 data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
405
406 if ((retval = alloc_cache(io, data)))
407 goto cleanup;
408
409 open_flags = (flags & IO_FLAG_RW) ? O_RDWR : O_RDONLY;
410#ifdef CONFIG_LFS
411 data->dev = open64(io->name, open_flags);
412#else
413 data->dev = open(io->name, open_flags);
414#endif
415 if (data->dev < 0) {
416 retval = errno;
417 goto cleanup;
418 }
419
420#ifdef __linux__
421#undef RLIM_INFINITY
422#if (defined(__alpha__) || ((defined(__sparc__) || defined(__mips__)) && (SIZEOF_LONG == 4)))
423#define RLIM_INFINITY ((unsigned long)(~0UL>>1))
424#else
425#define RLIM_INFINITY (~0UL)
426#endif
427 /*
428 * Work around a bug in 2.4.10-2.4.18 kernels where writes to
429 * block devices are wrongly getting hit by the filesize
430 * limit. This workaround isn't perfect, since it won't work
431 * if glibc wasn't built against 2.2 header files. (Sigh.)
432 *
433 */
434 if ((flags & IO_FLAG_RW) &&
435 (uname(&ut) == 0) &&
436 ((ut.release[0] == '2') && (ut.release[1] == '.') &&
437 (ut.release[2] == '4') && (ut.release[3] == '.') &&
438 (ut.release[4] == '1') && (ut.release[5] >= '0') &&
439 (ut.release[5] < '8')) &&
440 (fstat(data->dev, &st) == 0) &&
441 (S_ISBLK(st.st_mode))) {
442 struct rlimit rlim;
443
444 rlim.rlim_cur = rlim.rlim_max = (unsigned long) RLIM_INFINITY;
445 setrlimit(RLIMIT_FSIZE, &rlim);
446 getrlimit(RLIMIT_FSIZE, &rlim);
447 if (((unsigned long) rlim.rlim_cur) <
448 ((unsigned long) rlim.rlim_max)) {
449 rlim.rlim_cur = rlim.rlim_max;
450 setrlimit(RLIMIT_FSIZE, &rlim);
451 }
452 }
453#endif
454 *channel = io;
455 return 0;
456
457cleanup:
458 if (data) {
459 free_cache(data);
460 ext2fs_free_mem(&data);
461 }
462 ext2fs_free_mem(&io);
463 return retval;
464}
465
466static errcode_t unix_close(io_channel channel)
467{
468 struct unix_private_data *data;
469 errcode_t retval = 0;
470
471 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
472 data = (struct unix_private_data *) channel->private_data;
473 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
474
475 if (--channel->refcount > 0)
476 return 0;
477
478#ifndef NO_IO_CACHE
479 retval = flush_cached_blocks(channel, data, 0);
480#endif
481
482 if (close(data->dev) < 0)
483 retval = errno;
484 free_cache(data);
485
486 ext2fs_free_mem(&channel->private_data);
487 ext2fs_free_mem(&channel->name);
488 ext2fs_free_mem(&channel);
489 return retval;
490}
491
492static errcode_t unix_set_blksize(io_channel channel, int blksize)
493{
494 struct unix_private_data *data;
495 errcode_t retval;
496
497 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
498 data = (struct unix_private_data *) channel->private_data;
499 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
500
501 if (channel->block_size != blksize) {
502#ifndef NO_IO_CACHE
503 if ((retval = flush_cached_blocks(channel, data, 0)))
504 return retval;
505#endif
506
507 channel->block_size = blksize;
508 free_cache(data);
509 if ((retval = alloc_cache(channel, data)))
510 return retval;
511 }
512 return 0;
513}
514
515
516static errcode_t unix_read_blk(io_channel channel, unsigned long block,
517 int count, void *buf)
518{
519 struct unix_private_data *data;
520 struct unix_cache *cache, *reuse[READ_DIRECT_SIZE];
521 errcode_t retval;
522 char *cp;
523 int i, j;
524
525 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
526 data = (struct unix_private_data *) channel->private_data;
527 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
528
529#ifdef NO_IO_CACHE
530 return raw_read_blk(channel, data, block, count, buf);
531#else
532 /*
533 * If we're doing an odd-sized read or a very large read,
534 * flush out the cache and then do a direct read.
535 */
536 if (count < 0 || count > WRITE_DIRECT_SIZE) {
537 if ((retval = flush_cached_blocks(channel, data, 0)))
538 return retval;
539 return raw_read_blk(channel, data, block, count, buf);
540 }
541
542 cp = buf;
543 while (count > 0) {
544 /* If it's in the cache, use it! */
545 if ((cache = find_cached_block(data, block, &reuse[0]))) {
546#ifdef DEBUG
547 printf("Using cached block %d\n", block);
548#endif
549 memcpy(cp, cache->buf, channel->block_size);
550 count--;
551 block++;
552 cp += channel->block_size;
553 continue;
554 }
555 /*
556 * Find the number of uncached blocks so we can do a
557 * single read request
558 */
559 for (i=1; i < count; i++)
560 if (find_cached_block(data, block+i, &reuse[i]))
561 break;
562#ifdef DEBUG
563 printf("Reading %d blocks starting at %d\n", i, block);
564#endif
565 if ((retval = raw_read_blk(channel, data, block, i, cp)))
566 return retval;
567
568 /* Save the results in the cache */
569 for (j=0; j < i; j++) {
570 count--;
571 cache = reuse[j];
572 reuse_cache(channel, data, cache, block++);
573 memcpy(cache->buf, cp, channel->block_size);
574 cp += channel->block_size;
575 }
576 }
577 return 0;
578#endif /* NO_IO_CACHE */
579}
580
581static errcode_t unix_write_blk(io_channel channel, unsigned long block,
582 int count, const void *buf)
583{
584 struct unix_private_data *data;
585 struct unix_cache *cache, *reuse;
586 errcode_t retval = 0;
587 const char *cp;
588 int writethrough;
589
590 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
591 data = (struct unix_private_data *) channel->private_data;
592 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
593
594#ifdef NO_IO_CACHE
595 return raw_write_blk(channel, data, block, count, buf);
596#else
597 /*
598 * If we're doing an odd-sized write or a very large write,
599 * flush out the cache completely and then do a direct write.
600 */
601 if (count < 0 || count > WRITE_DIRECT_SIZE) {
602 if ((retval = flush_cached_blocks(channel, data, 1)))
603 return retval;
604 return raw_write_blk(channel, data, block, count, buf);
605 }
606
607 /*
608 * For a moderate-sized multi-block write, first force a write
609 * if we're in write-through cache mode, and then fill the
610 * cache with the blocks.
611 */
612 writethrough = channel->flags & CHANNEL_FLAGS_WRITETHROUGH;
613 if (writethrough)
614 retval = raw_write_blk(channel, data, block, count, buf);
615
616 cp = buf;
617 while (count > 0) {
618 cache = find_cached_block(data, block, &reuse);
619 if (!cache) {
620 cache = reuse;
621 reuse_cache(channel, data, cache, block);
622 }
623 memcpy(cache->buf, cp, channel->block_size);
624 cache->dirty = !writethrough;
625 count--;
626 block++;
627 cp += channel->block_size;
628 }
629 return retval;
630#endif /* NO_IO_CACHE */
631}
632
633static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
634 int size, const void *buf)
635{
636 struct unix_private_data *data;
637 errcode_t retval = 0;
638 ssize_t actual;
639
640 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
641 data = (struct unix_private_data *) channel->private_data;
642 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
643
644#ifndef NO_IO_CACHE
645 /*
646 * Flush out the cache completely
647 */
648 if ((retval = flush_cached_blocks(channel, data, 1)))
649 return retval;
650#endif
651
652 if (lseek(data->dev, offset + data->offset, SEEK_SET) < 0)
653 return errno;
654
655 actual = write(data->dev, buf, size);
656 if (actual != size)
657 return EXT2_ET_SHORT_WRITE;
658
659 return 0;
660}
661
662/*
663 * Flush data buffers to disk.
664 */
665static errcode_t unix_flush(io_channel channel)
666{
667 struct unix_private_data *data;
668 errcode_t retval = 0;
669
670 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
671 data = (struct unix_private_data *) channel->private_data;
672 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
673
674#ifndef NO_IO_CACHE
675 retval = flush_cached_blocks(channel, data, 0);
676#endif
677 fsync(data->dev);
678 return retval;
679}
680
681static errcode_t unix_set_option(io_channel channel, const char *option,
682 const char *arg)
683{
684 struct unix_private_data *data;
685 unsigned long tmp;
686 char *end;
687
688 EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
689 data = (struct unix_private_data *) channel->private_data;
690 EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
691
692 if (!strcmp(option, "offset")) {
693 if (!arg)
694 return EXT2_ET_INVALID_ARGUMENT;
695
696 tmp = strtoul(arg, &end, 0);
697 if (*end)
698 return EXT2_ET_INVALID_ARGUMENT;
699 data->offset = tmp;
700 return 0;
701 }
702 return EXT2_ET_INVALID_ARGUMENT;
703}
diff --git a/e2fsprogs/ext2fs/unlink.c b/e2fsprogs/ext2fs/unlink.c
deleted file mode 100644
index 83ac2713e..000000000
--- a/e2fsprogs/ext2fs/unlink.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * unlink.c --- delete links in a ext2fs directory
4 *
5 * Copyright (C) 1993, 1994, 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "ext2_fs.h"
20#include "ext2fs.h"
21
22struct link_struct {
23 const char *name;
24 int namelen;
25 ext2_ino_t inode;
26 int flags;
27 struct ext2_dir_entry *prev;
28 int done;
29};
30
31#ifdef __TURBOC__
32# pragma argsused
33#endif
34static int unlink_proc(struct ext2_dir_entry *dirent,
35 int offset EXT2FS_ATTR((unused)),
36 int blocksize EXT2FS_ATTR((unused)),
37 char *buf EXT2FS_ATTR((unused)),
38 void *priv_data)
39{
40 struct link_struct *ls = (struct link_struct *) priv_data;
41 struct ext2_dir_entry *prev;
42
43 prev = ls->prev;
44 ls->prev = dirent;
45
46 if (ls->name) {
47 if ((dirent->name_len & 0xFF) != ls->namelen)
48 return 0;
49 if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF))
50 return 0;
51 }
52 if (ls->inode) {
53 if (dirent->inode != ls->inode)
54 return 0;
55 } else {
56 if (!dirent->inode)
57 return 0;
58 }
59
60 if (prev)
61 prev->rec_len += dirent->rec_len;
62 else
63 dirent->inode = 0;
64 ls->done++;
65 return DIRENT_ABORT|DIRENT_CHANGED;
66}
67
68#ifdef __TURBOC__
69 #pragma argsused
70#endif
71errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
72 const char *name, ext2_ino_t ino,
73 int flags EXT2FS_ATTR((unused)))
74{
75 errcode_t retval;
76 struct link_struct ls;
77
78 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
79
80 if (!name && !ino)
81 return EXT2_ET_INVALID_ARGUMENT;
82
83 if (!(fs->flags & EXT2_FLAG_RW))
84 return EXT2_ET_RO_FILSYS;
85
86 ls.name = name;
87 ls.namelen = name ? strlen(name) : 0;
88 ls.inode = ino;
89 ls.flags = 0;
90 ls.done = 0;
91 ls.prev = 0;
92
93 retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
94 0, unlink_proc, &ls);
95 if (retval)
96 return retval;
97
98 return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
99}
100
diff --git a/e2fsprogs/ext2fs/valid_blk.c b/e2fsprogs/ext2fs/valid_blk.c
deleted file mode 100644
index 8ed77ae2a..000000000
--- a/e2fsprogs/ext2fs/valid_blk.c
+++ /dev/null
@@ -1,57 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * valid_blk.c --- does the inode have valid blocks?
4 *
5 * Copyright 1997 by Theodore Ts'o
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 *
12 */
13
14#include <stdio.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <string.h>
19#include <time.h>
20
21#include "ext2_fs.h"
22#include "ext2fs.h"
23
24/*
25 * This function returns 1 if the inode's block entries actually
26 * contain block entries.
27 */
28int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
29{
30 /*
31 * Only directories, regular files, and some symbolic links
32 * have valid block entries.
33 */
34 if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
35 !LINUX_S_ISLNK(inode->i_mode))
36 return 0;
37
38 /*
39 * If the symbolic link is a "fast symlink", then the symlink
40 * target is stored in the block entries.
41 */
42 if (LINUX_S_ISLNK (inode->i_mode)) {
43 if (inode->i_file_acl == 0) {
44 /* With no EA block, we can rely on i_blocks */
45 if (inode->i_blocks == 0)
46 return 0;
47 } else {
48 /* With an EA block, life gets more tricky */
49 if (inode->i_size >= EXT2_N_BLOCKS*4)
50 return 1; /* definitely using i_block[] */
51 if (inode->i_size > 4 && inode->i_block[1] == 0)
52 return 1; /* definitely using i_block[] */
53 return 0; /* Probably a fast symlink */
54 }
55 }
56 return 1;
57}
diff --git a/e2fsprogs/ext2fs/version.c b/e2fsprogs/ext2fs/version.c
deleted file mode 100644
index d2981e867..000000000
--- a/e2fsprogs/ext2fs/version.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * version.c --- Return the version of the ext2 library
4 *
5 * Copyright (C) 1997 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#if HAVE_UNISTD_H
14#include <unistd.h>
15#endif
16#include <string.h>
17#include <stdio.h>
18#include <ctype.h>
19
20#include "ext2_fs.h"
21#include "ext2fs.h"
22
23static const char *lib_version = E2FSPROGS_VERSION;
24static const char *lib_date = E2FSPROGS_DATE;
25
26int ext2fs_parse_version_string(const char *ver_string)
27{
28 const char *cp;
29 int version = 0;
30
31 for (cp = ver_string; *cp; cp++) {
32 if (*cp == '.')
33 continue;
34 if (!isdigit(*cp))
35 break;
36 version = (version * 10) + (*cp - '0');
37 }
38 return version;
39}
40
41
42int ext2fs_get_library_version(const char **ver_string,
43 const char **date_string)
44{
45 if (ver_string)
46 *ver_string = lib_version;
47 if (date_string)
48 *date_string = lib_date;
49
50 return ext2fs_parse_version_string(lib_version);
51}
diff --git a/e2fsprogs/ext2fs/write_bb_file.c b/e2fsprogs/ext2fs/write_bb_file.c
deleted file mode 100644
index 5b19eefa0..000000000
--- a/e2fsprogs/ext2fs/write_bb_file.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * write_bb_file.c --- write a list of bad blocks to a FILE *
4 *
5 * Copyright (C) 1994, 1995 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14
15#include "ext2_fs.h"
16#include "ext2fs.h"
17
18errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
19 unsigned int flags EXT2FS_ATTR((unused)),
20 FILE *f)
21{
22 badblocks_iterate bb_iter;
23 blk_t blk;
24 errcode_t retval;
25
26 retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);
27 if (retval)
28 return retval;
29
30 while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) {
31 fprintf(f, "%d\n", blk);
32 }
33 ext2fs_badblocks_list_iterate_end(bb_iter);
34 return 0;
35}