blob: 81092097768a5d9e5899817f5c91770ce7af6af4 [file] [log] [blame]
Theodore Ts'oba75d9e2012-12-24 00:22:10 -05001/*
2 * zap.c --- zap block
3 *
4 * Copyright (C) 2012 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
6 */
7
8#include "config.h"
9#include <stdio.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <ctype.h>
13#include <string.h>
14#include <time.h>
15#ifdef HAVE_ERRNO_H
16#include <errno.h>
17#endif
18#include <sys/types.h>
19#ifdef HAVE_GETOPT_H
20#include <getopt.h>
21#else
22extern int optind;
23extern char *optarg;
24#endif
25
26#include "debugfs.h"
27
28void do_zap_block(int argc, char *argv[])
29{
30 unsigned long pattern = 0;
31 unsigned char *buf;
32 ext2_ino_t inode;
33 errcode_t errcode;
34 blk64_t block;
Theodore Ts'oba75d9e2012-12-24 00:22:10 -050035 char *file = NULL;
Theodore Ts'oba75d9e2012-12-24 00:22:10 -050036 int c, err;
37 int offset = -1;
38 int length = -1;
39 int bit = -1;
40
41 if (check_fs_open(argv[0]))
42 return;
43 if (check_fs_read_write(argv[0]))
44 return;
45
46 reset_getopt();
47 while ((c = getopt (argc, argv, "b:f:l:o:p:")) != EOF) {
48 switch (c) {
49 case 'f':
50 file = optarg;
51 break;
52 case 'b':
53 bit = parse_ulong(optarg, argv[0],
54 "bit", &err);
55 if (err)
56 return;
Theodore Ts'o9e852082013-01-14 14:41:46 -050057 if (bit >= (int) current_fs->blocksize * 8) {
Theodore Ts'oba75d9e2012-12-24 00:22:10 -050058 com_err(argv[0], 0, "The bit to flip "
59 "must be within a %d block\n",
60 current_fs->blocksize);
61 return;
62 }
63 break;
64 case 'p':
65 pattern = parse_ulong(optarg, argv[0],
66 "pattern", &err);
67 if (err)
68 return;
69 if (pattern >= 256) {
70 com_err(argv[0], 0, "The fill pattern must "
71 "be an 8-bit value\n");
72 return;
73 }
74 break;
75 case 'o':
76 offset = parse_ulong(optarg, argv[0],
77 "offset", &err);
78 if (err)
79 return;
Theodore Ts'o9e852082013-01-14 14:41:46 -050080 if (offset >= (int) current_fs->blocksize) {
Theodore Ts'oba75d9e2012-12-24 00:22:10 -050081 com_err(argv[0], 0, "The offset must be "
82 "within a %d block\n",
83 current_fs->blocksize);
84 return;
85 }
86 break;
87
88 break;
89 case 'l':
90 length = parse_ulong(optarg, argv[0],
91 "length", &err);
92 if (err)
93 return;
94 break;
95 default:
96 goto print_usage;
97 }
98 }
99
100 if (bit > 0 && offset > 0) {
101 com_err(argv[0], 0, "The -o and -b options can not be mixed.");
102 return;
103 }
104
105 if (offset < 0)
106 offset = 0;
107 if (length < 0)
108 length = current_fs->blocksize - offset;
Theodore Ts'o9e852082013-01-14 14:41:46 -0500109 if ((offset + length) > (int) current_fs->blocksize) {
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500110 com_err(argv[0], 0, "The specified length is too bug\n");
111 return;
112 }
113
114 if (argc != optind+1) {
115 print_usage:
116 com_err(0, 0, "Usage:\tzap_block [-f file] [-o offset] "
117 "[-l length] [-p pattern] block_num");
118 com_err(0, 0, "\tzap_block [-f file] [-b bit] "
119 "block_num");
120 return;
121 }
122
123 block = parse_ulonglong(argv[optind], argv[0], "block", &err);
124 if (err)
125 return;
126
127 if (file) {
128 inode = string_to_inode(file);
129 if (!inode)
130 return;
131 errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
132 block, 0, &block);
133 if (errcode) {
134 com_err(argv[0], errcode,
135 "while mapping logical block %llu\n", block);
136 return;
137 }
138 }
139
140 buf = malloc(current_fs->blocksize);
141 if (!buf) {
142 com_err(argv[0], 0, "Couldn't allocate block buffer");
143 return;
144 }
145
146 errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
147 if (errcode) {
148 com_err(argv[0], errcode,
149 "while reading block %llu\n", block);
150 goto errout;
151 }
152
153 if (bit >= 0)
154 buf[bit >> 3] ^= 1 << (bit & 7);
155 else
156 memset(buf+offset, pattern, length);
157
158 errcode = io_channel_write_blk64(current_fs->io, block, 1, buf);
159 if (errcode) {
160 com_err(argv[0], errcode,
161 "while write block %llu\n", block);
162 goto errout;
163 }
164
165errout:
166 free(buf);
167 return;
168}
169
Theodore Ts'o9e852082013-01-14 14:41:46 -0500170void do_block_dump(int argc, char *argv[])
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500171{
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500172 unsigned char *buf;
173 ext2_ino_t inode;
174 errcode_t errcode;
175 blk64_t block;
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500176 char *file = NULL;
Theodore Ts'o9e852082013-01-14 14:41:46 -0500177 unsigned int i, j;
178 int c, err;
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500179 int suppress = -1;
180
181 if (check_fs_open(argv[0]))
182 return;
183
184 reset_getopt();
185 while ((c = getopt (argc, argv, "f:")) != EOF) {
186 switch (c) {
187 case 'f':
188 file = optarg;
189 break;
190
191 default:
192 goto print_usage;
193 }
194 }
195
Andreas Dilgerdba2bbd2013-12-15 22:12:43 -0500196 if (argc != optind + 1) {
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500197 print_usage:
Andreas Dilgerdba2bbd2013-12-15 22:12:43 -0500198 com_err(0, 0, "Usage: block_dump [-f inode] block_num");
Theodore Ts'oba75d9e2012-12-24 00:22:10 -0500199 return;
200 }
201
202 block = parse_ulonglong(argv[optind], argv[0], "block", &err);
203 if (err)
204 return;
205
206 if (file) {
207 inode = string_to_inode(file);
208 if (!inode)
209 return;
210 errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
211 block, 0, &block);
212 if (errcode) {
213 com_err(argv[0], errcode,
214 "while mapping logical block %llu\n", block);
215 return;
216 }
217 }
218
219 buf = malloc(current_fs->blocksize);
220 if (!buf) {
221 com_err(argv[0], 0, "Couldn't allocate block buffer");
222 return;
223 }
224
225 errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
226 if (errcode) {
227 com_err(argv[0], errcode,
228 "while reading block %llu\n", block);
229 goto errout;
230 }
231
232 for (i=0; i < current_fs->blocksize; i += 16) {
233 if (suppress < 0) {
234 if (i && memcmp(buf + i, buf + i - 16, 16) == 0) {
235 suppress = i;
236 printf("*\n");
237 continue;
238 }
239 } else {
240 if (memcmp(buf + i, buf + suppress, 16) == 0)
241 continue;
242 suppress = -1;
243 }
244 printf("%04o ", i);
245 for (j = 0; j < 16; j++) {
246 printf("%02x", buf[i+j]);
247 if ((j % 2) == 1)
248 putchar(' ');
249 }
250 putchar(' ');
251 for (j = 0; j < 16; j++)
252 printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
253 putchar('\n');
254 }
255 putchar('\n');
256
257errout:
258 free(buf);
259 return;
260}