aboutsummaryrefslogtreecommitdiff
path: root/e2fsprogs/e2fsck/swapfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'e2fsprogs/e2fsck/swapfs.c')
-rw-r--r--e2fsprogs/e2fsck/swapfs.c268
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
20struct 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 */
33static 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 */
79static 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
109static 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
201static 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
212void 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