diff options
Diffstat (limited to 'e2fsprogs/e2fsck/swapfs.c')
-rw-r--r-- | e2fsprogs/e2fsck/swapfs.c | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/e2fsprogs/e2fsck/swapfs.c b/e2fsprogs/e2fsck/swapfs.c deleted file mode 100644 index a737b9624..000000000 --- a/e2fsprogs/e2fsck/swapfs.c +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
1 | /* | ||
2 | * swapfs.c --- byte-swap an ext2 filesystem | ||
3 | * | ||
4 | * Copyright 1996, 1997 by Theodore Ts'o | ||
5 | * | ||
6 | * %Begin-Header% | ||
7 | * This file may be redistributed under the terms of the GNU Public | ||
8 | * License. | ||
9 | * %End-Header% | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #ifdef HAVE_ERRNO_H | ||
14 | #include <errno.h> | ||
15 | #endif | ||
16 | #include "e2fsck.h" | ||
17 | |||
18 | #ifdef ENABLE_SWAPFS | ||
19 | |||
20 | struct swap_block_struct { | ||
21 | ext2_ino_t ino; | ||
22 | int isdir; | ||
23 | errcode_t errcode; | ||
24 | char *dir_buf; | ||
25 | struct ext2_inode *inode; | ||
26 | }; | ||
27 | |||
28 | /* | ||
29 | * This is a helper function for block_iterate. We mark all of the | ||
30 | * indirect and direct blocks as changed, so that block_iterate will | ||
31 | * write them out. | ||
32 | */ | ||
33 | static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt, | ||
34 | void *priv_data) | ||
35 | { | ||
36 | errcode_t retval; | ||
37 | |||
38 | struct swap_block_struct *sb = (struct swap_block_struct *) priv_data; | ||
39 | |||
40 | if (sb->isdir && (blockcnt >= 0) && *block_nr) { | ||
41 | retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf); | ||
42 | if (retval) { | ||
43 | sb->errcode = retval; | ||
44 | return BLOCK_ABORT; | ||
45 | } | ||
46 | retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf); | ||
47 | if (retval) { | ||
48 | sb->errcode = retval; | ||
49 | return BLOCK_ABORT; | ||
50 | } | ||
51 | } | ||
52 | if (blockcnt >= 0) { | ||
53 | if (blockcnt < EXT2_NDIR_BLOCKS) | ||
54 | return 0; | ||
55 | return BLOCK_CHANGED; | ||
56 | } | ||
57 | if (blockcnt == BLOCK_COUNT_IND) { | ||
58 | if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK]) | ||
59 | return 0; | ||
60 | return BLOCK_CHANGED; | ||
61 | } | ||
62 | if (blockcnt == BLOCK_COUNT_DIND) { | ||
63 | if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK]) | ||
64 | return 0; | ||
65 | return BLOCK_CHANGED; | ||
66 | } | ||
67 | if (blockcnt == BLOCK_COUNT_TIND) { | ||
68 | if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK]) | ||
69 | return 0; | ||
70 | return BLOCK_CHANGED; | ||
71 | } | ||
72 | return BLOCK_CHANGED; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * This function is responsible for byte-swapping all of the indirect, | ||
77 | * block pointers. It is also responsible for byte-swapping directories. | ||
78 | */ | ||
79 | static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf, | ||
80 | struct ext2_inode *inode) | ||
81 | { | ||
82 | errcode_t retval; | ||
83 | struct swap_block_struct sb; | ||
84 | |||
85 | sb.ino = ino; | ||
86 | sb.inode = inode; | ||
87 | sb.dir_buf = block_buf + ctx->fs->blocksize*3; | ||
88 | sb.errcode = 0; | ||
89 | sb.isdir = 0; | ||
90 | if (LINUX_S_ISDIR(inode->i_mode)) | ||
91 | sb.isdir = 1; | ||
92 | |||
93 | retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf, | ||
94 | swap_block, &sb); | ||
95 | if (retval) { | ||
96 | com_err("swap_inode_blocks", retval, | ||
97 | _("while calling ext2fs_block_iterate")); | ||
98 | ctx->flags |= E2F_FLAG_ABORT; | ||
99 | return; | ||
100 | } | ||
101 | if (sb.errcode) { | ||
102 | com_err("swap_inode_blocks", sb.errcode, | ||
103 | _("while calling iterator function")); | ||
104 | ctx->flags |= E2F_FLAG_ABORT; | ||
105 | return; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void swap_inodes(e2fsck_t ctx) | ||
110 | { | ||
111 | ext2_filsys fs = ctx->fs; | ||
112 | dgrp_t group; | ||
113 | unsigned int i; | ||
114 | ext2_ino_t ino = 1; | ||
115 | char *buf, *block_buf; | ||
116 | errcode_t retval; | ||
117 | struct ext2_inode * inode; | ||
118 | |||
119 | e2fsck_use_inode_shortcuts(ctx, 1); | ||
120 | |||
121 | retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group, | ||
122 | &buf); | ||
123 | if (retval) { | ||
124 | com_err("swap_inodes", retval, | ||
125 | _("while allocating inode buffer")); | ||
126 | ctx->flags |= E2F_FLAG_ABORT; | ||
127 | return; | ||
128 | } | ||
129 | block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, | ||
130 | "block interate buffer"); | ||
131 | for (group = 0; group < fs->group_desc_count; group++) { | ||
132 | retval = io_channel_read_blk(fs->io, | ||
133 | fs->group_desc[group].bg_inode_table, | ||
134 | fs->inode_blocks_per_group, buf); | ||
135 | if (retval) { | ||
136 | com_err("swap_inodes", retval, | ||
137 | _("while reading inode table (group %d)"), | ||
138 | group); | ||
139 | ctx->flags |= E2F_FLAG_ABORT; | ||
140 | return; | ||
141 | } | ||
142 | inode = (struct ext2_inode *) buf; | ||
143 | for (i=0; i < fs->super->s_inodes_per_group; | ||
144 | i++, ino++, inode++) { | ||
145 | ctx->stashed_ino = ino; | ||
146 | ctx->stashed_inode = inode; | ||
147 | |||
148 | if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ) | ||
149 | ext2fs_swap_inode(fs, inode, inode, 0); | ||
150 | |||
151 | /* | ||
152 | * Skip deleted files. | ||
153 | */ | ||
154 | if (inode->i_links_count == 0) | ||
155 | continue; | ||
156 | |||
157 | if (LINUX_S_ISDIR(inode->i_mode) || | ||
158 | ((inode->i_block[EXT2_IND_BLOCK] || | ||
159 | inode->i_block[EXT2_DIND_BLOCK] || | ||
160 | inode->i_block[EXT2_TIND_BLOCK]) && | ||
161 | ext2fs_inode_has_valid_blocks(inode))) | ||
162 | swap_inode_blocks(ctx, ino, block_buf, inode); | ||
163 | |||
164 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
165 | return; | ||
166 | |||
167 | if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) | ||
168 | ext2fs_swap_inode(fs, inode, inode, 1); | ||
169 | } | ||
170 | retval = io_channel_write_blk(fs->io, | ||
171 | fs->group_desc[group].bg_inode_table, | ||
172 | fs->inode_blocks_per_group, buf); | ||
173 | if (retval) { | ||
174 | com_err("swap_inodes", retval, | ||
175 | _("while writing inode table (group %d)"), | ||
176 | group); | ||
177 | ctx->flags |= E2F_FLAG_ABORT; | ||
178 | return; | ||
179 | } | ||
180 | } | ||
181 | ext2fs_free_mem(&buf); | ||
182 | ext2fs_free_mem(&block_buf); | ||
183 | e2fsck_use_inode_shortcuts(ctx, 0); | ||
184 | ext2fs_flush_icache(fs); | ||
185 | } | ||
186 | |||
187 | #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS) | ||
188 | /* | ||
189 | * On the PowerPC, the big-endian variant of the ext2 filesystem | ||
190 | * has its bitmaps stored as 32-bit words with bit 0 as the LSB | ||
191 | * of each word. Thus a bitmap with only bit 0 set would be, as | ||
192 | * a string of bytes, 00 00 00 01 00 ... | ||
193 | * To cope with this, we byte-reverse each word of a bitmap if | ||
194 | * we have a big-endian filesystem, that is, if we are *not* | ||
195 | * byte-swapping other word-sized numbers. | ||
196 | */ | ||
197 | #define EXT2_BIG_ENDIAN_BITMAPS | ||
198 | #endif | ||
199 | |||
200 | #ifdef EXT2_BIG_ENDIAN_BITMAPS | ||
201 | static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap) | ||
202 | { | ||
203 | __u32 *p = (__u32 *) bmap->bitmap; | ||
204 | int n, nbytes = (bmap->end - bmap->start + 7) / 8; | ||
205 | |||
206 | for (n = nbytes / sizeof(__u32); n > 0; --n, ++p) | ||
207 | *p = ext2fs_swab32(*p); | ||
208 | } | ||
209 | #endif | ||
210 | |||
211 | |||
212 | void swap_filesys(e2fsck_t ctx) | ||
213 | { | ||
214 | ext2_filsys fs = ctx->fs; | ||
215 | #ifdef RESOURCE_TRACK | ||
216 | struct resource_track rtrack; | ||
217 | |||
218 | init_resource_track(&rtrack); | ||
219 | #endif | ||
220 | |||
221 | if (!(ctx->options & E2F_OPT_PREEN)) | ||
222 | printf(_("Pass 0: Doing byte-swap of filesystem\n")); | ||
223 | |||
224 | #ifdef MTRACE | ||
225 | mtrace_print("Byte swap"); | ||
226 | #endif | ||
227 | |||
228 | if (fs->super->s_mnt_count) { | ||
229 | fprintf(stderr, _("%s: the filesystem must be freshly " | ||
230 | "checked using fsck\n" | ||
231 | "and not mounted before trying to " | ||
232 | "byte-swap it.\n"), ctx->device_name); | ||
233 | ctx->flags |= E2F_FLAG_ABORT; | ||
234 | return; | ||
235 | } | ||
236 | if (fs->flags & EXT2_FLAG_SWAP_BYTES) { | ||
237 | fs->flags &= ~(EXT2_FLAG_SWAP_BYTES| | ||
238 | EXT2_FLAG_SWAP_BYTES_WRITE); | ||
239 | fs->flags |= EXT2_FLAG_SWAP_BYTES_READ; | ||
240 | } else { | ||
241 | fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ; | ||
242 | fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE; | ||
243 | } | ||
244 | swap_inodes(ctx); | ||
245 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
246 | return; | ||
247 | if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) | ||
248 | fs->flags |= EXT2_FLAG_SWAP_BYTES; | ||
249 | fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ| | ||
250 | EXT2_FLAG_SWAP_BYTES_WRITE); | ||
251 | |||
252 | #ifdef EXT2_BIG_ENDIAN_BITMAPS | ||
253 | e2fsck_read_bitmaps(ctx); | ||
254 | ext2fs_swap_bitmap(fs->inode_map); | ||
255 | ext2fs_swap_bitmap(fs->block_map); | ||
256 | fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY; | ||
257 | #endif | ||
258 | fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; | ||
259 | ext2fs_flush(fs); | ||
260 | fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; | ||
261 | |||
262 | #ifdef RESOURCE_TRACK | ||
263 | if (ctx->options & E2F_OPT_TIME2) | ||
264 | print_resource_track(_("Byte swap"), &rtrack); | ||
265 | #endif | ||
266 | } | ||
267 | |||
268 | #endif | ||