1 #include "clusterautoconfig.h"
2
3 #include <dirent.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <inttypes.h>
8 #include <sys/stat.h>
9 #include <libintl.h>
10 #define _(String) gettext(String)
11
12 #include <logging.h>
13 #include "libgfs2.h"
14 #include "fsck.h"
15 #include "util.h"
16 #include "metawalk.h"
17 #include "link.h"
18 #include "lost_n_found.h"
19 #include "inode_hash.h"
20 #include "afterpass1_common.h"
21 #include "fs_recovery.h"
22
23 #define MAX_FILENAME 256
24
25 static struct metawalk_fxns pass2_fxns;
26
27 static struct metawalk_fxns delete_eattrs = {
28 .check_eattr_indir = delete_eattr_indir,
29 .check_eattr_leaf = delete_eattr_leaf,
30 .check_eattr_entry = delete_eattr_entry,
31 .check_eattr_extentry = delete_eattr_extentry,
32 };
33
34 /* Set children's parent inode in dir_info structure - ext2 does not set
35 * dotdot inode here, but instead in pass3 - should we? */
36 static int set_parent_dir(struct fsck_cx *cx, struct lgfs2_inum child, struct lgfs2_inum parent)
37 {
38 struct dir_info *di;
39
40 di = dirtree_find(cx, child.in_addr);
41 if (!di) {
42 log_err(_("Unable to find block %"PRIu64" (0x%"PRIx64") in dir_info list\n"),
43 child.in_addr, child.in_addr);
44 return -1;
45 }
46
47 if (di->dinode.in_addr == child.in_addr &&
48 di->dinode.in_formal_ino == child.in_formal_ino) {
49 if (di->treewalk_parent) {
50 log_err(_("Another directory at block %"PRIu64" (0x%"PRIx64") "
51 "already contains this child %"PRIu64" (0x%"PRIx64")"
52 " - checking parent %"PRIu64" (0x%"PRIx64")\n"),
53 di->treewalk_parent, di->treewalk_parent, child.in_addr,
54 child.in_addr, parent.in_addr, parent.in_addr);
55 return 1;
56 }
57 log_debug(_("Child %"PRIu64" (0x%"PRIx64") has parent %"PRIu64" (0x%"PRIx64")\n"),
58 child.in_addr, child.in_addr, parent.in_addr, parent.in_addr);
59 di->treewalk_parent = parent.in_addr;
60 }
61
62 return 0;
63 }
64
65 /* Set's the child's '..' directory inode number in dir_info structure */
66 static int set_dotdot_dir(struct fsck_cx *cx, uint64_t childblock, struct lgfs2_inum parent)
67 {
68 struct dir_info *di;
69
70 di = dirtree_find(cx, childblock);
71 if (!di) {
72 log_err( _("Unable to find block %"PRIu64" (0x%" PRIx64
73 ") in dir_info tree\n"), childblock, childblock);
74 return -1;
75 }
76 if (di->dinode.in_addr != childblock) {
77 log_debug("'..' doesn't point to what we found: childblock "
78 "(0x%"PRIx64") != dinode (0x%"PRIx64")\n",
79 childblock, di->dinode.in_addr);
80 return -1;
81 }
82 /* Special case for root inode because we set it earlier */
83 if (di->dotdot_parent.in_addr &&
84 cx->sdp->md.rooti->i_num.in_addr != di->dinode.in_addr) {
85 /* This should never happen */
86 log_crit(_("Dotdot parent already set for block %"PRIu64" (0x%"PRIx64") "
87 "-> %"PRIu64" (0x%"PRIx64")\n"),
88 childblock, childblock, di->dotdot_parent.in_addr, di->dotdot_parent.in_addr);
89 return -1;
90 }
91 log_debug("Setting '..' for directory block (0x%"PRIx64") to parent (0x%"PRIx64")\n",
92 childblock, parent.in_addr);
93 di->dotdot_parent.in_addr = parent.in_addr;
94 di->dotdot_parent.in_formal_ino = parent.in_formal_ino;
95 return 0;
96 }
97
98 static int check_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block,
99 uint64_t parent, struct lgfs2_buffer_head **bh,
100 void *private)
101 {
102 *bh = lgfs2_bread(ip->i_sbd, block);
103 return 0;
104 }
105 static int check_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block,
106 uint64_t parent, struct lgfs2_buffer_head **bh,
107 void *private)
108 {
109 *bh = lgfs2_bread(ip->i_sbd, block);
110 return 0;
111 }
112
113 static const char *de_type_string(uint8_t de_type)
114 {
115 const char *de_types[15] = {"unknown", "fifo", "chrdev", "invalid",
116 "directory", "invalid", "blkdev", "invalid",
117 "file", "invalid", "symlink", "invalid",
118 "socket", "invalid", "wht"};
119 if (de_type < 15)
120 return de_types[de_type];
121 return de_types[3]; /* invalid */
122 }
123
124 static int check_file_type(struct fsck_cx *cx, uint64_t block, uint8_t de_type, int q,
125 int *isdir)
126 {
127 struct dir_info *dt;
128
129 *isdir = 0;
130 if (q != GFS2_BLKST_DINODE) {
131 log_err( _("Invalid block type\n"));
132 return -1;
133 }
134 if (de_type == DT_DIR)
135 *isdir = 1;
136 /* Check if the dinode is in the dir tree */
137 dt = dirtree_find(cx, block);
138 /* This is a bit confusing, so let me explain:
139 If the dirent says the inode supposed to be for a directory,
140 it should be in the dir tree. If it is, no problem, return 0.
141 If it's not, return 1 (wrong type). If it's not supposed to be
142 a directory, it shouldn't be in the dir tree. */
143 if (dt)
144 return !(*isdir);
145 return *isdir;
146 }
147
148 static struct metawalk_fxns pass2_fxns_delete = {
149 .private = NULL,
150 .check_metalist = delete_metadata,
151 .check_data = delete_data,
152 .check_leaf = delete_leaf,
153 .check_eattr_indir = delete_eattr_indir,
154 .check_eattr_leaf = delete_eattr_leaf,
155 .check_eattr_entry = delete_eattr_entry,
156 .check_eattr_extentry = delete_eattr_extentry,
157 };
158
159 /* bad_formal_ino - handle mismatches in formal inode number
160 * Returns: 0 if the dirent was repaired
161 * 1 if the caller should delete the dirent
162 */
163 static int bad_formal_ino(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent,
164 struct lgfs2_inum entry, const char *tmp_name,
165 int q, struct lgfs2_dirent *d,
166 struct lgfs2_buffer_head *bh)
167 {
168 struct inode_info *ii;
169 struct dir_info *di = NULL;
170 struct lgfs2_inode *child_ip;
171 struct lgfs2_inum childs_dotdot;
172 struct lgfs2_sbd *sdp = ip->i_sbd;
173 int error;
174 struct lgfs2_inum inum = {0};
175
176 ii = inodetree_find(cx, entry.in_addr);
177 if (ii)
178 inum = ii->num;
179 else {
180 di = dirtree_find(cx, entry.in_addr);
181 if (di)
182 inum = di->dinode;
183 else if (link1_type(&clink1map, entry.in_addr) == 1) {
184 struct lgfs2_inode *dent_ip;
185
186 dent_ip = fsck_load_inode(ip->i_sbd, entry.in_addr);
187 inum.in_addr = dent_ip->i_num.in_addr;
188 inum.in_formal_ino = dent_ip->i_num.in_formal_ino;
189 fsck_inode_put(&dent_ip);
190 }
191 }
192 log_err(_("Directory entry '%s' pointing to block %"PRIu64" (0x%"PRIx64") in "
193 "directory %"PRIu64" (0x%"PRIx64") has the wrong 'formal' inode number.\n"),
194 tmp_name, entry.in_addr, entry.in_addr, ip->i_num.in_addr, ip->i_num.in_addr);
195 log_err(_("The directory entry has %"PRIu64" (0x%"PRIx64") "
196 "but the inode has %"PRIu64" (0x%"PRIx64")\n"),
197 entry.in_formal_ino, entry.in_formal_ino,
198 inum.in_formal_ino, inum.in_formal_ino);
199 if (q != GFS2_BLKST_DINODE || !strcmp("..", tmp_name)) {
200 if (query(cx, _("Remove the corrupt directory entry? (y/n) ")))
201 return 1;
202 log_err( _("Corrupt directory entry not removed.\n"));
203 return 0;
204 }
205 /* We have a directory pointing to another directory, but the
206 formal inode number still doesn't match. If that directory
207 has a '..' pointing back, just fix up the no_formal_ino. */
208 child_ip = lgfs2_inode_read(sdp, entry.in_addr);
209 error = lgfs2_dir_search(child_ip, "..", 2, NULL, &childs_dotdot);
210 if (!error && childs_dotdot.in_addr == ip->i_num.in_addr) {
211 log_err( _("The entry points to another directory with intact "
212 "linkage.\n"));
213 if (query(cx, _("Fix the bad directory entry? (y/n) "))) {
214 log_err( _("Fixing the corrupt directory entry.\n"));
215 entry.in_formal_ino = inum.in_formal_ino;
216 d->dr_inum.in_formal_ino = entry.in_formal_ino;
217 lgfs2_dirent_out(d, dent);
218 lgfs2_bmodified(bh);
219 incr_link_count(cx, entry, ip, _("fixed reference"));
220 set_parent_dir(cx, entry, ip->i_num);
221 } else {
222 log_err( _("Directory entry not fixed.\n"));
223 }
224 } else {
225 if (query(cx, _("Remove the corrupt directory entry? (y/n) "))) {
226 lgfs2_inode_put(&child_ip);
227 return 1;
228 }
229 log_err( _("Corrupt directory entry not removed.\n"));
230 }
231 lgfs2_inode_put(&child_ip);
232 return 0;
233 }
234
235 static int hash_table_index(uint32_t hash, struct lgfs2_inode *ip)
236 {
237 return hash >> (32 - ip->i_depth);
238 }
239
240 static int hash_table_max(int lindex, struct lgfs2_inode *ip,
241 struct lgfs2_buffer_head *bh)
242 {
243 struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data;
244 return (1 << (ip->i_depth - be16_to_cpu(leaf->lf_depth))) +
245 lindex - 1;
246 }
247
248 static int check_leaf_depth(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t leaf_no,
249 int ref_count, struct lgfs2_buffer_head *lbh)
250 {
251 struct gfs2_leaf *leaf = (struct gfs2_leaf *)lbh->b_data;
252 int cur_depth = be16_to_cpu(leaf->lf_depth);
253 int exp_count = 1 << (ip->i_depth - cur_depth);
254 int divisor;
255 int factor, correct_depth;
256
257 if (exp_count == ref_count)
258 return 0;
259
260 factor = 0;
261 divisor = ref_count;
262 while (divisor > 1) {
263 factor++;
264 divisor >>= 1;
265 }
266 if (ip->i_depth < factor) /* can't be fixed--leaf must be on the
267 wrong dinode. */
268 return -1;
269 correct_depth = ip->i_depth - factor;
270 if (cur_depth == correct_depth)
271 return 0;
272
273 log_err(_("Leaf block %"PRIu64" (0x%"PRIx64") in dinode %"PRIu64" (0x%"PRIx64") has the "
274 "wrong depth: is %d (length %d), should be %d (length %d).\n"),
275 leaf_no, leaf_no, ip->i_num.in_addr, ip->i_num.in_addr,
276 cur_depth, ref_count, correct_depth, exp_count);
277 if (!query(cx, _("Fix the leaf block? (y/n)"))) {
278 log_err( _("The leaf block was not fixed.\n"));
279 return 0;
280 }
281
282 leaf->lf_depth = cpu_to_be16(correct_depth);
283 lgfs2_bmodified(lbh);
284 log_err( _("The leaf block depth was fixed.\n"));
285 return 1;
286 }
287
288 /* wrong_leaf: Deal with a dirent discovered to be on the wrong leaf block
289 *
290 * Returns: 1 if the dirent is to be removed, 0 if it needs to be kept,
291 * or -1 on error
292 */
293 static int wrong_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_inum *entry,
294 const char *tmp_name, int *lindex, int lindex_max,
295 int hash_index, struct lgfs2_buffer_head *bh,
296 struct dir_status *ds, struct gfs2_dirent *dent,
297 struct lgfs2_dirent *d, struct gfs2_dirent *prev_de,
298 uint32_t *count, int q)
299 {
300 struct lgfs2_sbd *sdp = ip->i_sbd;
301 struct lgfs2_buffer_head *dest_lbh;
302 uint64_t planned_leaf, real_leaf;
303 int li, dest_ref, error;
304 __be64 *tbl;
305 int di_depth;
306
307 log_err(_("Directory entry '%s' at block %"PRIu64" (0x%"PRIx64") is on the wrong leaf block.\n"),
308 tmp_name, entry->in_addr, entry->in_addr);
309 log_err(_("Leaf index is: 0x%x. The range for this leaf block is "
310 "0x%x - 0x%x\n"), hash_index, *lindex, lindex_max);
311 if (!query(cx, _("Move the misplaced directory entry to a valid leaf block? (y/n) "))) {
312 log_err( _("Misplaced directory entry not moved.\n"));
313 return 0;
314 }
315
316 /* check the destination leaf block's depth */
317 tbl = get_dir_hash(ip);
318 if (tbl == NULL) {
319 perror("get_dir_hash");
320 return -1;
321 }
322 planned_leaf = be64_to_cpu(tbl[hash_index]);
323 log_err(_("Moving it from leaf %"PRIu64" (0x%"PRIx64") to %"PRIu64" (0x%"PRIx64")\n"),
324 be64_to_cpu(tbl[*lindex]), be64_to_cpu(tbl[*lindex]), planned_leaf, planned_leaf);
325 /* Can't trust lf_depth; we have to count */
326 dest_ref = 0;
327 for (li = 0; li < (1 << ip->i_depth); li++) {
328 if (be64_to_cpu(tbl[li]) == planned_leaf)
329 dest_ref++;
330 else if (dest_ref)
331 break;
332 }
333 dest_lbh = lgfs2_bread(sdp, planned_leaf);
334 check_leaf_depth(cx, ip, planned_leaf, dest_ref, dest_lbh);
335 lgfs2_brelse(dest_lbh);
336 free(tbl);
337
338 /* check if it's already on the correct leaf block */
339 error = lgfs2_dir_search(ip, tmp_name, d->dr_name_len, NULL, &d->dr_inum);
340 if (!error) {
341 log_err(_("The misplaced directory entry already appears on "
342 "the correct leaf block.\n"));
343 log_err( _("The bad duplicate directory entry "
344 "'%s' was cleared.\n"), tmp_name);
345 return 1; /* nuke the dent upon return */
346 }
347
348 di_depth = ip->i_depth;
349 if (lgfs2_dir_add(ip, tmp_name, d->dr_name_len, &d->dr_inum, d->dr_type) == 0) {
350 log_err(_("The misplaced directory entry was moved to a "
351 "valid leaf block.\n"));
352 if (ip->i_depth > di_depth) {
353 log_err(_("Directory hash table was doubled.\n"));
354 hash_index <<= (ip->i_depth - di_depth);
355 (*lindex) <<= (ip->i_depth - di_depth);
356 }
357 if (lgfs2_get_leaf_ptr(ip, hash_index, &real_leaf)) {
358 log_err(_("Could not read leaf %d in dinode %"PRIu64": %s\n"), hash_index,
359 ip->i_num.in_addr, strerror(errno));
360 }
361 if (real_leaf != planned_leaf) {
362 log_err(_("The planned leaf was split. The new leaf "
363 "is: %"PRIu64" (0x%"PRIx64"). di_blocks=%"PRIu64"\n"),
364 real_leaf, real_leaf, ip->i_blocks);
365 fsck_bitmap_set(cx, ip, real_leaf, _("split leaf"), GFS2_BLKST_USED);
366 }
367 /* If the misplaced dirent was supposed to be earlier in the
368 hash table, we need to adjust our counts for the blocks
369 that have already been processed. If it's supposed to
370 appear later, we'll count it has part of our normal
371 processing when we get to that leaf block later on in the
372 hash table. */
373 if (hash_index > *lindex) {
374 log_err(_("Accounting deferred.\n"));
375 return 1; /* nuke the dent upon return */
376 }
377 /* If we get here, it's because we moved a dent to another
378 leaf, but that leaf has already been processed. So we have
379 to nuke the dent from this leaf when we return, but we
380 still need to do the "good dent" accounting. */
381 if (d->dr_type == DT_DIR) {
382 error = set_parent_dir(cx, d->dr_inum, ip->i_num);
383 if (error > 0)
384 /* This is a bit of a kludge, but returning 0
385 in this case causes the caller to go through
386 function set_parent_dir a second time and
387 deal properly with the hard link. */
388 return 0;
389 }
390 error = incr_link_count(cx, *entry, ip, _("moved valid reference"));
391 if (error > 0 &&
392 bad_formal_ino(cx, ip, dent, *entry, tmp_name, q, d, bh) == 1)
393 return 1; /* nuke it */
394
395 /* You cannot do this:
396 (*count)++;
397 The reason is: *count is the count of dentries on the leaf,
398 and we moved the dentry to a previous leaf within the same
399 directory dinode. So the directory counts still get
400 incremented, but not leaf entries. When we called lgfs2_dir_add
401 above, it should have fixed that prev leaf's lf_entries. */
402 ds->entry_count++;
403 return 1;
404 } else {
405 log_err(_("Error moving directory entry.\n"));
406 return 1; /* nuke it */
407 }
408 }
409
410 /* basic_dentry_checks - fundamental checks for directory entries
411 *
412 * @ip: pointer to the incode inode structure
413 * @entry: pointer to the inum info
414 * @tmp_name: user-friendly file name
415 * @count: pointer to the entry count
416 * @de: pointer to the directory entry
417 *
418 * Returns: 1 means corruption, nuke the dentry, 0 means checks pass
419 */
420 static int basic_dentry_checks(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent,
421 struct lgfs2_inum *entry, const char *tmp_name,
422 uint32_t *count, struct lgfs2_dirent *d,
423 struct dir_status *ds, int *q,
424 struct lgfs2_buffer_head *bh, int *isdir)
425 {
426 struct lgfs2_sbd *sdp = ip->i_sbd;
427 uint32_t calculated_hash;
428 struct lgfs2_inode *entry_ip = NULL;
429 int error;
430 struct inode_info *ii;
431 struct dir_info *di = NULL;
432 struct lgfs2_inum inum = {0};
433
434 *isdir = 0;
435 if (!valid_block_ip(ip, entry->in_addr)) {
436 log_err(_("Block # referenced by directory entry %s in inode %"PRIu64
437 " (0x%"PRIx64") is invalid\n"),
438 tmp_name, ip->i_num.in_addr, ip->i_num.in_addr);
439 if (query(cx, _("Clear directory entry to out of range block? (y/n) "))) {
440 return 1;
441 } else {
442 log_err( _("Directory entry to out of range block remains\n"));
443 (*count)++;
444 ds->entry_count++;
445 /* can't do this because the block is out of range:
446 incr_link_count(entry); */
447 return 0;
448 }
449 }
450
451 if (d->dr_rec_len < GFS2_DIRENT_SIZE(d->dr_name_len) ||
452 d->dr_name_len > GFS2_FNAMESIZE) {
453 log_err( _("Dir entry with bad record or name length\n"
454 "\tRecord length = %u\n\tName length = %u\n"),
455 d->dr_rec_len, d->dr_name_len);
456 if (!query(cx, _("Clear the directory entry? (y/n) "))) {
457 log_err( _("Directory entry not fixed.\n"));
458 return 0;
459 }
460 /* Don't be tempted to do this:
461 fsck_bitmap_set(ip, ip->i_di.di_num.no_addr,
462 _("corrupt directory entry"),
463 GFS2_BLKST_FREE);
464 We can't free it because another dir may have a valid reference
465 to it. Just return 1 so we can delete the bad dirent. */
466 log_err( _("Bad directory entry deleted.\n"));
467 return 1;
468 }
469
470 calculated_hash = lgfs2_disk_hash(tmp_name, d->dr_name_len);
471 if (d->dr_hash != calculated_hash){
472 log_err( _("Dir entry with bad hash or name length\n"
473 "\tHash found = %u (0x%x)\n"
474 "\tFilename = %s\n"),
475 d->dr_hash, d->dr_hash, tmp_name);
476 log_err( _("\tName length found = %u\n"
477 "\tHash expected = %u (0x%x)\n"),
478 d->dr_name_len, calculated_hash, calculated_hash);
479 if (!query(cx, _("Fix directory hash for %s? (y/n) "),
480 tmp_name)) {
481 log_err( _("Directory entry hash for %s not "
482 "fixed.\n"), tmp_name);
483 return 0;
484 }
485 d->dr_hash = calculated_hash;
486 lgfs2_dirent_out(d, dent);
487 lgfs2_bmodified(bh);
488 log_err( _("Directory entry hash for %s fixed.\n"),
489 tmp_name);
490 }
491
492 *q = bitmap_type(sdp, entry->in_addr);
493 /* Get the status of the directory inode */
494 /**
495 * 1. Blocks marked "invalid" were invalidated due to duplicate
496 * block references. Pass1b should have already taken care of deleting
497 * their metadata, so here we only need to delete the directory entries
498 * pointing to them. We delete the metadata in pass1b because we need
499 * to eliminate the inode referencing the duplicate-referenced block
500 * from the list of candidates to keep. So we have a delete-as-we-go
501 * policy.
502 *
503 * 2. Blocks marked "bad" need to have their entire
504 * metadata tree deleted.
505 */
506 if (*q != GFS2_BLKST_DINODE) {
507 log_err(_("Directory entry '%s' referencing inode %"PRIu64" (0x%"PRIx64") "
508 "in dir inode %"PRIu64" (0x%"PRIx64") block type %d: %s.\n"),
509 tmp_name, entry->in_addr, entry->in_addr, ip->i_num.in_addr, ip->i_num.in_addr,
510 *q, *q == GFS2_BLKST_FREE ?
511 _("was previously marked invalid") :
512 _("was deleted or is not an inode"));
513
514 if (!query(cx, _("Clear directory entry to non-inode block? (y/n) "))) {
515 log_err( _("Directory entry to non-inode block remains\n"));
516 return 0;
517 }
518
519 /* Don't decrement the link here: Here in pass2, we increment
520 only when we know it's okay.
521 decr_link_count(ip->i_di.di_num.no_addr, blah); */
522 /* If it was previously marked invalid (i.e. known
523 to be bad, not just a free block, etc.) then the temptation
524 would be to delete any metadata it holds. The trouble is:
525 if it's invalid, we may or _may_not_ have traversed its
526 metadata tree, and therefore may or may not have marked the
527 blocks it points to as a metadata type, or as a duplicate.
528 If there is really a duplicate reference, but we didn't
529 process the metadata tree because it's invalid, some other
530 inode has a reference to the metadata block, in which case
531 freeing it would do more harm than good. IOW we cannot
532 count on "delete_block_if_notdup" knowing whether it's
533 really a duplicate block if we never traversed the metadata
534 tree for the invalid inode. */
535 return 1;
536 }
537
538 error = check_file_type(cx, entry->in_addr, d->dr_type, *q, isdir);
539 if (error < 0) {
540 log_err(_("Error: directory entry type is incompatible with block type at block %"PRIu64
541 " (0x%"PRIx64") in directory inode %"PRIu64" (0x%"PRIx64").\n"),
542 entry->in_addr, entry->in_addr, ip->i_num.in_addr, ip->i_num.in_addr);
543 log_err( _("Directory entry type is %d, block type is %d.\n"),
544 d->dr_type, *q);
545 stack;
546 return -1;
547 }
548 if (error > 0) {
549 log_err( _("Type '%s' in dir entry (%s, %"PRIu64"/0x%"PRIx64") conflicts"
550 " with type '%s' in dinode. (Dir entry is stale.)\n"),
551 de_type_string(d->dr_type), tmp_name,
552 entry->in_addr, entry->in_addr,
553 block_type_string(*q));
554 if (!query(cx, _("Clear stale directory entry? (y/n) "))) {
555 log_err( _("Stale directory entry remains\n"));
556 return 0;
557 }
558 if (ip->i_num.in_addr == entry->in_addr)
559 entry_ip = ip;
560 else
561 entry_ip = fsck_load_inode(sdp, entry->in_addr);
562 check_inode_eattr(cx, entry_ip, &delete_eattrs);
563 if (entry_ip != ip)
564 fsck_inode_put(&entry_ip);
565 return 1;
566 }
567 /* We need to verify the formal inode number matches. If it doesn't,
568 it needs to be deleted. */
569 ii = inodetree_find(cx, entry->in_addr);
570 if (ii)
571 inum = ii->num;
572 else {
573 di = dirtree_find(cx, entry->in_addr);
574 if (di)
575 inum = di->dinode;
576 else if (link1_type(&nlink1map, entry->in_addr) == 1) {
577 /* Since we don't have ii or di, the only way to
578 validate formal_ino is to read in the inode, which
579 would kill performance. So skip it for now. */
580 return 0;
581 }
582 }
583 if (inum.in_formal_ino != entry->in_formal_ino) {
584 log_err(_("Directory entry '%s' pointing to block %"PRIu64" (0x%"PRIx64") "
585 "in directory %"PRIu64" (0x%"PRIx64") has the wrong 'formal' inode number.\n"),
586 tmp_name, entry->in_addr, entry->in_addr, ip->i_num.in_addr, ip->i_num.in_addr);
587 log_err(_("The directory entry has %"PRIu64" (0x%"PRIx64") but the "
588 "inode has %"PRIu64" (0x%"PRIx64")\n"),
589 entry->in_formal_ino, entry->in_formal_ino,
590 inum.in_formal_ino, inum.in_formal_ino);
591 return 1;
592 }
593 return 0;
594 }
595
596 static int dirref_find(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent,
597 struct gfs2_dirent *prev, struct lgfs2_buffer_head *bh,
598 char *filename, uint32_t *count, int *lindex,
599 void *private)
600 {
601 /* the metawalk_fxn's private field must be set to the dentry
602 * block we want to clear */
603 struct lgfs2_inum *entry = private;
604 struct lgfs2_dirent dentry;
605 char fn[MAX_FILENAME];
606
607 memset(&dentry, 0, sizeof(dentry));
608 lgfs2_dirent_in(&dentry, dent);
609
610 if (dentry.dr_inum.in_addr != entry->in_addr) {
611 (*count)++;
612 return 0;
613 }
614 if (dentry.dr_inum.in_formal_ino == entry->in_formal_ino) {
615 log_debug("Formal inode number matches; must be a hard "
616 "link.\n");
617 goto out;
618 }
619 log_err(_("The original reference to inode %"PRIu64" (0x%"PRIx64") from "
620 "directory %"PRIu64" (0x%"PRIx64") has the wrong 'formal' inode "
621 "number.\n"), entry->in_addr, entry->in_addr, ip->i_num.in_addr, ip->i_num.in_addr);
622 memset(fn, 0, sizeof(fn));
623 if (dentry.dr_name_len < MAX_FILENAME)
624 strncpy(fn, filename, dentry.dr_name_len);
625 else
626 strncpy(fn, filename, MAX_FILENAME - 1);
627 log_err(_("The bad reference '%s' had formal inode number: %"PRIu64
628 " (0x%"PRIx64") but the correct value is: %"PRIu64" (0x%"PRIx64")\n"),
629 fn, dentry.dr_inum.in_formal_ino, dentry.dr_inum.in_formal_ino,
630 entry->in_formal_ino, entry->in_formal_ino);
631 if (!query(cx, _("Delete the bad directory entry? (y/n) "))) {
632 log_err(_("The corrupt directory entry was not fixed.\n"));
633 goto out;
634 }
635 decr_link_count(cx, entry->in_addr, ip->i_num.in_addr, _("bad original reference"));
636 lgfs2_dirent2_del(ip, bh, prev, dent);
637 log_err(_("The corrupt directory entry '%s' was deleted.\n"), fn);
638 out:
639 return -1; /* force check_dir to stop; don't waste time. */
640 }
641
642 /**
643 * check_suspicious_dirref - double-check a questionable first dentry ref
644 *
645 * This function is called when a dentry has caused us to increment the
646 * link count to a file from 1 to 2, and we know the object pointed to is
647 * not a directory. (Most likely, it'a a file). The second directory to
648 * reference the dinode has the correct formal inode number, but when we
649 * created the original reference in the counted links bitmap (clink1map),
650 * we had no way to check the formal inode number. (Well, we could have read
651 * in the dinode, but that would kill fsck.gfs2 performance.)
652 * So now we have to walk through the directory tree and find that original
653 * reference so make sure it's a valid reference. If the formal inode number
654 * is the same, it's a hard link (which is unlikely for gfs2). If it's not
655 * the same, that's an error, and we need to delete the damaged original
656 * dentry, since we failed to detect the problem earlier.
657 */
658 static int check_suspicious_dirref(struct fsck_cx *cx, struct lgfs2_inum *entry)
659 {
660 struct osi_node *tmp, *next = NULL;
661 struct dir_info *dt;
662 struct lgfs2_inode *ip;
663 uint64_t dirblk;
664 int error = FSCK_OK;
665 struct metawalk_fxns dirref_hunt = {
666 .private = entry,
667 .check_dentry = dirref_find,
668 };
669
670 log_debug("This dentry is good, but since this is a second "
671 "reference to block 0x%"PRIx64", we need to check the "
672 "original.\n", entry->in_addr);
673 for (tmp = osi_first(&cx->dirtree); tmp; tmp = next) {
674 next = osi_next(tmp);
675 dt = (struct dir_info *)tmp;
676 dirblk = dt->dinode.in_addr;
677 if (skip_this_pass || fsck_abort) /* asked to skip the rest */
678 break;
679 ip = fsck_load_inode(cx->sdp, dirblk);
680 if (ip == NULL) {
681 stack;
682 return FSCK_ERROR;
683 }
684 error = check_dir(cx, ip, &dirref_hunt);
685 fsck_inode_put(&ip);
686 /* Error just means we found the dentry and dealt with it. */
687 if (error)
688 break;
689 }
690 log_debug("Original reference check complete. Found = %d.\n",
691 error ? 1 : 0);
692 return 0;
693 }
694
695 /* FIXME: should maybe refactor this a bit - but need to deal with
696 * FIXMEs internally first */
697 static int check_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent,
698 struct gfs2_dirent *prev_de,
699 struct lgfs2_buffer_head *bh, char *filename,
700 uint32_t *count, int *lindex, void *priv)
701 {
702 struct lgfs2_sbd *sdp = ip->i_sbd;
703 int q = 0;
704 char tmp_name[MAX_FILENAME];
705 struct lgfs2_inum entry;
706 struct dir_status *ds = (struct dir_status *) priv;
707 int error;
708 struct lgfs2_inode *entry_ip = NULL;
709 struct lgfs2_dirent d;
710 int hash_index; /* index into the hash table based on the hash */
711 int lindex_max; /* largest acceptable hash table index for hash */
712 int isdir;
713
714 lgfs2_dirent_in(&d, dent);
715
716 entry.in_addr = d.dr_inum.in_addr;
717 entry.in_formal_ino = d.dr_inum.in_formal_ino;
718
719 /* Start of checks */
720 memset(tmp_name, 0, MAX_FILENAME);
721 if (d.dr_name_len < MAX_FILENAME)
722 strncpy(tmp_name, filename, d.dr_name_len);
723 else
724 strncpy(tmp_name, filename, MAX_FILENAME - 1);
725
726 error = basic_dentry_checks(cx, ip, dent, &entry, tmp_name, count, &d,
727 ds, &q, bh, &isdir);
728 if (error)
729 goto nuke_dentry;
730
731 if (!strcmp(".", tmp_name)) {
732 log_debug(_("Found . dentry in directory %"PRIu64" (0x%"PRIx64")\n"),
733 ip->i_num.in_addr, ip->i_num.in_addr);
734
735 if (ds->dotdir) {
736 log_err(_("Already found '.' entry in directory %"PRIu64" (0x%"PRIx64")\n"),
737 ip->i_num.in_addr, ip->i_num.in_addr);
738 if (!query(cx, _("Clear duplicate '.' entry? (y/n) "))) {
739 log_err( _("Duplicate '.' entry remains\n"));
740 /* FIXME: Should we continue on here
741 * and check the rest of the '.' entry? */
742 goto dentry_is_valid;
743 }
744 if (ip->i_num.in_addr == entry.in_addr)
745 entry_ip = ip;
746 else
747 entry_ip = fsck_load_inode(sdp, entry.in_addr);
748 check_inode_eattr(cx, entry_ip, &delete_eattrs);
749 if (entry_ip != ip)
750 fsck_inode_put(&entry_ip);
751 goto nuke_dentry;
752 }
753
754 /* GFS2 does not rely on '.' being in a certain
755 * location */
756
757 /* check that '.' refers to this inode */
758 if (entry.in_addr != ip->i_num.in_addr) {
759 log_err(_("'.' entry's value incorrect in directory %"PRIu64" (0x%"PRIx64")."
760 " Points to %"PRIu64" (0x%"PRIx64") when it should point to %"PRIu64
761 " (0x%"PRIx64").\n"),
762 entry.in_addr, entry.in_addr, entry.in_addr, entry.in_addr,
763 ip->i_num.in_addr, ip->i_num.in_addr);
764 if (!query(cx, _("Remove '.' reference? (y/n) "))) {
765 log_err( _("Invalid '.' reference remains\n"));
766 /* Not setting ds->dotdir here since
767 * this '.' entry is invalid */
768 goto dentry_is_valid;
769 }
770 if (ip->i_num.in_addr == entry.in_addr)
771 entry_ip = ip;
772 else
773 entry_ip = fsck_load_inode(sdp, entry.in_addr);
774 check_inode_eattr(cx, entry_ip, &delete_eattrs);
775 if (entry_ip != ip)
776 fsck_inode_put(&entry_ip);
777 goto nuke_dentry;
778 }
779
780 ds->dotdir = 1;
781 goto dentry_is_valid;
782 }
783 if (!strcmp("..", tmp_name)) {
784 log_debug(_("Found '..' dentry in directory %"PRIu64" (0x%"PRIx64")\n"),
785 ip->i_num.in_addr, ip->i_num.in_addr);
786 if (ds->dotdotdir) {
787 log_err(_("Already had a '..' entry in directory %"PRIu64" (0x%"PRIx64")\n"),
788 ip->i_num.in_addr, ip->i_num.in_addr);
789 if (!query(cx, _("Clear duplicate '..' entry? (y/n) "))) {
790 log_err( _("Duplicate '..' entry remains\n"));
791 /* FIXME: Should we continue on here
792 * and check the rest of the '..'
793 * entry? */
794 goto dentry_is_valid;
795 }
796
797 if (ip->i_num.in_addr == entry.in_addr)
798 entry_ip = ip;
799 else
800 entry_ip = fsck_load_inode(sdp, entry.in_addr);
801 check_inode_eattr(cx, entry_ip, &delete_eattrs);
802 if (entry_ip != ip)
803 fsck_inode_put(&entry_ip);
804
805 goto nuke_dentry;
806 }
807 if (!isdir) {
808 log_err(_("Found '..' entry in directory %"PRIu64" (0x%"PRIx64") "
809 "pointing to something that's not a directory"),
810 ip->i_num.in_addr, ip->i_num.in_addr);
811 if (!query(cx, _("Clear bad '..' directory entry? (y/n) "))) {
812 log_err( _("Bad '..' directory entry remains\n"));
813 goto dentry_is_valid;
814 }
815 if (ip->i_num.in_addr == entry.in_addr)
816 entry_ip = ip;
817 else
818 entry_ip = fsck_load_inode(sdp, entry.in_addr);
819 check_inode_eattr(cx, entry_ip, &delete_eattrs);
820 if (entry_ip != ip)
821 fsck_inode_put(&entry_ip);
822
823 goto nuke_dentry;
824 }
825 /* GFS2 does not rely on '..' being in a certain location */
826
827 /* Add the address this entry is pointing to
828 * to this inode's dotdot_parent in
829 * dir_info */
830 if (set_dotdot_dir(cx, ip->i_num.in_addr, entry)) {
831 stack;
832 return -1;
833 }
834
835 ds->dotdotdir = 1;
836 goto dentry_is_valid;
837 }
838 /* If this is an exhash directory, make sure the dentries in the leaf
839 block have a hash table index that fits */
840 if (ip->i_flags & GFS2_DIF_EXHASH) {
841 hash_index = hash_table_index(d.dr_hash, ip);
842 lindex_max = hash_table_max(*lindex, ip, bh);
843 if (hash_index < *lindex || hash_index > lindex_max) {
844 int nuke_dent;
845
846 nuke_dent = wrong_leaf(cx, ip, &entry, tmp_name, lindex,
847 lindex_max, hash_index, bh, ds,
848 dent, &d, prev_de, count, q);
849 if (nuke_dent)
850 goto nuke_dentry;
851 }
852 }
853
854 /* After this point we're only concerned with directories */
855 if (!isdir) {
856 log_debug(_("Found non-dir inode dentry pointing to %"PRIu64" (0x%"PRIx64")\n"),
857 entry.in_addr, entry.in_addr);
858 goto dentry_is_valid;
859 }
860
861 /*log_debug( _("Found plain directory dentry\n"));*/
862 error = set_parent_dir(cx, entry, ip->i_num);
863 if (error > 0) {
864 log_err(_("%s: Hard link to block %"PRIu64" (0x%"PRIx64") detected.\n"),
865 tmp_name, entry.in_addr, entry.in_addr);
866
867 if (query(cx, _("Clear hard link to directory? (y/n) ")))
868 goto nuke_dentry;
869 else {
870 log_err( _("Hard link to directory remains\n"));
871 goto dentry_is_valid;
872 }
873 } else if (error < 0) {
874 stack;
875 return -1;
876 }
877 dentry_is_valid:
878 /* This directory inode links to this inode via this dentry */
879 error = incr_link_count(cx, entry, ip, _("valid reference"));
880 if (error == INCR_LINK_CHECK_ORIG) {
881 error = check_suspicious_dirref(cx, &entry);
882 } else if (error == INCR_LINK_INO_MISMATCH) {
883 log_err("incr_link_count err=%d.\n", error);
884 if (bad_formal_ino(cx, ip, dent, entry, tmp_name, q, &d, bh) == 1)
885 goto nuke_dentry;
886 }
887 (*count)++;
888 ds->entry_count++;
889 /* End of checks */
890 return 0;
891
892 nuke_dentry:
893 lgfs2_dirent2_del(ip, bh, prev_de, dent);
894 log_err( _("Bad directory entry '%s' cleared.\n"), tmp_name);
895 return 1;
896 }
897
898 /*
899 * write_new_leaf - allocate and write a new leaf to cover a gap in hash table
900 * @dip: the directory inode
901 * @start_lindex: where in the hash table to start writing
902 * @num_copies: number of copies of the pointer to write into hash table
903 * @before_or_after: desc. of whether this is being added before/after/etc.
904 * @bn: pointer to return the newly allocated leaf's block number
905 */
906 static int write_new_leaf(struct fsck_cx *cx, struct lgfs2_inode *dip, int start_lindex,
907 int num_copies, const char *before_or_after,
908 uint64_t *bn)
909 {
910 struct lgfs2_buffer_head *nbh;
911 struct gfs2_leaf *leaf;
912 struct gfs2_dirent *dent;
913 int count, i;
914 int factor = 0, pad_size;
915 __be64 *padbuf, *cpyptr;
916 int divisor = num_copies;
917 int end_lindex = start_lindex + num_copies;
918
919 padbuf = calloc(num_copies, sizeof(__be64));
920 if (padbuf == NULL)
921 return -1;
922 /* calculate the depth needed for the new leaf */
923 while (divisor > 1) {
924 factor++;
925 divisor /= 2;
926 }
927 /* Make sure the number of copies is properly a factor of 2 */
928 if ((1 << factor) != num_copies) {
929 log_err(_("Program error: num_copies not a factor of 2.\n"));
930 log_err(_("num_copies=%d, dinode = %"PRIu64" (0x%"PRIx64")\n"),
931 num_copies, dip->i_num.in_addr, dip->i_num.in_addr);
932 log_err(_("lindex = %d (0x%x)\n"), start_lindex, start_lindex);
933 stack;
934 free(padbuf);
935 return -1;
936 }
937
938 /* allocate and write out a new leaf block */
939 if (lgfs2_meta_alloc(dip, bn)) {
940 log_err( _("Error: allocation failed while fixing directory leaf "
941 "pointers.\n"));
942 free(padbuf);
943 return -1;
944 }
945 fsck_bitmap_set(cx, dip, *bn, _("directory leaf"), GFS2_BLKST_USED);
946 log_err(_("A new directory leaf was allocated at block %"PRIu64" "
947 "(0x%"PRIx64") to fill the %d (0x%x) pointer gap %s the existing "
948 "pointer at index %d (0x%x).\n"), *bn, *bn,
949 num_copies, num_copies,
950 before_or_after, start_lindex, start_lindex);
951 dip->i_blocks++;
952 lgfs2_bmodified(dip->i_bh);
953 nbh = lgfs2_bget(dip->i_sbd, *bn);
954 memset(nbh->b_data, 0, dip->i_sbd->sd_bsize);
955 leaf = (struct gfs2_leaf *)nbh->b_data;
956 leaf->lf_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
957 leaf->lf_header.mh_type = cpu_to_be32(GFS2_METATYPE_LF);
958 leaf->lf_header.mh_format = cpu_to_be32(GFS2_FORMAT_LF);
959 leaf->lf_depth = cpu_to_be16(dip->i_depth - factor);
960
961 /* initialize the first dirent on the new leaf block */
962 dent = (struct gfs2_dirent *)(nbh->b_data + sizeof(struct gfs2_leaf));
963 dent->de_rec_len = cpu_to_be16(dip->i_sbd->sd_bsize -
964 sizeof(struct gfs2_leaf));
965 lgfs2_bmodified(nbh);
966 lgfs2_brelse(nbh);
967
968 /* pad the hash table with the new leaf block */
969 cpyptr = padbuf;
970 for (i = start_lindex; i < end_lindex; i++) {
971 *cpyptr = cpu_to_be64(*bn);
972 cpyptr++;
973 }
974 pad_size = num_copies * sizeof(uint64_t);
975 log_err(_("Writing to the hash table of directory %"PRIu64
976 " (0x%"PRIx64") at index: 0x%x for 0x%lx pointers.\n"),
977 dip->i_num.in_addr, dip->i_num.in_addr,
978 start_lindex, (unsigned long)pad_size / sizeof(uint64_t));
979 count = lgfs2_writei(dip, padbuf, start_lindex * sizeof(uint64_t), pad_size);
980 free(padbuf);
981 if (count != pad_size) {
982 log_err( _("Error: bad write while fixing directory leaf "
983 "pointers.\n"));
984 return -1;
985 }
986 return 0;
987 }
988
989 /* pad_with_leafblks - pad a hash table with pointers to new leaf blocks
990 *
991 * @ip: pointer to the dinode structure
992 * @tbl: pointer to the hash table in memory
993 * @lindex: index location within the hash table to pad
994 * @len: number of pointers to be padded
995 */
996 static void pad_with_leafblks(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl,
997 int lindex, int len)
998 {
999 int new_len, i;
1000 uint32_t proper_start = lindex;
1001 uint64_t new_leaf_blk;
1002
1003 log_err(_("Padding inode %"PRIu64" (0x%"PRIx64") hash table at offset %d (0x%x) "
1004 "for %d pointers.\n"),
1005 ip->i_num.in_addr, ip->i_num.in_addr, lindex, lindex, len);
1006 while (len) {
1007 new_len = 1;
1008 /* Determine the next factor of 2 down from extras. We can't
1009 just write out a leaf block on a power-of-two boundary.
1010 We also need to make sure it has a length that will
1011 ensure a "proper start" block as well. */
1012 while ((new_len << 1) <= len) {
1013 /* Translation: If doubling the size of the new leaf
1014 will make its start boundary wrong, we have to
1015 settle for a smaller length (and iterate more). */
1016 proper_start = (lindex & ~((new_len << 1) - 1));
1017 if (lindex != proper_start)
1018 break;
1019 new_len <<= 1;
1020 }
1021 write_new_leaf(cx, ip, lindex, new_len, "after", &new_leaf_blk);
1022 log_err(_("New leaf block was allocated at %"PRIu64" (0x%"PRIx64") for "
1023 "index %d (0x%x), length %d\n"),
1024 new_leaf_blk, new_leaf_blk, lindex, lindex, new_len);
1025 fsck_bitmap_set(cx, ip, new_leaf_blk, _("pad leaf"), GFS2_BLKST_USED);
1026 /* Fix the hash table in memory to have the new leaf */
1027 for (i = 0; i < new_len; i++)
1028 tbl[lindex + i] = cpu_to_be64(new_leaf_blk);
1029 len -= new_len;
1030 lindex += new_len;
1031 }
1032 }
1033
1034 /* lost_leaf - repair a leaf block that's on the wrong directory inode
1035 *
1036 * If the correct index is less than the starting index, we have a problem.
1037 * Since we process the index sequentially, the previous index has already
1038 * been processed, fixed, and is now correct. But this leaf wants to overwrite
1039 * a previously written good leaf. The only thing we can do is move all the
1040 * directory entries to lost+found so we don't overwrite the good leaf. Then
1041 * we need to pad the gap we leave.
1042 */
1043 static int lost_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, uint64_t leafno,
1044 int ref_count, int lindex, struct lgfs2_buffer_head *bh)
1045 {
1046 char *filename;
1047 char *bh_end = bh->b_data + ip->i_sbd->sd_bsize;
1048 struct gfs2_dirent *dent;
1049 struct lgfs2_dirent de;
1050 int error;
1051 int isdir = 0;
1052
1053 log_err(_("Leaf block %"PRIu64" (0x%"PRIx64") seems to be out of place and its "
1054 "contents need to be moved to lost+found.\n"),
1055 leafno, leafno);
1056 if (!query(cx, _("Attempt to fix it? (y/n) "))) {
1057 log_err( _("Directory leaf was not fixed.\n"));
1058 return 0;
1059 }
1060 make_sure_lf_exists(cx, ip);
1061
1062 dent = (struct gfs2_dirent *)(bh->b_data + sizeof(struct gfs2_leaf));
1063 while (1) {
1064 char tmp_name[PATH_MAX];
1065
1066 memset(&de, 0, sizeof(de));
1067 lgfs2_dirent_in(&de, dent);
1068 filename = (char *)dent + sizeof(struct gfs2_dirent);
1069 memset(tmp_name, 0, sizeof(tmp_name));
1070 if (de.dr_name_len > sizeof(filename)) {
1071 log_debug(_("Encountered bad filename length; "
1072 "stopped processing.\n"));
1073 break;
1074 }
1075 memcpy(tmp_name, filename, de.dr_name_len);
1076 if ((de.dr_name_len == 1 && filename[0] == '.')) {
1077 log_debug(_("Skipping entry '.'\n"));
1078 } else if (de.dr_name_len == 2 && filename[0] == '.' &&
1079 filename[1] == '.') {
1080 log_debug(_("Skipping entry '..'\n"));
1081 } else if (!de.dr_inum.in_formal_ino) { /* sentinel */
1082 log_debug(_("Skipping sentinel '%s'\n"), tmp_name);
1083 } else {
1084 uint32_t count = 0;
1085 struct dir_status ds = {0};
1086 int q = 0;
1087
1088 error = basic_dentry_checks(cx, ip, dent, &de.dr_inum,
1089 tmp_name, &count, &de,
1090 &ds, &q, bh, &isdir);
1091 if (error) {
1092 log_err(_("Not relocating corrupt entry "
1093 "\"%s\".\n"), tmp_name);
1094 } else {
1095
1096 error = lgfs2_dir_add(lf_dip, filename,
1097 de.dr_name_len, &de.dr_inum,
1098 de.dr_type);
1099 if (error && error != -EEXIST) {
1100 log_err(_("Error %d encountered while "
1101 "trying to relocate \"%s\" "
1102 "to lost+found.\n"), error,
1103 tmp_name);
1104 return error;
1105 }
1106 /* This inode is linked from lost+found */
1107 incr_link_count(cx, de.dr_inum, lf_dip,
1108 _("from lost+found"));
1109 /* If it's a directory, lost+found is
1110 back-linked to it via .. */
1111 if (isdir) {
1112 struct lgfs2_inum no = lf_dip->i_num;
1113 incr_link_count(cx, no, NULL, _("to lost+found"));
1114 }
1115 log_err(_("Relocated \"%s\", block %"PRIu64" (0x%"PRIx64") to lost+found.\n"),
1116 tmp_name, de.dr_inum.in_addr, de.dr_inum.in_addr);
1117 }
1118 }
1119 if ((char *)dent + de.dr_rec_len >= bh_end)
1120 break;
1121 dent = (struct gfs2_dirent *)((char *)dent + de.dr_rec_len);
1122 }
1123 log_err(_("Directory entries from misplaced leaf block were relocated "
1124 "to lost+found.\n"));
1125 /* Free the lost leaf. */
1126 fsck_bitmap_set(cx, ip, leafno, _("lost leaf"), GFS2_BLKST_FREE);
1127 ip->i_blocks--;
1128 lgfs2_bmodified(ip->i_bh);
1129 /* Now we have to deal with the bad hash table entries pointing to the
1130 misplaced leaf block. But we can't just fill the gap with a single
1131 leaf. We have to write on nice power-of-two boundaries, and we have
1132 to pad out any extra pointers. */
1133 pad_with_leafblks(cx, ip, tbl, lindex, ref_count);
1134 return 1;
1135 }
1136
1137 static int basic_check_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent,
1138 struct gfs2_dirent *prev_de,
1139 struct lgfs2_buffer_head *bh, char *filename,
1140 uint32_t *count, int *lindex, void *priv)
1141 {
1142 int q = 0;
1143 char tmp_name[MAX_FILENAME];
1144 struct lgfs2_inum entry;
1145 struct dir_status *ds = (struct dir_status *) priv;
1146 struct lgfs2_dirent dentry, *de;
1147 int error;
1148 int isdir;
1149
1150 memset(&dentry, 0, sizeof(dentry));
1151 lgfs2_dirent_in(&dentry, dent);
1152 de = &dentry;
1153
1154 entry.in_addr = de->dr_inum.in_addr;
1155 entry.in_formal_ino = de->dr_inum.in_formal_ino;
1156
1157 /* Start of checks */
1158 memset(tmp_name, 0, MAX_FILENAME);
1159 if (de->dr_name_len < MAX_FILENAME)
1160 strncpy(tmp_name, filename, de->dr_name_len);
1161 else
1162 strncpy(tmp_name, filename, MAX_FILENAME - 1);
1163
1164 error = basic_dentry_checks(cx, ip, dent, &entry, tmp_name, count, de,
1165 ds, &q, bh, &isdir);
1166 if (error) {
1167 lgfs2_dirent2_del(ip, bh, prev_de, dent);
1168 log_err( _("Bad directory entry '%s' cleared.\n"), tmp_name);
1169 return 1;
1170 } else {
1171 (*count)++;
1172 return 0;
1173 }
1174 }
1175
1176 /* pass2_repair_leaf - Warn the user of an error and ask permission to fix it
1177 * Process a bad leaf pointer and ask to repair the first time.
1178 * The repair process involves extending the previous leaf's entries
1179 * so that they replace the bad ones. We have to hack up the old
1180 * leaf a bit, but it's better than deleting the whole directory,
1181 * which is what used to happen before. */
1182 static int pass2_repair_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t *leaf_no,
1183 int lindex, int ref_count, const char *msg)
1184 {
1185 int new_leaf_blks = 0, error, refs;
1186 uint64_t bn = 0;
1187
1188 log_err(_("Directory Inode %"PRIu64" (0x%"PRIx64") points to leaf %"PRIu64" (0x%"PRIx64") %s.\n"),
1189 ip->i_num.in_addr, ip->i_num.in_addr, *leaf_no, *leaf_no, msg);
1190 if (!query(cx, _("Attempt to patch around it? (y/n) "))) {
1191 log_err( _("Bad leaf left in place.\n"));
1192 goto out;
1193 }
1194 /* We can only write leafs in quantities that are factors of
1195 two, since leaves are doubled, not added sequentially.
1196 So if we have a hole that's not a factor of 2, we have to
1197 break it down into separate leaf blocks that are. */
1198 while (ref_count) {
1199 refs = 1;
1200 while (refs <= ref_count) {
1201 if (refs * 2 > ref_count)
1202 break;
1203 refs *= 2;
1204 }
1205 error = write_new_leaf(cx, ip, lindex, refs, _("replacing"), &bn);
1206 if (error)
1207 return error;
1208
1209 new_leaf_blks++;
1210 lindex += refs;
1211 ref_count -= refs;
1212 }
1213 log_err(_("Directory Inode %"PRIu64" (0x%"PRIx64") repaired.\n"),
1214 ip->i_num.in_addr, ip->i_num.in_addr);
1215 out:
1216 *leaf_no = bn;
1217 return new_leaf_blks;
1218 }
1219
1220 /* The purpose of leafck_fxns is to provide a means for function fix_hashtable
1221 * to do basic sanity checks on leaf blocks before manipulating them, for
1222 * example, splitting them. If they're corrupt, splitting them or trying to
1223 * move their contents can cause a segfault. We can't really use the standard
1224 * pass2_fxns because that will do things we don't want. For example, it will
1225 * find '.' and '..' and increment the directory link count, which would be
1226 * done a second time when the dirent is really checked in pass2_fxns.
1227 * We don't want it to do the "wrong leaf" thing, or set_parent_dir either.
1228 * We just want a basic sanity check on pointers and lengths.
1229 */
1230 static struct metawalk_fxns leafck_fxns = {
1231 .check_leaf_depth = check_leaf_depth,
1232 .check_dentry = basic_check_dentry,
1233 .repair_leaf = pass2_repair_leaf,
1234 };
1235
1236 /* fix_hashtable - fix a corrupt hash table
1237 *
1238 * The main intent of this function is to sort out hash table problems.
1239 * That is, it needs to determine if leaf blocks are in the wrong place,
1240 * if the count of pointers is wrong, and if there are extra pointers.
1241 * Everything should be placed on correct power-of-two boundaries appropriate
1242 * to their leaf depth, and extra pointers should be correctly padded with new
1243 * leaf blocks.
1244 *
1245 * @ip: the directory dinode structure pointer
1246 * @tbl: hash table that's already read into memory
1247 * @hsize: hash table size, as dictated by the dinode's di_depth
1248 * @leafblk: the leaf block number that appears at this lindex in the tbl
1249 * @lindex: leaf index that has a problem
1250 * @proper_start: where this leaf's pointers should start, as far as the
1251 * hash table is concerned (sight unseen; trusting the leaf
1252 * really belongs here).
1253 * @len: count of pointers in the hash table to this leafblk
1254 * @proper_len: pointer to return the proper number of pointers, as the kernel
1255 * calculates it, based on the leaf depth.
1256 * @factor: the proper depth, given this number of pointers (rounded down).
1257 *
1258 * Returns: 0 - no changes made, or X if changes were made
1259 */
1260 static int fix_hashtable(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize,
1261 uint64_t leafblk, int lindex, uint32_t proper_start,
1262 int len, int *proper_len, int factor)
1263 {
1264 struct lgfs2_buffer_head *lbh;
1265 struct lgfs2_dirent dentry;
1266 struct lgfs2_leaf leaf;
1267 struct gfs2_dirent *de;
1268 int changes = 0, error, i, extras, hash_index;
1269 uint64_t new_leaf_blk;
1270 uint64_t leaf_no;
1271 uint32_t leaf_proper_start;
1272
1273 *proper_len = len;
1274 log_err(_("Dinode %"PRIu64" (0x%"PRIx64") has a hash table error at index "
1275 "0x%x, length 0x%x: leaf block %"PRIu64" (0x%"PRIx64")\n"),
1276 ip->i_num.in_addr, ip->i_num.in_addr, lindex, len, leafblk, leafblk);
1277 if (!query(cx, _("Fix the hash table? (y/n) "))) {
1278 log_err(_("Hash table not fixed.\n"));
1279 return 0;
1280 }
1281
1282 memset(&leaf, 0, sizeof(leaf));
1283 leaf_no = leafblk;
1284 error = check_leaf(cx, ip, lindex, &leafck_fxns, &leaf_no, &leaf, &len);
1285 if (error)
1286 log_debug("Leaf repaired while fixing the hash table.\n");
1287 lbh = lgfs2_bread(ip->i_sbd, leafblk);
1288 /* If the leaf's depth is out of range for this dinode, it's obviously
1289 attached to the wrong dinode. Move the dirents to lost+found. */
1290 if (leaf.lf_depth > ip->i_depth) {
1291 log_err(_("This leaf block's depth (%d) is too big for this "
1292 "dinode's depth (%d)\n"),
1293 leaf.lf_depth, ip->i_depth);
1294 error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh);
1295 lgfs2_brelse(lbh);
1296 return error;
1297 }
1298
1299 memset(&dentry, 0, sizeof(dentry));
1300 de = (struct gfs2_dirent *)(lbh->b_data + sizeof(struct gfs2_leaf));
1301 lgfs2_dirent_in(&dentry, de);
1302
1303 /* If this is an empty leaf, we can just delete it and pad. */
1304 if ((dentry.dr_rec_len == ip->i_sbd->sd_bsize - sizeof(struct gfs2_leaf)) &&
1305 (dentry.dr_inum.in_formal_ino == 0)) {
1306 lgfs2_brelse(lbh);
1307 lgfs2_free_block(ip->i_sbd, leafblk);
1308 ip->i_blocks--;
1309 log_err(_("Out of place leaf block %"PRIu64" (0x%"PRIx64") had no "
1310 "entries, so it was deleted.\n"),
1311 leafblk, leafblk);
1312 pad_with_leafblks(cx, ip, tbl, lindex, len);
1313 log_err(_("Reprocessing index 0x%x (case 1).\n"), lindex);
1314 return 1;
1315 }
1316
1317 /* Calculate the proper number of pointers based on the leaf depth. */
1318 *proper_len = 1 << (ip->i_depth - leaf.lf_depth);
1319
1320 /* Look at the first dirent and check its hash value to see if it's
1321 at the proper starting offset. */
1322 hash_index = hash_table_index(dentry.dr_hash, ip);
1323 /* Need to use len here, not *proper_len because the leaf block may
1324 be valid within the range, but starts too soon in the hash table. */
1325 if (hash_index < lindex || hash_index > lindex + len) {
1326 log_err(_("This leaf block has hash index %d, which is out of "
1327 "bounds for where it appears in the hash table "
1328 "(%d - %d)\n"),
1329 hash_index, lindex, lindex + *proper_len);
1330 error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh);
1331 lgfs2_brelse(lbh);
1332 return error;
1333 }
1334
1335 /* Now figure out where this leaf should start, and pad any pointers
1336 up to that point with new leaf blocks. */
1337 leaf_proper_start = (hash_index & ~(*proper_len - 1));
1338 if (lindex < leaf_proper_start) {
1339 log_err(_("Leaf pointers start at %d (0x%x), should be %d "
1340 "(%x).\n"), lindex, lindex,
1341 leaf_proper_start, leaf_proper_start);
1342 pad_with_leafblks(cx, ip, tbl, lindex, leaf_proper_start - lindex);
1343 lgfs2_brelse(lbh);
1344 return 1; /* reprocess the starting lindex */
1345 }
1346 /* If the proper start according to the leaf's hash index is later
1347 than the proper start according to the hash table, it's once
1348 again lost and we have to relocate it. The same applies if the
1349 leaf's hash index is prior to the proper state, but the leaf is
1350 already at its maximum depth. */
1351 if ((leaf_proper_start < proper_start) ||
1352 ((*proper_len > len || lindex > leaf_proper_start) &&
1353 leaf.lf_depth == ip->i_depth)) {
1354 log_err(_("Leaf block should start at 0x%x, but it appears at "
1355 "0x%x in the hash table.\n"), leaf_proper_start,
1356 proper_start);
1357 error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh);
1358 lgfs2_brelse(lbh);
1359 return error;
1360 }
1361
1362 /* If we SHOULD have more pointers than we do, we can solve the
1363 problem by splitting the block to a lower depth. Then we may have
1364 the right number of pointers. If the leaf block pointers start
1365 later than they should, we can split the leaf to give it a smaller
1366 footprint in the hash table. */
1367 if ((*proper_len > len || lindex > leaf_proper_start) &&
1368 ip->i_depth > leaf.lf_depth) {
1369 log_err(_("For depth %d, length %d, the proper start is: "
1370 "0x%x.\n"), factor, len, proper_start);
1371 changes++;
1372 new_leaf_blk = find_free_blk(ip->i_sbd);
1373 if (lgfs2_dir_split_leaf(ip, lindex, leafblk, lbh)) {
1374 log_crit(_("Failed to split directory leaf block at 0x%"PRIx64": %s\n"),
1375 ip->i_num.in_addr, strerror(errno));
1376 exit(1);
1377 }
1378 /* re-read the leaf to pick up lgfs2_dir_split_leaf's changes */
1379 lgfs2_leaf_in(&leaf, lbh->b_data);
1380 *proper_len = 1 << (ip->i_depth - leaf.lf_depth);
1381 log_err(_("Leaf block %"PRIu64" (0x%"PRIx64") was split from length %d to %d\n"),
1382 leafblk, leafblk, len, *proper_len);
1383 if (*proper_len < 0) {
1384 log_err(_("Programming error: proper_len=%d, "
1385 "di_depth = %d, lf_depth = %d.\n"),
1386 *proper_len, ip->i_depth, leaf.lf_depth);
1387 exit(FSCK_ERROR);
1388 }
1389 log_err(_("New split-off leaf block was allocated at %"PRIu64" "
1390 "(0x%"PRIx64") for index %d (0x%x)\n"),
1391 new_leaf_blk, new_leaf_blk, lindex, lindex);
1392 fsck_bitmap_set(cx, ip, new_leaf_blk, _("split leaf"), GFS2_BLKST_USED);
1393 log_err(_("Hash table repaired.\n"));
1394 /* Fix up the hash table in memory to include the new leaf */
1395 for (i = 0; i < *proper_len; i++)
1396 tbl[lindex + i] = cpu_to_be64(new_leaf_blk);
1397 if (*proper_len < (len >> 1)) {
1398 log_err(_("One leaf split is not enough. The hash "
1399 "table will need to be reprocessed.\n"));
1400 lgfs2_brelse(lbh);
1401 return changes;
1402 }
1403 lindex += (*proper_len); /* skip the new leaf from the split */
1404 len -= (*proper_len);
1405 }
1406 if (*proper_len < len) {
1407 log_err(_("There are %d pointers, but leaf 0x%"PRIx64"'s "
1408 "depth, %d, only allows %d\n"),
1409 len, leafblk, leaf.lf_depth,
1410 *proper_len);
1411 }
1412 lgfs2_brelse(lbh);
1413 /* At this point, lindex should be at the proper end of the pointers.
1414 Now we need to replace any extra duplicate pointers to the old
1415 (original) leafblk (that ran off the end) with new leaf blocks. */
1416 lindex += (*proper_len); /* Skip past the normal good pointers */
1417 len -= (*proper_len);
1418 extras = 0;
1419 for (i = 0; i < len; i++) {
1420 if (be64_to_cpu(tbl[lindex + i]) == leafblk)
1421 extras++;
1422 else
1423 break;
1424 }
1425 if (extras) {
1426 log_err(_("Found %d extra pointers to leaf %"PRIu64" (0x%"PRIx64")\n"),
1427 extras, leafblk, leafblk);
1428 pad_with_leafblks(cx, ip, tbl, lindex, extras);
1429 log_err(_("Reprocessing index 0x%x (case 2).\n"), lindex);
1430 return 1;
1431 }
1432 return changes;
1433 }
1434
1435 /* check_hash_tbl_dups - check for the same leaf in multiple places */
1436 static int check_hash_tbl_dups(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl,
1437 unsigned hsize, int lindex, int len)
1438 {
1439 int l, len2;
1440 uint64_t leafblk, leaf_no;
1441 struct lgfs2_buffer_head *lbh;
1442 struct gfs2_leaf leaf;
1443 struct lgfs2_dirent dentry;
1444 struct gfs2_dirent *de;
1445 int hash_index; /* index into the hash table based on the hash */
1446
1447 leafblk = be64_to_cpu(tbl[lindex]);
1448 for (l = 0; l < hsize; l++) {
1449 if (l == lindex) { /* skip the valid reference */
1450 l += len - 1;
1451 continue;
1452 }
1453 if (be64_to_cpu(tbl[l]) != leafblk)
1454 continue;
1455
1456 for (len2 = 0; l + len2 < hsize; len2++) {
1457 if (l + len2 == lindex)
1458 break;
1459 if (be64_to_cpu(tbl[l + len2]) != leafblk)
1460 break;
1461 }
1462 log_err(_("Dinode %"PRIu64" (0x%"PRIx64") has duplicate leaf pointers "
1463 "to block %"PRIu64" (0x%"PRIx64") at offsets %u (0x%x) "
1464 "(for 0x%x) and %u (0x%x) (for 0x%x)\n"),
1465 ip->i_num.in_addr, ip->i_num.in_addr, leafblk, leafblk, lindex, lindex,
1466 len, l, l, len2);
1467
1468 /* See which set of references is valid: the one passed in
1469 or the duplicate we found. */
1470 memset(&leaf, 0, sizeof(leaf));
1471 leaf_no = leafblk;
1472 if (!valid_block_ip(ip, leaf_no)) /* Checked later */
1473 continue;
1474
1475 lbh = lgfs2_bread(ip->i_sbd, leafblk);
1476 if (lgfs2_check_meta(lbh->b_data, GFS2_METATYPE_LF)) { /* Chked later */
1477 lgfs2_brelse(lbh);
1478 continue;
1479 }
1480
1481 memset(&dentry, 0, sizeof(dentry));
1482 de = (struct gfs2_dirent *)(lbh->b_data + sizeof(struct gfs2_leaf));
1483 lgfs2_dirent_in(&dentry, de);
1484 hash_index = hash_table_index(dentry.dr_hash, ip);
1485 lgfs2_brelse(lbh);
1486 /* check the duplicate ref first */
1487 if (hash_index < l || hash_index > l + len2) {
1488 log_err(_("This leaf block has hash index %d, which "
1489 "is out of bounds for lindex (%d - %d)\n"),
1490 hash_index, l, l + len2);
1491 if (!query(cx, _("Fix the hash table? (y/n) "))) {
1492 log_err(_("Hash table not fixed.\n"));
1493 return 0;
1494 }
1495 /* Adjust the ondisk block count. The original value
1496 may have been correct without the duplicates but
1497 pass1 would have counted them and adjusted the
1498 count to include them. So we must subtract them. */
1499 ip->i_blocks--;
1500 lgfs2_bmodified(ip->i_bh);
1501 pad_with_leafblks(cx, ip, tbl, l, len2);
1502 } else {
1503 log_debug(_("Hash index 0x%x is the proper reference to leaf 0x%"PRIx64".\n"),
1504 l, leafblk);
1505 }
1506 /* Check the original ref: both references might be bad.
1507 If both were bad, just return and if we encounter it
1508 again, we'll treat it as new. If the original ref is not
1509 bad, keep looking for (and fixing) other instances. */
1510 if (hash_index < lindex || hash_index > lindex + len) {
1511 log_err(_("This leaf block has hash index %d, which "
1512 "is out of bounds for lindex (%d - %d).\n"),
1513 hash_index, lindex, lindex + len);
1514 if (!query(cx, _("Fix the hash table? (y/n) "))) {
1515 log_err(_("Hash table not fixed.\n"));
1516 return 0;
1517 }
1518 ip->i_blocks--;
1519 lgfs2_bmodified(ip->i_bh);
1520 pad_with_leafblks(cx, ip, tbl, lindex, len);
1521 /* At this point we know both copies are bad, so we
1522 return to start fresh */
1523 return -EFAULT;
1524 } else {
1525 log_debug(_("Hash index 0x%x is the proper reference to leaf 0x%"PRIx64".\n"),
1526 lindex, leafblk);
1527 }
1528 }
1529 return 0;
1530 }
1531
1532 /* check_hash_tbl - check that the hash table is sane
1533 *
1534 * We've got to make sure the hash table is sane. Each leaf needs to
1535 * be counted a proper power of 2. We can't just have 3 pointers to a leaf.
1536 * The number of pointers must correspond to the proper leaf depth, and they
1537 * must all fall on power-of-two boundaries. The leaf block pointers all need
1538 * to fall properly on these boundaries, otherwise the kernel code's
1539 * calculations will land it on the wrong leaf block while it's searching,
1540 * and the result will be files you can see with ls, but can't open, delete
1541 * or use them.
1542 *
1543 * The goal of this function is to check the hash table to make sure the
1544 * boundaries and lengths all line up properly, and if not, to fix it.
1545 *
1546 * Note: There's a delicate balance here, because this function gets called
1547 * BEFORE leaf blocks are checked by function check_leaf from function
1548 * check_leaf_blks: the hash table has to be sane before we can start
1549 * checking all the leaf blocks. And yet if there's hash table corruption
1550 * we may need to reference leaf blocks to fix it, which means we need
1551 * to check and/or fix a leaf block along the way.
1552 */
1553 static int check_hash_tbl(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl,
1554 unsigned hsize, void *private)
1555 {
1556 int error = 0;
1557 int lindex, len, proper_len, i, changes = 0;
1558 uint64_t leafblk;
1559 struct lgfs2_leaf leaf;
1560 struct lgfs2_buffer_head *lbh;
1561 int factor;
1562 uint32_t proper_start;
1563 int anomaly;
1564
1565 lindex = 0;
1566 while (lindex < hsize) {
1567 if (fsck_abort)
1568 return changes;
1569 len = 1;
1570 factor = 0;
1571 leafblk = be64_to_cpu(tbl[lindex]);
1572 anomaly = 0;
1573 while (lindex + (len << 1) - 1 < hsize) {
1574 uint32_t next_proper_start;
1575 if (be64_to_cpu(tbl[lindex + (len << 1) - 1]) !=
1576 leafblk)
1577 break;
1578 next_proper_start = (lindex & ~((len << 1) - 1));
1579 if (lindex != next_proper_start)
1580 anomaly = 1;
1581 /* Check if there are other values written between
1582 here and the next factor. */
1583 for (i = len; !anomaly && i + lindex < hsize &&
1584 i < (len << 1); i++)
1585 if (be64_to_cpu(tbl[lindex + i]) != leafblk)
1586 anomaly = 1;
1587 if (anomaly)
1588 break;
1589 len <<= 1;
1590 factor++;
1591 }
1592
1593 /* Check for leftover pointers after the factor of two: */
1594 proper_len = len; /* A factor of 2 that fits nicely */
1595 while (lindex + len < hsize &&
1596 be64_to_cpu(tbl[lindex + len]) == leafblk)
1597 len++;
1598
1599 /* See if that leaf block is valid. If not, write a new one
1600 that falls on a proper boundary. If it doesn't naturally,
1601 we may need more. */
1602 if (!valid_block_ip(ip, leafblk)) {
1603 uint64_t new_leafblk;
1604
1605 log_err(_("Dinode %"PRIu64" (0x%"PRIx64") has bad leaf pointers "
1606 "at offset %d for %d\n"),
1607 ip->i_num.in_addr, ip->i_num.in_addr, lindex, len);
1608 if (!query(cx, _("Fix the hash table? (y/n) "))) {
1609 log_err(_("Hash table not fixed.\n"));
1610 lindex += len;
1611 continue;
1612 }
1613 error = write_new_leaf(cx, ip, lindex, proper_len,
1614 _("replacing"), &new_leafblk);
1615 if (error)
1616 return error;
1617
1618 for (i = lindex; i < lindex + proper_len; i++)
1619 tbl[i] = cpu_to_be64(new_leafblk);
1620 lindex += proper_len;
1621 continue;
1622 }
1623
1624 if (check_hash_tbl_dups(cx, ip, tbl, hsize, lindex, len))
1625 continue;
1626
1627 /* Make sure they call on proper leaf-split boundaries. This
1628 is the calculation used by the kernel, and lgfs2_dir_split_leaf */
1629 proper_start = (lindex & ~(proper_len - 1));
1630 if (lindex != proper_start) {
1631 log_debug(_("lindex 0x%x is not a proper starting "
1632 "point for leaf %"PRIu64" (0x%"PRIx64"): 0x%"PRIx32"\n"),
1633 lindex, leafblk, leafblk, proper_start);
1634 changes = fix_hashtable(cx, ip, tbl, hsize, leafblk,
1635 lindex, proper_start, len,
1636 &proper_len, factor);
1637 /* Check if we need to split more leaf blocks */
1638 if (changes) {
1639 if (proper_len < (len >> 1))
1640 log_err(_("More leaf splits are "
1641 "needed; "));
1642 log_err(_("Reprocessing index 0x%x (case 3).\n"),
1643 lindex);
1644 continue; /* Make it reprocess the lindex */
1645 }
1646 }
1647 /* Check for extra pointers to this leaf. At this point, len
1648 is the number of pointers we have. proper_len is the proper
1649 number of pointers if the hash table is assumed correct.
1650 Function fix_hashtable will read in the leaf block and
1651 determine the "actual" proper length based on the leaf
1652 depth, and adjust the hash table accordingly. */
1653 if (len != proper_len) {
1654 log_err(_("Length %d (0x%x) is not a proper length "
1655 "for leaf %"PRIu64" (0x%"PRIx64"). Valid boundary "
1656 "assumed to be %d (0x%x).\n"), len, len,
1657 leafblk, leafblk, proper_len, proper_len);
1658 lbh = lgfs2_bread(ip->i_sbd, leafblk);
1659 lgfs2_leaf_in(&leaf, lbh->b_data);
1660 if (lgfs2_check_meta(lbh->b_data, GFS2_METATYPE_LF) ||
1661 leaf.lf_depth > ip->i_depth)
1662 leaf.lf_depth = factor;
1663 lgfs2_brelse(lbh);
1664 changes = fix_hashtable(cx, ip, tbl, hsize, leafblk,
1665 lindex, lindex, len,
1666 &proper_len, leaf.lf_depth);
1667 /* If fixing the hash table made changes, we can no
1668 longer count on the leaf block pointers all pointing
1669 to the same leaf (which is checked below). To avoid
1670 flagging another error, reprocess the offset. */
1671 if (changes) {
1672 log_err(_("Reprocessing index 0x%x (case 4).\n"),
1673 lindex);
1674 continue; /* Make it reprocess the lindex */
1675 }
1676 }
1677
1678 /* Now make sure they're all the same pointer */
1679 for (i = lindex; i < lindex + proper_len; i++) {
1680 if (fsck_abort)
1681 return changes;
1682
1683 if (be64_to_cpu(tbl[i]) == leafblk) /* No problem */
1684 continue;
1685
1686 log_err(_("Dinode %"PRIu64" (0x%"PRIx64") has a hash table "
1687 "inconsistency at index %d (0x%x) for %d\n"),
1688 ip->i_num.in_addr, ip->i_num.in_addr,
1689 i, i, len);
1690 if (!query(cx, _("Fix the hash table? (y/n) "))) {
1691 log_err(_("Hash table not fixed.\n"));
1692 continue;
1693 }
1694 changes++;
1695 /* Now we have to determine if the hash table is
1696 corrupt, or if the leaf has the wrong depth. */
1697 lbh = lgfs2_bread(ip->i_sbd, leafblk);
1698 lgfs2_leaf_in(&leaf, lbh->b_data);
1699 lgfs2_brelse(lbh);
1700 /* Calculate the expected pointer count based on the
1701 leaf depth. */
1702 proper_len = 1 << (ip->i_depth - leaf.lf_depth);
1703 if (proper_len != len) {
1704 log_debug(_("Length 0x%x is not proper for "
1705 "leaf %"PRIu64" (0x%"PRIx64"): 0x%x\n"),
1706 len, leafblk, leafblk,
1707 proper_len);
1708 changes = fix_hashtable(cx, ip, tbl, hsize,
1709 leafblk, lindex,
1710 lindex, len,
1711 &proper_len,
1712 leaf.lf_depth);
1713 break;
1714 }
1715 }
1716 lindex += proper_len;
1717 }
1718 if (!error && changes)
1719 error = 1;
1720 return error;
1721 }
1722
1723 static struct metawalk_fxns pass2_fxns = {
1724 .private = NULL,
1725 .check_leaf_depth = check_leaf_depth,
1726 .check_leaf = NULL,
1727 .check_metalist = NULL,
1728 .check_data = NULL,
1729 .check_eattr_indir = check_eattr_indir,
1730 .check_eattr_leaf = check_eattr_leaf,
1731 .check_dentry = check_dentry,
1732 .check_eattr_entry = NULL,
1733 .check_hash_tbl = check_hash_tbl,
1734 .repair_leaf = pass2_repair_leaf,
1735 };
1736
1737 static int check_metalist_qc(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h,
1738 int *is_valid, int *was_duplicate, void *private)
1739 {
1740 struct lgfs2_inode *ip = iptr.ipt_ip;
1741 uint64_t block = iptr_block(iptr);
1742
1743 *was_duplicate = 0;
1744 *is_valid = 1;
1745 *bh = lgfs2_bread(ip->i_sbd, block);
1746 return META_IS_GOOD;
1747 }
1748
1749 static int check_data_qc(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock,
1750 uint64_t block, void *private,
1751 struct lgfs2_buffer_head *bbh, __be64 *ptr)
1752 {
1753 struct lgfs2_buffer_head *bh;
1754
1755 /* At this point, basic data block checks have already been done,
1756 so we only need to make sure they're QC blocks. */
1757 if (!valid_block_ip(ip, block))
1758 return -1;
1759
1760 bh = lgfs2_bread(ip->i_sbd, block);
1761 if (lgfs2_check_meta(bh->b_data, GFS2_METATYPE_QC) != 0) {
1762 log_crit(_("Error: quota_change block at %"PRIu64" (0x%"PRIx64") is "
1763 "the wrong metadata type.\n"),
1764 block, block);
1765 lgfs2_brelse(bh);
1766 return -1;
1767 }
1768 lgfs2_brelse(bh);
1769 return 0;
1770 }
1771
1772 static struct metawalk_fxns quota_change_fxns = {
1773 .check_metalist = check_metalist_qc,
1774 .check_data = check_data_qc,
1775 };
1776
1777 /* check_pernode_for - verify a file within the system per_node directory
1778 * @x - index number X
1779 * @per_node - pointer to the per_node inode
1780 * @fn - system file name
1781 * @filelen - the file length the system file needs to be
1782 * @multiple - the file length must be a multiple (versus the exact value)
1783 * @pass - a metawalk function for checking the data blocks (if any)
1784 * @builder - a rebuild function for the file
1785 *
1786 * Returns: 0 if all went well, else error. */
1787 static int check_pernode_for(struct fsck_cx *cx, int x, struct lgfs2_inode *pernode, const char *fn,
1788 size_t filelen, int multiple,
1789 struct metawalk_fxns *pass,
1790 int builder(struct lgfs2_inode *per_node,
1791 unsigned int j))
1792 {
1793 struct lgfs2_inode *ip;
1794 int error, valid_size = 1;
1795
1796 log_debug(_("Checking system file %s\n"), fn);
1797 /* coverity[identity_transfer:SUPPRESS] */
1798 ip = lgfs2_lookupi(pernode, fn, strlen(fn));
1799 if (ip == NULL) {
1800 log_err(_("System file %s is missing.\n"), fn);
1801 if (!query(cx, _("Rebuild the system file? (y/n) ")))
1802 return 0;
1803 goto build_it;
1804 }
1805 if (!ip->i_size)
1806 valid_size = 0;
1807 else if (!multiple && ip->i_size != filelen)
1808 valid_size = 0;
1809 else if (multiple && (ip->i_size % filelen))
1810 valid_size = 0;
1811 if (!valid_size) {
1812 log_err(_("System file %s has an invalid size. Is %"PRIu64", should be %zu.\n"),
1813 fn, ip->i_size, filelen);
1814 if (!query(cx, _("Rebuild the system file? (y/n) ")))
1815 goto out_good;
1816 fsck_inode_put(&ip);
1817 goto build_it;
1818 }
1819 if (pass) {
1820 error = check_metatree(cx, ip, pass);
1821 if (!error)
1822 goto out_good;
1823 log_err(_("System file %s has bad contents.\n"), fn);
1824 if (!query(cx, _("Delete and rebuild the system file? (y/n) ")))
1825 goto out_good;
1826 check_metatree(cx, ip, &pass2_fxns_delete);
1827 fsck_inode_put(&ip);
1828 lgfs2_dirent_del(pernode, fn, strlen(fn));
1829 goto build_it;
1830 }
1831 out_good:
1832 fsck_inode_put(&ip);
1833 return 0;
1834
1835 build_it:
1836 if (builder(pernode, x)) {
1837 log_err(_("Error building %s\n"), fn);
1838 return -1;
1839 }
1840 ip = lgfs2_lookupi(pernode, fn, strlen(fn));
1841 if (ip == NULL) {
1842 log_err(_("Error rebuilding %s.\n"), fn);
1843 return -1;
1844 }
1845 fsck_bitmap_set(cx, ip, ip->i_num.in_addr, fn, GFS2_BLKST_DINODE);
1846 log_err(_("System file %s rebuilt.\n"), fn);
1847 goto out_good;
1848 }
1849
1850 static int build_inum_range(struct lgfs2_inode *per_node, unsigned int n)
1851 {
1852 struct lgfs2_inode *ip = lgfs2_build_inum_range(per_node, n);
1853
1854 if (ip == NULL)
1855 return 1;
1856 lgfs2_inode_put(&ip);
1857 return 0;
1858 }
1859
1860 static int build_statfs_change(struct lgfs2_inode *per_node, unsigned int n)
1861 {
1862 struct lgfs2_inode *ip = lgfs2_build_statfs_change(per_node, n);
1863
1864 if (ip == NULL)
1865 return 1;
1866 lgfs2_inode_put(&ip);
1867 return 0;
1868 }
1869
1870 static int build_quota_change(struct lgfs2_inode *per_node, unsigned int n)
1871 {
1872 struct lgfs2_inode *ip = lgfs2_build_quota_change(per_node, n, LGFS2_DEFAULT_QCSIZE);
1873
1874 if (ip == NULL)
1875 return 1;
1876 lgfs2_inode_put(&ip);
1877 return 0;
1878 }
1879
1880 /* Check system directory inode */
1881 /* Should work for all system directories: root, master, jindex, per_node */
1882 static int check_system_dir(struct fsck_cx *cx, struct lgfs2_inode *sysinode, const char *dirname,
1883 int builder(struct fsck_cx *cx))
1884 {
1885 uint64_t iblock = 0;
1886 struct dir_status ds = {0};
1887 int error = 0;
1888
|
(1) Event cond_true: |
Condition "print_level >= 6", taking true branch. |
1889 log_info( _("Checking system directory inode '%s'\n"), dirname);
1890
|
(2) Event cond_false: |
Condition "!sysinode", taking false branch. |
1891 if (!sysinode) {
1892 log_err( _("Failed to check '%s': sysinode is null\n"), dirname);
1893 stack;
1894 return -1;
|
(3) Event if_end: |
End of if statement. |
1895 }
1896
1897 iblock = sysinode->i_num.in_addr;
1898 ds.q = bitmap_type(sysinode->i_sbd, iblock);
1899
1900 pass2_fxns.private = (void *) &ds;
|
(4) Event cond_false: |
Condition "ds.q == 0", taking false branch. |
1901 if (ds.q == GFS2_BLKST_FREE) {
1902 /* First check that the directory's metatree is valid */
1903 error = check_metatree(cx, sysinode, &pass2_fxns);
1904 if (error < 0) {
1905 stack;
1906 return error;
1907 }
|
(5) Event if_end: |
End of if statement. |
1908 }
1909 error = check_dir(cx, sysinode, &pass2_fxns);
|
(6) Event cond_false: |
Condition "skip_this_pass", taking false branch. |
|
(7) Event cond_false: |
Condition "fsck_abort", taking false branch. |
1910 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
|
(8) Event if_end: |
End of if statement. |
1911 return FSCK_OK;
|
(9) Event cond_false: |
Condition "error < 0", taking false branch. |
1912 if (error < 0) {
1913 stack;
1914 return -1;
|
(10) Event if_end: |
End of if statement. |
1915 }
|
(11) Event cond_false: |
Condition "error > 0", taking false branch. |
1916 if (error > 0)
|
(12) Event if_end: |
End of if statement. |
1917 fsck_bitmap_set(cx, sysinode, iblock, dirname, GFS2_BLKST_FREE);
1918
|
(13) Event cond_false: |
Condition "check_inode_eattr(cx, sysinode, &pass2_fxns)", taking false branch. |
1919 if (check_inode_eattr(cx, sysinode, &pass2_fxns)) {
1920 stack;
1921 return -1;
|
(14) Event if_end: |
End of if statement. |
1922 }
|
(15) Event cond_true: |
Condition "!ds.dotdir", taking true branch. |
1923 if (!ds.dotdir) {
|
(16) Event cond_true: |
Condition "print_level >= 3", taking true branch. |
1924 log_err( _("No '.' entry found for %s directory.\n"), dirname);
|
(17) Event cond_true: |
Condition "fsck_query(cx, dcgettext(NULL, "Is it okay to add '.' entry? (y/n) ", 5))", taking true branch. |
1925 if (query(cx, _("Is it okay to add '.' entry? (y/n) "))) {
1926 struct lgfs2_inum no = sysinode->i_num;
|
(18) Event cond_true: |
Condition "print_level >= 4", taking true branch. |
1927 log_warn( _("Adding '.' entry\n"));
1928 error = lgfs2_dir_add(sysinode, ".", 1, &no, DT_DIR);
|
(19) Event cond_false: |
Condition "error", taking false branch. |
1929 if (error) {
1930 log_err(_("Error adding directory %s: %s\n"), "'.'",
1931 strerror(errno));
1932 return -errno;
|
(20) Event if_end: |
End of if statement. |
1933 }
1934 /* This system inode is linked to itself via '.' */
1935 incr_link_count(cx, no, sysinode, "sysinode \".\"");
1936 ds.entry_count++;
|
(21) Event if_fallthrough: |
Falling through to end of if statement. |
1937 } else
|
(22) Event if_end: |
End of if statement. |
1938 log_err( _("The directory was not fixed.\n"));
1939 }
|
(23) Event cond_true: |
Condition "sysinode->i_entries != ds.entry_count", taking true branch. |
1940 if (sysinode->i_entries != ds.entry_count) {
|
(24) Event cond_true: |
Condition "print_level >= 3", taking true branch. |
1941 log_err(_("%s inode %"PRIu64" (0x%"PRIx64"): Entries is %d - should be %d\n"),
1942 dirname, sysinode->i_num.in_addr, sysinode->i_num.in_addr, sysinode->i_entries,
1943 ds.entry_count);
|
(25) Event cond_true: |
Condition "fsck_query(cx, dcgettext(NULL, "Fix entries for %s inode %lu (0x%lx)? (y/n) ", 5), dirname, sysinode->i_num.in_addr, sysinode->i_num.in_addr)", taking true branch. |
1944 if (query(cx, _("Fix entries for %s inode %"PRIu64" (0x%"PRIx64")? (y/n) "),
1945 dirname, sysinode->i_num.in_addr, sysinode->i_num.in_addr)) {
1946 sysinode->i_entries = ds.entry_count;
1947 lgfs2_bmodified(sysinode->i_bh);
|
(26) Event cond_true: |
Condition "print_level >= 4", taking true branch. |
1948 log_warn( _("Entries updated\n"));
|
(27) Event if_fallthrough: |
Falling through to end of if statement. |
1949 } else {
1950 log_err(_("Entries for inode %"PRIu64" (0x%"PRIx64") left out of sync\n"),
1951 sysinode->i_num.in_addr, sysinode->i_num.in_addr);
|
(28) Event if_end: |
End of if statement. |
1952 }
1953 }
1954 error = 0;
|
(29) Event cond_true: |
Condition "sysinode == sysinode->i_sbd->md.pinode", taking true branch. |
1955 if (sysinode == sysinode->i_sbd->md.pinode) {
1956 int j;
1957 char fn[64];
1958
1959 /* Make sure all the per_node files are there, and valid */
|
(30) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(32) Event loop_begin: |
Jumped back to beginning of loop. |
|
(33) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(35) Event loop_begin: |
Jumped back to beginning of loop. |
|
(36) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(40) Event loop_begin: |
Jumped back to beginning of loop. |
|
(41) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(46) Event loop_begin: |
Jumped back to beginning of loop. |
|
(47) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(52) Event loop_begin: |
Jumped back to beginning of loop. |
|
(53) Event cond_true: |
Condition "j < sysinode->i_sbd->md.journals", taking true branch. |
|
(58) Event loop_begin: |
Jumped back to beginning of loop. |
|
(59) Event cond_false: |
Condition "j < sysinode->i_sbd->md.journals", taking false branch. |
1960 for (j = 0; j < sysinode->i_sbd->md.journals; j++) {
1961 sprintf(fn, "inum_range%d", j);
|
(42) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 16UL, 0, NULL, build_inum_range)" is deemed overflowed because at least one of its arguments has overflowed. |
|
(48) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 16UL, 0, NULL, build_inum_range)" is deemed underflowed because at least one of its arguments has underflowed. |
|
(54) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 16UL, 0, NULL, build_inum_range)" is deemed underflowed because at least one of its arguments has underflowed. |
| Also see events: |
[tainted_data_return][overflow][overflow][overflow][overflow][overflow][overflow][overflow][return_overflow] |
1962 error += check_pernode_for(cx, j, sysinode, fn, 16, 0,
1963 NULL, build_inum_range);
1964 sprintf(fn, "statfs_change%d", j);
|
(43) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 24UL, 0, NULL, build_statfs_change)" is deemed underflowed because at least one of its arguments has underflowed. |
|
(49) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 24UL, 0, NULL, build_statfs_change)" is deemed underflowed because at least one of its arguments has underflowed. |
|
(55) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 24UL, 0, NULL, build_statfs_change)" is deemed underflowed because at least one of its arguments has underflowed. |
| Also see events: |
[tainted_data_return][overflow][overflow][overflow][overflow][overflow][overflow][overflow][return_overflow] |
1965 error += check_pernode_for(cx, j, sysinode, fn, 24, 0,
1966 NULL, build_statfs_change);
1967 sprintf(fn, "quota_change%d", j);
|
(37) Event tainted_data_return: |
Called function "check_pernode_for(cx, j, sysinode, fn, 1048576UL, 1, "a_change_fxns, build_quota_change)", and a possible return value may be less than zero. |
|
(38) Event overflow: |
The expression "error" is considered to have possibly overflowed. |
|
(44) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 1048576UL, 1, "a_change_fxns, build_quota_change)" is deemed underflowed because at least one of its arguments has underflowed. |
|
(50) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 1048576UL, 1, "a_change_fxns, build_quota_change)" is deemed underflowed because at least one of its arguments has underflowed. |
|
(56) Event overflow: |
The expression "error += check_pernode_for(cx, j, sysinode, fn, 1048576UL, 1, "a_change_fxns, build_quota_change)" is deemed underflowed because at least one of its arguments has underflowed. |
| Also see events: |
[overflow][overflow][overflow][overflow][overflow][overflow][return_overflow] |
1968 error += check_pernode_for(cx, j, sysinode, fn, 1048576, 1,
1969 "a_change_fxns,
1970 build_quota_change);
|
(31) Event loop: |
Jumping back to the beginning of the loop. |
|
(34) Event loop: |
Jumping back to the beginning of the loop. |
|
(39) Event loop: |
Jumping back to the beginning of the loop. |
|
(45) Event loop: |
Jumping back to the beginning of the loop. |
|
(51) Event loop: |
Jumping back to the beginning of the loop. |
|
(57) Event loop: |
Jumping back to the beginning of the loop. |
|
(60) Event loop_end: |
Reached end of loop. |
1971 }
1972 }
1973 return error;
1974 }
1975
1976 /**
1977 * is_system_dir - determine if a given block is for a system directory.
1978 */
1979 static inline int is_system_dir(struct lgfs2_sbd *sdp, uint64_t block)
1980 {
1981 if (block == sdp->md.rooti->i_num.in_addr ||
1982 block == sdp->md.jiinode->i_num.in_addr ||
1983 block == sdp->md.pinode->i_num.in_addr ||
1984 block == sdp->master_dir->i_num.in_addr)
1985 return 1;
1986 return 0;
1987 }
1988
1989 static int pass2_check_dir(struct fsck_cx *cx, struct lgfs2_inode *ip)
1990 {
1991 uint64_t dirblk = ip->i_num.in_addr;
1992 struct dir_status ds = {0};
1993 int error;
1994
1995 pass2_fxns.private = &ds;
1996 error = check_dir(cx, ip, &pass2_fxns);
1997 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
1998 return FSCK_OK;
1999 if (error < 0) {
2000 stack;
2001 return FSCK_ERROR;
2002 }
2003 if (error > 0) {
2004 struct dir_info *di;
2005
2006 di = dirtree_find(cx, dirblk);
2007 if (!di) {
2008 stack;
2009 return FSCK_ERROR;
2010 }
2011 if (query(cx, _("Remove directory entry for bad inode %"PRIu64" (0x%"PRIx64") in %"PRIu64" (0x%"PRIx64")? (y/n)"),
2012 dirblk, dirblk, di->treewalk_parent, di->treewalk_parent)) {
2013 error = remove_dentry_from_dir(cx, di->treewalk_parent, dirblk);
2014 if (error < 0) {
2015 stack;
2016 return FSCK_ERROR;
2017 }
2018 if (error > 0) {
2019 log_warn(_("Unable to find dentry for %"PRIu64" (0x%"PRIx64") in %"PRIu64" (0x%"PRIx64")\n"),
2020 dirblk, dirblk, di->treewalk_parent, di->treewalk_parent);
2021 }
2022 log_warn(_("Directory entry removed\n"));
2023 } else
2024 log_err(_("Directory entry to invalid inode remains.\n"));
2025
2026 log_debug(_("Directory block %"PRIu64" (0x%"PRIx64") is now marked as 'invalid'\n"),
2027 dirblk, dirblk);
2028 check_n_fix_bitmap(cx, ip->i_rgd, dirblk, 0, GFS2_BLKST_FREE);
2029 }
2030
2031 if (!ds.dotdir) {
2032 log_err(_("No '.' entry found for directory inode at block %"PRIu64" (0x%"PRIx64")\n"),
2033 dirblk, dirblk);
2034
2035 if (query(cx, _("Is it okay to add '.' entry? (y/n) "))) {
2036 struct lgfs2_inum no = ip->i_num;
2037 error = lgfs2_dir_add(ip, ".", 1, &no, DT_DIR);
2038 if (error) {
2039 log_err(_("Error adding directory %s: %s\n"), "'.'",
2040 strerror(errno));
2041 return -errno;
2042 }
2043 /* directory links to itself via '.' */
2044 incr_link_count(cx, no, ip, _("\". (itself)\""));
2045 ds.entry_count++;
2046 log_err(_("The directory was fixed.\n"));
2047 } else {
2048 log_err(_("The directory was not fixed.\n"));
2049 }
2050 }
2051
2052 if (!fsck_abort && ip->i_entries != ds.entry_count) {
2053 log_err(_("Entries is %d - should be %d for inode block %"PRIu64" (0x%"PRIx64")\n"),
2054 ip->i_entries, ds.entry_count, ip->i_num.in_addr, ip->i_num.in_addr);
2055 if (query(cx, _("Fix the entry count? (y/n) "))) {
2056 ip->i_entries = ds.entry_count;
2057 lgfs2_bmodified(ip->i_bh);
2058 } else {
2059 log_err(_("The entry count was not fixed.\n"));
2060 }
2061 }
2062 return FSCK_OK;
2063 }
2064
2065 /* What i need to do in this pass is check that the dentries aren't
2066 * pointing to invalid blocks...and verify the contents of each
2067 * directory. and start filling in the directory info structure*/
2068
2069 /**
2070 * pass2 - check pathnames
2071 *
2072 * verify root inode
2073 * directory name length
2074 * entries in range
2075 */
2076 int pass2(struct fsck_cx *cx)
2077 {
2078 struct lgfs2_sbd *sdp = cx->sdp;
2079 struct osi_node *tmp, *next = NULL;
2080 struct lgfs2_inode *ip;
2081 struct dir_info *dt;
2082 uint64_t dirblk;
2083 int error;
2084
2085 /* Check all the system directory inodes. */
2086 if (check_system_dir(cx, sdp->md.jiinode, "jindex", build_jindex)) {
2087 stack;
2088 return FSCK_ERROR;
2089 }
2090 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
2091 return FSCK_OK;
2092 if (check_system_dir(cx, sdp->md.pinode, "per_node", build_per_node)) {
2093 stack;
2094 return FSCK_ERROR;
2095 }
2096 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
2097 return FSCK_OK;
2098 if (check_system_dir(cx, sdp->master_dir, "master", build_metadir)) {
2099 stack;
2100 return FSCK_ERROR;
2101 }
2102 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
2103 return FSCK_OK;
2104 if (check_system_dir(cx, sdp->md.rooti, "root", build_root)) {
2105 stack;
2106 return FSCK_ERROR;
2107 }
2108 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
2109 return FSCK_OK;
2110 log_info( _("Checking directory inodes.\n"));
2111 /* Grab each directory inode, and run checks on it */
2112 for (tmp = osi_first(&cx->dirtree); tmp; tmp = next) {
2113 next = osi_next(tmp);
2114
2115 dt = (struct dir_info *)tmp;
2116 dirblk = dt->dinode.in_addr;
2117 display_progress(dirblk);
2118 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
2119 return FSCK_OK;
2120
2121 /* Skip the system inodes - they're checked above */
2122 if (is_system_dir(sdp, dirblk))
2123 continue;
2124
2125 /* If we created lost+found, its links should have been
2126 properly adjusted, so don't check it. */
2127 if (lf_was_created && (dirblk == lf_dip->i_num.in_addr)) {
2128 log_debug(_("Pass2 skipping the new lost+found.\n"));
2129 continue;
2130 }
2131
2132 log_debug(_("Checking directory inode at block %"PRIu64" (0x%"PRIx64")\n"),
2133 dirblk, dirblk);
2134
2135 ip = fsck_load_inode(sdp, dirblk);
2136 if (ip == NULL) {
2137 stack;
2138 return FSCK_ERROR;
2139 }
2140 error = pass2_check_dir(cx, ip);
2141 fsck_inode_put(&ip);
2142
2143 if (skip_this_pass || fsck_abort)
2144 return FSCK_OK;
2145
2146 if (error != FSCK_OK) {
2147 stack;
2148 return error;
2149 }
2150 }
2151 return FSCK_OK;
2152 }
2153