move e2fsck/* to e2fsck.c, one e2fsck_main and jornal exported, small automatic size...
[oweals/busybox.git] / e2fsprogs / e2fsck.c
1 /*
2  * e2fsck
3  *
4  * Copyright (C) 1993, 1994 Theodore Ts'o.  This file may be
5  * redistributed under the terms of the GNU Public License.
6  *
7  */
8
9 #ifndef _GNU_SOURCE
10 #define _GNU_SOURCE 1 /* get strnlen() */
11 #endif
12 #include <sys/types.h>
13 #include <inttypes.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <fcntl.h>
20 #include <ctype.h>
21 #include <setjmp.h>
22 #include <errno.h>
23 #include <getopt.h>
24 #include <limits.h>
25 #include <stddef.h>
26 #include <assert.h>
27 #include <signal.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30 #include <sys/resource.h>
31 #include <sys/param.h>
32 #include <sys/mount.h>
33 #include <sys/ioctl.h>
34 #include <malloc.h>
35 #include <termios.h>
36 #include <mntent.h>
37 #include <dirent.h>
38
39 #include "e2fsbb.h"
40
41 #include "ext2fs/ext2_fs.h"
42 #include "ext2fs/ext2fs.h"
43 #include "blkid/blkid.h"
44 #include "ext2fs/ext2_ext_attr.h"
45 #include "uuid/uuid.h"
46
47 #ifdef __GNUC__
48 #define _INLINE_ __inline__
49 #define EXT2FS_ATTR(x) __attribute__(x)
50 #else
51 #define _INLINE_
52 #define EXT2FS_ATTR(x)
53 #endif
54
55 /*
56  * Exit codes used by fsck-type programs
57  */
58 #define FSCK_OK          0      /* No errors */
59 #define FSCK_NONDESTRUCT 1      /* File system errors corrected */
60 #define FSCK_REBOOT      2      /* System should be rebooted */
61 #define FSCK_UNCORRECTED 4      /* File system errors left uncorrected */
62 #define FSCK_ERROR       8      /* Operational error */
63 #define FSCK_USAGE       16     /* Usage or syntax error */
64 #define FSCK_CANCELED    32     /* Aborted with a signal or ^C */
65 #define FSCK_LIBRARY     128    /* Shared library error */
66
67 /*
68  * The last ext2fs revision level that this version of e2fsck is able to
69  * support
70  */
71 #define E2FSCK_CURRENT_REV      1
72
73 /*
74  * The directory information structure; stores directory information
75  * collected in earlier passes, to avoid disk i/o in fetching the
76  * directory information.
77  */
78 struct dir_info {
79         ext2_ino_t              ino;    /* Inode number */
80         ext2_ino_t              dotdot; /* Parent according to '..' */
81         ext2_ino_t              parent; /* Parent according to treewalk */
82 };
83
84
85 /*
86  * The indexed directory information structure; stores information for
87  * directories which contain a hash tree index.
88  */
89 struct dx_dir_info {
90         ext2_ino_t              ino;            /* Inode number */
91         int                     numblocks;      /* number of blocks */
92         int                     hashversion;
93         short                   depth;          /* depth of tree */
94         struct dx_dirblock_info *dx_block;      /* Array of size numblocks */
95 };
96
97 #define DX_DIRBLOCK_ROOT        1
98 #define DX_DIRBLOCK_LEAF        2
99 #define DX_DIRBLOCK_NODE        3
100 #define DX_DIRBLOCK_CORRUPT     4
101 #define DX_DIRBLOCK_CLEARED     8
102
103 struct dx_dirblock_info {
104         int             type;
105         blk_t           phys;
106         int             flags;
107         blk_t           parent;
108         ext2_dirhash_t  min_hash;
109         ext2_dirhash_t  max_hash;
110         ext2_dirhash_t  node_min_hash;
111         ext2_dirhash_t  node_max_hash;
112 };
113
114 #define DX_FLAG_REFERENCED      1
115 #define DX_FLAG_DUP_REF         2
116 #define DX_FLAG_FIRST           4
117 #define DX_FLAG_LAST            8
118
119 #ifdef RESOURCE_TRACK
120 /*
121  * This structure is used for keeping track of how much resources have
122  * been used for a particular pass of e2fsck.
123  */
124 struct resource_track {
125         struct timeval time_start;
126         struct timeval user_start;
127         struct timeval system_start;
128         void    *brk_start;
129 };
130 #endif
131
132 /*
133  * E2fsck options
134  */
135 #define E2F_OPT_READONLY        0x0001
136 #define E2F_OPT_PREEN           0x0002
137 #define E2F_OPT_YES             0x0004
138 #define E2F_OPT_NO              0x0008
139 #define E2F_OPT_TIME            0x0010
140 #define E2F_OPT_TIME2           0x0020
141 #define E2F_OPT_CHECKBLOCKS     0x0040
142 #define E2F_OPT_DEBUG           0x0080
143 #define E2F_OPT_FORCE           0x0100
144 #define E2F_OPT_WRITECHECK      0x0200
145 #define E2F_OPT_COMPRESS_DIRS   0x0400
146
147 /*
148  * E2fsck flags
149  */
150 #define E2F_FLAG_ABORT          0x0001 /* Abort signaled */
151 #define E2F_FLAG_CANCEL         0x0002 /* Cancel signaled */
152 #define E2F_FLAG_SIGNAL_MASK    0x0003
153 #define E2F_FLAG_RESTART        0x0004 /* Restart signaled */
154
155 #define E2F_FLAG_SETJMP_OK      0x0010 /* Setjmp valid for abort */
156
157 #define E2F_FLAG_PROG_BAR       0x0020 /* Progress bar on screen */
158 #define E2F_FLAG_PROG_SUPPRESS  0x0040 /* Progress suspended */
159 #define E2F_FLAG_JOURNAL_INODE  0x0080 /* Create a new ext3 journal inode */
160 #define E2F_FLAG_SB_SPECIFIED   0x0100 /* The superblock was explicitly
161                                         * specified by the user */
162 #define E2F_FLAG_RESTARTED      0x0200 /* E2fsck has been restarted */
163 #define E2F_FLAG_RESIZE_INODE   0x0400 /* Request to recreate resize inode */
164
165 /*
166  * Defines for indicating the e2fsck pass number
167  */
168 #define E2F_PASS_1      1
169 #define E2F_PASS_2      2
170 #define E2F_PASS_3      3
171 #define E2F_PASS_4      4
172 #define E2F_PASS_5      5
173 #define E2F_PASS_1B     6
174
175 /*
176  * Define the extended attribute refcount structure
177  */
178 typedef struct ea_refcount *ext2_refcount_t;
179
180 /*
181  * This is the global e2fsck structure.
182  */
183 typedef struct e2fsck_struct *e2fsck_t;
184
185 struct e2fsck_struct {
186         ext2_filsys fs;
187         const char *program_name;
188         char *filesystem_name;
189         char *device_name;
190         char *io_options;
191         int     flags;          /* E2fsck internal flags */
192         int     options;
193         blk_t   use_superblock; /* sb requested by user */
194         blk_t   superblock;     /* sb used to open fs */
195         int     blocksize;      /* blocksize */
196         blk_t   num_blocks;     /* Total number of blocks */
197         int     mount_flags;
198         blkid_cache blkid;      /* blkid cache */
199
200         jmp_buf abort_loc;
201
202         unsigned long abort_code;
203
204         int (*progress)(e2fsck_t ctx, int pass, unsigned long cur,
205                         unsigned long max);
206
207         ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */
208         ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */
209         ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
210         ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */
211         ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */
212         ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/
213
214         ext2fs_block_bitmap block_found_map; /* Blocks which are in use */
215         ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */
216         ext2fs_block_bitmap block_ea_map; /* Blocks which are used by EA's */
217
218         /*
219          * Inode count arrays
220          */
221         ext2_icount_t   inode_count;
222         ext2_icount_t inode_link_info;
223
224         ext2_refcount_t refcount;
225         ext2_refcount_t refcount_extra;
226
227         /*
228          * Array of flags indicating whether an inode bitmap, block
229          * bitmap, or inode table is invalid
230          */
231         int *invalid_inode_bitmap_flag;
232         int *invalid_block_bitmap_flag;
233         int *invalid_inode_table_flag;
234         int invalid_bitmaps;    /* There are invalid bitmaps/itable */
235
236         /*
237          * Block buffer
238          */
239         char *block_buf;
240
241         /*
242          * For pass1_check_directory and pass1_get_blocks
243          */
244         ext2_ino_t stashed_ino;
245         struct ext2_inode *stashed_inode;
246
247         /*
248          * Location of the lost and found directory
249          */
250         ext2_ino_t lost_and_found;
251         int bad_lost_and_found;
252
253         /*
254          * Directory information
255          */
256         int             dir_info_count;
257         int             dir_info_size;
258         struct dir_info *dir_info;
259
260         /*
261          * Indexed directory information
262          */
263         int             dx_dir_info_count;
264         int             dx_dir_info_size;
265         struct dx_dir_info *dx_dir_info;
266
267         /*
268          * Directories to hash
269          */
270         ext2_u32_list   dirs_to_hash;
271
272         /*
273          * Tuning parameters
274          */
275         int process_inode_size;
276         int inode_buffer_blocks;
277
278         /*
279          * ext3 journal support
280          */
281         io_channel      journal_io;
282         char    *journal_name;
283
284 #ifdef RESOURCE_TRACK
285         /*
286          * For timing purposes
287          */
288         struct resource_track   global_rtrack;
289 #endif
290
291         /*
292          * How we display the progress update (for unix)
293          */
294         int progress_fd;
295         int progress_pos;
296         int progress_last_percent;
297         unsigned int progress_last_time;
298         int interactive;        /* Are we connected directly to a tty? */
299         char start_meta[2], stop_meta[2];
300
301         /* File counts */
302         int fs_directory_count;
303         int fs_regular_count;
304         int fs_blockdev_count;
305         int fs_chardev_count;
306         int fs_links_count;
307         int fs_symlinks_count;
308         int fs_fast_symlinks_count;
309         int fs_fifo_count;
310         int fs_total_count;
311         int fs_badblocks_count;
312         int fs_sockets_count;
313         int fs_ind_count;
314         int fs_dind_count;
315         int fs_tind_count;
316         int fs_fragmented;
317         int large_files;
318         int fs_ext_attr_inodes;
319         int fs_ext_attr_blocks;
320
321         int ext_attr_ver;
322
323         /*
324          * For the use of callers of the e2fsck functions; not used by
325          * e2fsck functions themselves.
326          */
327         void *priv_data;
328 };
329
330 /* Used by the region allocation code */
331 typedef __u32 region_addr_t;
332 typedef struct region_struct *region_t;
333
334 /*
335  * Procedure declarations
336  */
337
338 static void e2fsck_pass1(e2fsck_t ctx);
339 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
340 static void e2fsck_pass2(e2fsck_t ctx);
341 static void e2fsck_pass3(e2fsck_t ctx);
342 static void e2fsck_pass4(e2fsck_t ctx);
343 static void e2fsck_pass5(e2fsck_t ctx);
344
345 /* e2fsck.c */
346 static errcode_t e2fsck_allocate_context(e2fsck_t *ret);
347 static errcode_t e2fsck_reset_context(e2fsck_t ctx);
348 static void e2fsck_free_context(e2fsck_t ctx);
349 static int e2fsck_run(e2fsck_t ctx);
350
351
352 /* badblock.c */
353 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
354                                  int replace_bad_blocks);
355
356 /* dirinfo.c */
357 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent);
358 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino);
359 static void e2fsck_free_dir_info(e2fsck_t ctx);
360 static int e2fsck_get_num_dirinfo(e2fsck_t ctx);
361 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control);
362
363 /* dx_dirinfo.c */
364 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks);
365 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino);
366 static void e2fsck_free_dx_dir_info(e2fsck_t ctx);
367 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control);
368
369 /* ea_refcount.c */
370 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret);
371 static void ea_refcount_free(ext2_refcount_t refcount);
372 static errcode_t ea_refcount_increment(ext2_refcount_t refcount,
373                                        blk_t blk, int *ret);
374 static errcode_t ea_refcount_decrement(ext2_refcount_t refcount,
375                                        blk_t blk, int *ret);
376 static errcode_t ea_refcount_store(ext2_refcount_t refcount,
377                                    blk_t blk, int count);
378 static void ea_refcount_intr_begin(ext2_refcount_t refcount);
379 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret);
380
381 /* ehandler.c */
382 static const char *ehandler_operation(const char *op);
383 static void ehandler_init(io_channel channel);
384
385 /* journal.c */
386 static int e2fsck_check_ext3_journal(e2fsck_t ctx);
387 static int e2fsck_run_ext3_journal(e2fsck_t ctx);
388 static void e2fsck_move_ext3_journal(e2fsck_t ctx);
389
390 /* pass1.c */
391 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
392 static int e2fsck_pass1_check_device_inode(ext2_filsys fs,
393                                            struct ext2_inode *inode);
394 static int e2fsck_pass1_check_symlink(ext2_filsys fs,
395                                       struct ext2_inode *inode, char *buf);
396
397 /* pass2.c */
398 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
399                                     ext2_ino_t ino, char *buf);
400
401 /* pass3.c */
402 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
403 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
404                                          int num, int gauranteed_size);
405 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
406 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
407                                            int adj);
408
409
410 /* region.c */
411 static region_t region_create(region_addr_t min, region_addr_t max);
412 static void region_free(region_t region);
413 static int region_allocate(region_t region, region_addr_t start, int n);
414
415 /* rehash.c */
416 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino);
417 static void e2fsck_rehash_directories(e2fsck_t ctx);
418
419 /* super.c */
420 static void check_super_block(e2fsck_t ctx);
421 static errcode_t e2fsck_get_device_size(e2fsck_t ctx);
422
423 #ifdef ENABLE_SWAPFS
424 /* swapfs.c */
425 static void swap_filesys(e2fsck_t ctx);
426 #endif
427
428 /* util.c */
429 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
430                                     const char *description);
431 static int ask(e2fsck_t ctx, const char * string, int def);
432 static int ask_yn(const char * string, int def);
433 static void e2fsck_read_bitmaps(e2fsck_t ctx);
434 static void e2fsck_write_bitmaps(e2fsck_t ctx);
435 static void preenhalt(e2fsck_t ctx);
436 static char *string_copy(e2fsck_t ctx, const char *str, int len);
437 #ifdef RESOURCE_TRACK
438 static void print_resource_track(const char *desc,
439                                  struct resource_track *track);
440 static void init_resource_track(struct resource_track *track);
441 #endif
442 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
443                               struct ext2_inode * inode, const char * proc);
444 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
445                                struct ext2_inode * inode, const char * proc);
446 #ifdef MTRACE
447 static void mtrace_print(char *mesg);
448 #endif
449 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
450                            const char *name, io_manager manager);
451 static int ext2_file_type(unsigned int mode);
452
453 /* unix.c */
454 static void e2fsck_clear_progbar(e2fsck_t ctx);
455 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
456                                   float percent, unsigned int dpynum);
457 /*
458  * problem.h --- e2fsck problem error codes
459  */
460
461 typedef __u32 problem_t;
462
463 struct problem_context {
464         errcode_t       errcode;
465         ext2_ino_t ino, ino2, dir;
466         struct ext2_inode *inode;
467         struct ext2_dir_entry *dirent;
468         blk_t   blk, blk2;
469         e2_blkcnt_t     blkcount;
470         int             group;
471         __u64   num;
472         const char *str;
473 };
474
475 /*
476  * We define a set of "latch groups"; these are problems which are
477  * handled as a set.  The user answers once for a particular latch
478  * group.
479  */
480 #define PR_LATCH_MASK   0x0ff0  /* Latch mask */
481 #define PR_LATCH_BLOCK  0x0010  /* Latch for illegal blocks (pass 1) */
482 #define PR_LATCH_BBLOCK 0x0020  /* Latch for bad block inode blocks (pass 1) */
483 #define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */
484 #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */
485 #define PR_LATCH_RELOC  0x0050  /* Latch for superblock relocate hint */
486 #define PR_LATCH_DBLOCK 0x0060  /* Latch for pass 1b dup block headers */
487 #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
488 #define PR_LATCH_TOOBIG 0x0080  /* Latch for file to big errors */
489 #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */
490
491 #define PR_LATCH(x)     ((((x) & PR_LATCH_MASK) >> 4) - 1)
492
493 /*
494  * Latch group descriptor flags
495  */
496 #define PRL_YES         0x0001  /* Answer yes */
497 #define PRL_NO          0x0002  /* Answer no */
498 #define PRL_LATCHED     0x0004  /* The latch group is latched */
499 #define PRL_SUPPRESS    0x0008  /* Suppress all latch group questions */
500
501 #define PRL_VARIABLE    0x000f  /* All the flags that need to be reset */
502
503 /*
504  * Pre-Pass 1 errors
505  */
506
507 /* Block bitmap not in group */
508 #define PR_0_BB_NOT_GROUP       0x000001
509
510 /* Inode bitmap not in group */
511 #define PR_0_IB_NOT_GROUP       0x000002
512
513 /* Inode table not in group */
514 #define PR_0_ITABLE_NOT_GROUP   0x000003
515
516 /* Superblock corrupt */
517 #define PR_0_SB_CORRUPT         0x000004
518
519 /* Filesystem size is wrong */
520 #define PR_0_FS_SIZE_WRONG      0x000005
521
522 /* Fragments not supported */
523 #define PR_0_NO_FRAGMENTS       0x000006
524
525 /* Bad blocks_per_group */
526 #define PR_0_BLOCKS_PER_GROUP   0x000007
527
528 /* Bad first_data_block */
529 #define PR_0_FIRST_DATA_BLOCK   0x000008
530
531 /* Adding UUID to filesystem */
532 #define PR_0_ADD_UUID           0x000009
533
534 /* Relocate hint */
535 #define PR_0_RELOCATE_HINT      0x00000A
536
537 /* Miscellaneous superblock corruption */
538 #define PR_0_MISC_CORRUPT_SUPER 0x00000B
539
540 /* Error determing physical device size of filesystem */
541 #define PR_0_GETSIZE_ERROR      0x00000C
542
543 /* Inode count in the superblock incorrect */
544 #define PR_0_INODE_COUNT_WRONG  0x00000D
545
546 /* The Hurd does not support the filetype feature */
547 #define PR_0_HURD_CLEAR_FILETYPE 0x00000E
548
549 /* Journal inode is invalid */
550 #define PR_0_JOURNAL_BAD_INODE  0x00000F
551
552 /* The external journal has multiple filesystems (which we can't handle yet) */
553 #define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010
554
555 /* Can't find external journal */
556 #define PR_0_CANT_FIND_JOURNAL  0x000011
557
558 /* External journal has bad superblock */
559 #define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012
560
561 /* Superblock has a bad journal UUID */
562 #define PR_0_JOURNAL_BAD_UUID   0x000013
563
564 /* Journal has an unknown superblock type */
565 #define PR_0_JOURNAL_UNSUPP_SUPER 0x000014
566
567 /* Journal superblock is corrupt */
568 #define PR_0_JOURNAL_BAD_SUPER  0x000015
569
570 /* Journal superblock is corrupt */
571 #define PR_0_JOURNAL_HAS_JOURNAL 0x000016
572
573 /* Superblock has recovery flag set but no journal */
574 #define PR_0_JOURNAL_RECOVER_SET 0x000017
575
576 /* Journal has data, but recovery flag is clear */
577 #define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018
578
579 /* Ask if we should clear the journal */
580 #define PR_0_JOURNAL_RESET_JOURNAL 0x000019
581
582 /* Filesystem revision is 0, but feature flags are set */
583 #define PR_0_FS_REV_LEVEL       0x00001A
584
585 /* Clearing orphan inode */
586 #define PR_0_ORPHAN_CLEAR_INODE                 0x000020
587
588 /* Illegal block found in orphaned inode */
589 #define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM           0x000021
590
591 /* Already cleared block found in orphaned inode */
592 #define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK       0x000022
593
594 /* Illegal orphan inode in superblock */
595 #define PR_0_ORPHAN_ILLEGAL_HEAD_INODE          0x000023
596
597 /* Illegal inode in orphaned inode list */
598 #define PR_0_ORPHAN_ILLEGAL_INODE               0x000024
599
600 /* Journal has unsupported read-only feature - abort */
601 #define PR_0_JOURNAL_UNSUPP_ROCOMPAT            0x000025
602
603 /* Journal has unsupported incompatible feature - abort */
604 #define PR_0_JOURNAL_UNSUPP_INCOMPAT            0x000026
605
606 /* Journal has unsupported version number */
607 #define PR_0_JOURNAL_UNSUPP_VERSION             0x000027
608
609 /* Moving journal to hidden file */
610 #define PR_0_MOVE_JOURNAL                       0x000028
611
612 /* Error moving journal */
613 #define PR_0_ERR_MOVE_JOURNAL                   0x000029
614
615 /* Clearing V2 journal superblock */
616 #define PR_0_CLEAR_V2_JOURNAL                   0x00002A
617
618 /* Run journal anyway */
619 #define PR_0_JOURNAL_RUN                        0x00002B
620
621 /* Run journal anyway by default */
622 #define PR_0_JOURNAL_RUN_DEFAULT                0x00002C
623
624 /* Backup journal inode blocks */
625 #define PR_0_BACKUP_JNL                         0x00002D
626
627 /* Reserved blocks w/o resize_inode */
628 #define PR_0_NONZERO_RESERVED_GDT_BLOCKS        0x00002E
629
630 /* Resize_inode not enabled, but resize inode is non-zero */
631 #define PR_0_CLEAR_RESIZE_INODE                 0x00002F
632
633 /* Resize inode invalid */
634 #define PR_0_RESIZE_INODE_INVALID               0x000030
635
636 /*
637  * Pass 1 errors
638  */
639
640 /* Pass 1: Checking inodes, blocks, and sizes */
641 #define PR_1_PASS_HEADER                0x010000
642
643 /* Root directory is not an inode */
644 #define PR_1_ROOT_NO_DIR                0x010001
645
646 /* Root directory has dtime set */
647 #define PR_1_ROOT_DTIME                 0x010002
648
649 /* Reserved inode has bad mode */
650 #define PR_1_RESERVED_BAD_MODE          0x010003
651
652 /* Deleted inode has zero dtime */
653 #define PR_1_ZERO_DTIME                 0x010004
654
655 /* Inode in use, but dtime set */
656 #define PR_1_SET_DTIME                  0x010005
657
658 /* Zero-length directory */
659 #define PR_1_ZERO_LENGTH_DIR            0x010006
660
661 /* Block bitmap conflicts with some other fs block */
662 #define PR_1_BB_CONFLICT                0x010007
663
664 /* Inode bitmap conflicts with some other fs block */
665 #define PR_1_IB_CONFLICT                0x010008
666
667 /* Inode table conflicts with some other fs block */
668 #define PR_1_ITABLE_CONFLICT            0x010009
669
670 /* Block bitmap is on a bad block */
671 #define PR_1_BB_BAD_BLOCK               0x01000A
672
673 /* Inode bitmap is on a bad block */
674 #define PR_1_IB_BAD_BLOCK               0x01000B
675
676 /* Inode has incorrect i_size */
677 #define PR_1_BAD_I_SIZE                 0x01000C
678
679 /* Inode has incorrect i_blocks */
680 #define PR_1_BAD_I_BLOCKS               0x01000D
681
682 /* Illegal block number in inode */
683 #define PR_1_ILLEGAL_BLOCK_NUM          0x01000E
684
685 /* Block number overlaps fs metadata */
686 #define PR_1_BLOCK_OVERLAPS_METADATA    0x01000F
687
688 /* Inode has illegal blocks (latch question) */
689 #define PR_1_INODE_BLOCK_LATCH          0x010010
690
691 /* Too many bad blocks in inode */
692 #define PR_1_TOO_MANY_BAD_BLOCKS        0x010011
693
694 /* Illegal block number in bad block inode */
695 #define PR_1_BB_ILLEGAL_BLOCK_NUM       0x010012
696
697 /* Bad block inode has illegal blocks (latch question) */
698 #define PR_1_INODE_BBLOCK_LATCH         0x010013
699
700 /* Duplicate or bad blocks in use! */
701 #define PR_1_DUP_BLOCKS_PREENSTOP       0x010014
702
703 /* Bad block used as bad block indirect block */
704 #define PR_1_BBINODE_BAD_METABLOCK      0x010015
705
706 /* Inconsistency can't be fixed prompt */
707 #define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
708
709 /* Bad primary block */
710 #define PR_1_BAD_PRIMARY_BLOCK          0x010017
711
712 /* Bad primary block prompt */
713 #define PR_1_BAD_PRIMARY_BLOCK_PROMPT   0x010018
714
715 /* Bad primary superblock */
716 #define PR_1_BAD_PRIMARY_SUPERBLOCK     0x010019
717
718 /* Bad primary block group descriptors */
719 #define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A
720
721 /* Bad superblock in group */
722 #define PR_1_BAD_SUPERBLOCK             0x01001B
723
724 /* Bad block group descriptors in group */
725 #define PR_1_BAD_GROUP_DESCRIPTORS      0x01001C
726
727 /* Block claimed for no reason */
728 #define PR_1_PROGERR_CLAIMED_BLOCK      0x01001D
729
730 /* Error allocating blocks for relocating metadata */
731 #define PR_1_RELOC_BLOCK_ALLOCATE       0x01001E
732
733 /* Error allocating block buffer during relocation process */
734 #define PR_1_RELOC_MEMORY_ALLOCATE      0x01001F
735
736 /* Relocating metadata group information from X to Y */
737 #define PR_1_RELOC_FROM_TO              0x010020
738
739 /* Relocating metatdata group information to X */
740 #define PR_1_RELOC_TO                   0x010021
741
742 /* Block read error during relocation process */
743 #define PR_1_RELOC_READ_ERR             0x010022
744
745 /* Block write error during relocation process */
746 #define PR_1_RELOC_WRITE_ERR            0x010023
747
748 /* Error allocating inode bitmap */
749 #define PR_1_ALLOCATE_IBITMAP_ERROR     0x010024
750
751 /* Error allocating block bitmap */
752 #define PR_1_ALLOCATE_BBITMAP_ERROR     0x010025
753
754 /* Error allocating icount structure */
755 #define PR_1_ALLOCATE_ICOUNT            0x010026
756
757 /* Error allocating dbcount */
758 #define PR_1_ALLOCATE_DBCOUNT           0x010027
759
760 /* Error while scanning inodes */
761 #define PR_1_ISCAN_ERROR                0x010028
762
763 /* Error while iterating over blocks */
764 #define PR_1_BLOCK_ITERATE              0x010029
765
766 /* Error while storing inode count information */
767 #define PR_1_ICOUNT_STORE               0x01002A
768
769 /* Error while storing directory block information */
770 #define PR_1_ADD_DBLOCK                 0x01002B
771
772 /* Error while reading inode (for clearing) */
773 #define PR_1_READ_INODE                 0x01002C
774
775 /* Suppress messages prompt */
776 #define PR_1_SUPPRESS_MESSAGES          0x01002D
777
778 /* Imagic flag set on an inode when filesystem doesn't support it */
779 #define PR_1_SET_IMAGIC                 0x01002F
780
781 /* Immutable flag set on a device or socket inode */
782 #define PR_1_SET_IMMUTABLE              0x010030
783
784 /* Compression flag set on a non-compressed filesystem */
785 #define PR_1_COMPR_SET                  0x010031
786
787 /* Non-zero size on on device, fifo or socket inode */
788 #define PR_1_SET_NONZSIZE               0x010032
789
790 /* Filesystem revision is 0, but feature flags are set */
791 #define PR_1_FS_REV_LEVEL               0x010033
792
793 /* Journal inode not in use, needs clearing */
794 #define PR_1_JOURNAL_INODE_NOT_CLEAR    0x010034
795
796 /* Journal inode has wrong mode */
797 #define PR_1_JOURNAL_BAD_MODE           0x010035
798
799 /* Inode that was part of orphan linked list */
800 #define PR_1_LOW_DTIME                  0x010036
801
802 /* Latch question which asks how to deal with low dtime inodes */
803 #define PR_1_ORPHAN_LIST_REFUGEES       0x010037
804
805 /* Error allocating refcount structure */
806 #define PR_1_ALLOCATE_REFCOUNT          0x010038
807
808 /* Error reading Extended Attribute block */
809 #define PR_1_READ_EA_BLOCK              0x010039
810
811 /* Invalid Extended Attribute block */
812 #define PR_1_BAD_EA_BLOCK               0x01003A
813
814 /* Error reading Extended Attribute block while fixing refcount -- abort */
815 #define PR_1_EXTATTR_READ_ABORT         0x01003B
816
817 /* Extended attribute reference count incorrect */
818 #define PR_1_EXTATTR_REFCOUNT           0x01003C
819
820 /* Error writing Extended Attribute block while fixing refcount */
821 #define PR_1_EXTATTR_WRITE              0x01003D
822
823 /* Multiple EA blocks not supported */
824 #define PR_1_EA_MULTI_BLOCK             0x01003E
825
826 /* Error allocating EA region allocation structure */
827 #define PR_1_EA_ALLOC_REGION            0x01003F
828
829 /* Error EA allocation collision */
830 #define PR_1_EA_ALLOC_COLLISION         0x010040
831
832 /* Bad extended attribute name */
833 #define PR_1_EA_BAD_NAME                0x010041
834
835 /* Bad extended attribute value */
836 #define PR_1_EA_BAD_VALUE               0x010042
837
838 /* Inode too big (latch question) */
839 #define PR_1_INODE_TOOBIG               0x010043
840
841 /* Directory too big */
842 #define PR_1_TOOBIG_DIR                 0x010044
843
844 /* Regular file too big */
845 #define PR_1_TOOBIG_REG                 0x010045
846
847 /* Symlink too big */
848 #define PR_1_TOOBIG_SYMLINK             0x010046
849
850 /* INDEX_FL flag set on a non-HTREE filesystem */
851 #define PR_1_HTREE_SET                  0x010047
852
853 /* INDEX_FL flag set on a non-directory */
854 #define PR_1_HTREE_NODIR                0x010048
855
856 /* Invalid root node in HTREE directory */
857 #define PR_1_HTREE_BADROOT              0x010049
858
859 /* Unsupported hash version in HTREE directory */
860 #define PR_1_HTREE_HASHV                0x01004A
861
862 /* Incompatible flag in HTREE root node */
863 #define PR_1_HTREE_INCOMPAT             0x01004B
864
865 /* HTREE too deep */
866 #define PR_1_HTREE_DEPTH                0x01004C
867
868 /* Bad block has indirect block that conflicts with filesystem block */
869 #define PR_1_BB_FS_BLOCK                0x01004D
870
871 /* Resize inode failed */
872 #define PR_1_RESIZE_INODE_CREATE        0x01004E
873
874 /* inode->i_size is too long */
875 #define PR_1_EXTRA_ISIZE                0x01004F
876
877 /* attribute name is too long */
878 #define PR_1_ATTR_NAME_LEN              0x010050
879
880 /* wrong EA value offset */
881 #define PR_1_ATTR_VALUE_OFFSET          0x010051
882
883 /* wrong EA blocknumber */
884 #define PR_1_ATTR_VALUE_BLOCK           0x010052
885
886 /* wrong EA value size */
887 #define PR_1_ATTR_VALUE_SIZE            0x010053
888
889 /* wrong EA hash value */
890 #define PR_1_ATTR_HASH                  0x010054
891
892 /*
893  * Pass 1b errors
894  */
895
896 /* Pass 1B: Rescan for duplicate/bad blocks */
897 #define PR_1B_PASS_HEADER       0x011000
898
899 /* Duplicate/bad block(s) header */
900 #define PR_1B_DUP_BLOCK_HEADER  0x011001
901
902 /* Duplicate/bad block(s) in inode */
903 #define PR_1B_DUP_BLOCK         0x011002
904
905 /* Duplicate/bad block(s) end */
906 #define PR_1B_DUP_BLOCK_END     0x011003
907
908 /* Error while scanning inodes */
909 #define PR_1B_ISCAN_ERROR       0x011004
910
911 /* Error allocating inode bitmap */
912 #define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005
913
914 /* Error while iterating over blocks */
915 #define PR_1B_BLOCK_ITERATE     0x0110006
916
917 /* Error adjusting EA refcount */
918 #define PR_1B_ADJ_EA_REFCOUNT   0x0110007
919
920
921 /* Pass 1C: Scan directories for inodes with dup blocks. */
922 #define PR_1C_PASS_HEADER       0x012000
923
924
925 /* Pass 1D: Reconciling duplicate blocks */
926 #define PR_1D_PASS_HEADER       0x013000
927
928 /* File has duplicate blocks */
929 #define PR_1D_DUP_FILE          0x013001
930
931 /* List of files sharing duplicate blocks */
932 #define PR_1D_DUP_FILE_LIST     0x013002
933
934 /* File sharing blocks with filesystem metadata  */
935 #define PR_1D_SHARE_METADATA    0x013003
936
937 /* Report of how many duplicate/bad inodes */
938 #define PR_1D_NUM_DUP_INODES    0x013004
939
940 /* Duplicated blocks already reassigned or cloned. */
941 #define PR_1D_DUP_BLOCKS_DEALT  0x013005
942
943 /* Clone duplicate/bad blocks? */
944 #define PR_1D_CLONE_QUESTION    0x013006
945
946 /* Delete file? */
947 #define PR_1D_DELETE_QUESTION   0x013007
948
949 /* Couldn't clone file (error) */
950 #define PR_1D_CLONE_ERROR       0x013008
951
952 /*
953  * Pass 2 errors
954  */
955
956 /* Pass 2: Checking directory structure */
957 #define PR_2_PASS_HEADER        0x020000
958
959 /* Bad inode number for '.' */
960 #define PR_2_BAD_INODE_DOT      0x020001
961
962 /* Directory entry has bad inode number */
963 #define PR_2_BAD_INO            0x020002
964
965 /* Directory entry has deleted or unused inode */
966 #define PR_2_UNUSED_INODE       0x020003
967
968 /* Directry entry is link to '.' */
969 #define PR_2_LINK_DOT           0x020004
970
971 /* Directory entry points to inode now located in a bad block */
972 #define PR_2_BB_INODE           0x020005
973
974 /* Directory entry contains a link to a directory */
975 #define PR_2_LINK_DIR           0x020006
976
977 /* Directory entry contains a link to the root directry */
978 #define PR_2_LINK_ROOT          0x020007
979
980 /* Directory entry has illegal characters in its name */
981 #define PR_2_BAD_NAME           0x020008
982
983 /* Missing '.' in directory inode */
984 #define PR_2_MISSING_DOT        0x020009
985
986 /* Missing '..' in directory inode */
987 #define PR_2_MISSING_DOT_DOT    0x02000A
988
989 /* First entry in directory inode doesn't contain '.' */
990 #define PR_2_1ST_NOT_DOT        0x02000B
991
992 /* Second entry in directory inode doesn't contain '..' */
993 #define PR_2_2ND_NOT_DOT_DOT    0x02000C
994
995 /* i_faddr should be zero */
996 #define PR_2_FADDR_ZERO         0x02000D
997
998 /* i_file_acl should be zero */
999 #define PR_2_FILE_ACL_ZERO      0x02000E
1000
1001 /* i_dir_acl should be zero */
1002 #define PR_2_DIR_ACL_ZERO       0x02000F
1003
1004 /* i_frag should be zero */
1005 #define PR_2_FRAG_ZERO          0x020010
1006
1007 /* i_fsize should be zero */
1008 #define PR_2_FSIZE_ZERO         0x020011
1009
1010 /* inode has bad mode */
1011 #define PR_2_BAD_MODE           0x020012
1012
1013 /* directory corrupted */
1014 #define PR_2_DIR_CORRUPTED      0x020013
1015
1016 /* filename too long */
1017 #define PR_2_FILENAME_LONG      0x020014
1018
1019 /* Directory inode has a missing block (hole) */
1020 #define PR_2_DIRECTORY_HOLE     0x020015
1021
1022 /* '.' is not NULL terminated */
1023 #define PR_2_DOT_NULL_TERM      0x020016
1024
1025 /* '..' is not NULL terminated */
1026 #define PR_2_DOT_DOT_NULL_TERM  0x020017
1027
1028 /* Illegal character device in inode */
1029 #define PR_2_BAD_CHAR_DEV       0x020018
1030
1031 /* Illegal block device in inode */
1032 #define PR_2_BAD_BLOCK_DEV      0x020019
1033
1034 /* Duplicate '.' entry */
1035 #define PR_2_DUP_DOT            0x02001A
1036
1037 /* Duplicate '..' entry */
1038 #define PR_2_DUP_DOT_DOT        0x02001B
1039
1040 /* Internal error: couldn't find dir_info */
1041 #define PR_2_NO_DIRINFO         0x02001C
1042
1043 /* Final rec_len is wrong */
1044 #define PR_2_FINAL_RECLEN       0x02001D
1045
1046 /* Error allocating icount structure */
1047 #define PR_2_ALLOCATE_ICOUNT    0x02001E
1048
1049 /* Error iterating over directory blocks */
1050 #define PR_2_DBLIST_ITERATE     0x02001F
1051
1052 /* Error reading directory block */
1053 #define PR_2_READ_DIRBLOCK      0x020020
1054
1055 /* Error writing directory block */
1056 #define PR_2_WRITE_DIRBLOCK     0x020021
1057
1058 /* Error allocating new directory block */
1059 #define PR_2_ALLOC_DIRBOCK      0x020022
1060
1061 /* Error deallocating inode */
1062 #define PR_2_DEALLOC_INODE      0x020023
1063
1064 /* Directory entry for '.' is big.  Split? */
1065 #define PR_2_SPLIT_DOT          0x020024
1066
1067 /* Illegal FIFO */
1068 #define PR_2_BAD_FIFO           0x020025
1069
1070 /* Illegal socket */
1071 #define PR_2_BAD_SOCKET         0x020026
1072
1073 /* Directory filetype not set */
1074 #define PR_2_SET_FILETYPE       0x020027
1075
1076 /* Directory filetype incorrect */
1077 #define PR_2_BAD_FILETYPE       0x020028
1078
1079 /* Directory filetype set when it shouldn't be */
1080 #define PR_2_CLEAR_FILETYPE     0x020029
1081
1082 /* Directory filename can't be zero-length  */
1083 #define PR_2_NULL_NAME          0x020030
1084
1085 /* Invalid symlink */
1086 #define PR_2_INVALID_SYMLINK    0x020031
1087
1088 /* i_file_acl (extended attribute) is bad */
1089 #define PR_2_FILE_ACL_BAD       0x020032
1090
1091 /* Filesystem contains large files, but has no such flag in sb */
1092 #define PR_2_FEATURE_LARGE_FILES 0x020033
1093
1094 /* Node in HTREE directory not referenced */
1095 #define PR_2_HTREE_NOTREF       0x020034
1096
1097 /* Node in HTREE directory referenced twice */
1098 #define PR_2_HTREE_DUPREF       0x020035
1099
1100 /* Node in HTREE directory has bad min hash */
1101 #define PR_2_HTREE_MIN_HASH     0x020036
1102
1103 /* Node in HTREE directory has bad max hash */
1104 #define PR_2_HTREE_MAX_HASH     0x020037
1105
1106 /* Clear invalid HTREE directory */
1107 #define PR_2_HTREE_CLEAR        0x020038
1108
1109 /* Clear the htree flag forcibly */
1110 /* #define PR_2_HTREE_FCLR      0x020039 */
1111
1112 /* Bad block in htree interior node */
1113 #define PR_2_HTREE_BADBLK       0x02003A
1114
1115 /* Error adjusting EA refcount */
1116 #define PR_2_ADJ_EA_REFCOUNT    0x02003B
1117
1118 /* Invalid HTREE root node */
1119 #define PR_2_HTREE_BAD_ROOT     0x02003C
1120
1121 /* Invalid HTREE limit */
1122 #define PR_2_HTREE_BAD_LIMIT    0x02003D
1123
1124 /* Invalid HTREE count */
1125 #define PR_2_HTREE_BAD_COUNT    0x02003E
1126
1127 /* HTREE interior node has out-of-order hashes in table */
1128 #define PR_2_HTREE_HASH_ORDER   0x02003F
1129
1130 /* Node in HTREE directory has bad depth */
1131 #define PR_2_HTREE_BAD_DEPTH    0x020040
1132
1133 /* Duplicate directory entry found */
1134 #define PR_2_DUPLICATE_DIRENT   0x020041
1135
1136 /* Non-unique filename found */
1137 #define PR_2_NON_UNIQUE_FILE    0x020042
1138
1139 /* Duplicate directory entry found */
1140 #define PR_2_REPORT_DUP_DIRENT  0x020043
1141
1142 /*
1143  * Pass 3 errors
1144  */
1145
1146 /* Pass 3: Checking directory connectivity */
1147 #define PR_3_PASS_HEADER                0x030000
1148
1149 /* Root inode not allocated */
1150 #define PR_3_NO_ROOT_INODE              0x030001
1151
1152 /* No room in lost+found */
1153 #define PR_3_EXPAND_LF_DIR              0x030002
1154
1155 /* Unconnected directory inode */
1156 #define PR_3_UNCONNECTED_DIR            0x030003
1157
1158 /* /lost+found not found */
1159 #define PR_3_NO_LF_DIR                  0x030004
1160
1161 /* .. entry is incorrect */
1162 #define PR_3_BAD_DOT_DOT                0x030005
1163
1164 /* Bad or non-existent /lost+found.  Cannot reconnect */
1165 #define PR_3_NO_LPF                     0x030006
1166
1167 /* Could not expand /lost+found */
1168 #define PR_3_CANT_EXPAND_LPF            0x030007
1169
1170 /* Could not reconnect inode */
1171 #define PR_3_CANT_RECONNECT             0x030008
1172
1173 /* Error while trying to find /lost+found */
1174 #define PR_3_ERR_FIND_LPF               0x030009
1175
1176 /* Error in ext2fs_new_block while creating /lost+found */
1177 #define PR_3_ERR_LPF_NEW_BLOCK          0x03000A
1178
1179 /* Error in ext2fs_new_inode while creating /lost+found */
1180 #define PR_3_ERR_LPF_NEW_INODE          0x03000B
1181
1182 /* Error in ext2fs_new_dir_block while creating /lost+found */
1183 #define PR_3_ERR_LPF_NEW_DIR_BLOCK      0x03000C
1184
1185 /* Error while writing directory block for /lost+found */
1186 #define PR_3_ERR_LPF_WRITE_BLOCK        0x03000D
1187
1188 /* Error while adjusting inode count */
1189 #define PR_3_ADJUST_INODE               0x03000E
1190
1191 /* Couldn't fix parent directory -- error */
1192 #define PR_3_FIX_PARENT_ERR             0x03000F
1193
1194 /* Couldn't fix parent directory -- couldn't find it */
1195 #define PR_3_FIX_PARENT_NOFIND          0x030010
1196
1197 /* Error allocating inode bitmap */
1198 #define PR_3_ALLOCATE_IBITMAP_ERROR     0x030011
1199
1200 /* Error creating root directory */
1201 #define PR_3_CREATE_ROOT_ERROR          0x030012
1202
1203 /* Error creating lost and found directory */
1204 #define PR_3_CREATE_LPF_ERROR           0x030013
1205
1206 /* Root inode is not directory; aborting */
1207 #define PR_3_ROOT_NOT_DIR_ABORT         0x030014
1208
1209 /* Cannot proceed without a root inode. */
1210 #define PR_3_NO_ROOT_INODE_ABORT        0x030015
1211
1212 /* Internal error: couldn't find dir_info */
1213 #define PR_3_NO_DIRINFO                 0x030016
1214
1215 /* Lost+found is not a directory */
1216 #define PR_3_LPF_NOTDIR                 0x030017
1217
1218 /*
1219  * Pass 3a --- rehashing diretories
1220  */
1221 /* Pass 3a: Reindexing directories */
1222 #define PR_3A_PASS_HEADER               0x031000
1223
1224 /* Error iterating over directories */
1225 #define PR_3A_OPTIMIZE_ITER             0x031001
1226
1227 /* Error rehash directory */
1228 #define PR_3A_OPTIMIZE_DIR_ERR          0x031002
1229
1230 /* Rehashing dir header */
1231 #define PR_3A_OPTIMIZE_DIR_HEADER               0x031003
1232
1233 /* Rehashing directory %d */
1234 #define PR_3A_OPTIMIZE_DIR              0x031004
1235
1236 /* Rehashing dir end */
1237 #define PR_3A_OPTIMIZE_DIR_END          0x031005
1238
1239 /*
1240  * Pass 4 errors
1241  */
1242
1243 /* Pass 4: Checking reference counts */
1244 #define PR_4_PASS_HEADER        0x040000
1245
1246 /* Unattached zero-length inode */
1247 #define PR_4_ZERO_LEN_INODE     0x040001
1248
1249 /* Unattached inode */
1250 #define PR_4_UNATTACHED_INODE   0x040002
1251
1252 /* Inode ref count wrong */
1253 #define PR_4_BAD_REF_COUNT      0x040003
1254
1255 /* Inconsistent inode count information cached */
1256 #define PR_4_INCONSISTENT_COUNT 0x040004
1257
1258 /*
1259  * Pass 5 errors
1260  */
1261
1262 /* Pass 5: Checking group summary information */
1263 #define PR_5_PASS_HEADER                0x050000
1264
1265 /* Padding at end of inode bitmap is not set. */
1266 #define PR_5_INODE_BMAP_PADDING         0x050001
1267
1268 /* Padding at end of block bitmap is not set. */
1269 #define PR_5_BLOCK_BMAP_PADDING         0x050002
1270
1271 /* Block bitmap differences header */
1272 #define PR_5_BLOCK_BITMAP_HEADER        0x050003
1273
1274 /* Block not used, but marked in bitmap */
1275 #define PR_5_BLOCK_UNUSED               0x050004
1276
1277 /* Block used, but not marked used in bitmap */
1278 #define PR_5_BLOCK_USED                 0x050005
1279
1280 /* Block bitmap differences end */
1281 #define PR_5_BLOCK_BITMAP_END           0x050006
1282
1283 /* Inode bitmap differences header */
1284 #define PR_5_INODE_BITMAP_HEADER        0x050007
1285
1286 /* Inode not used, but marked in bitmap */
1287 #define PR_5_INODE_UNUSED               0x050008
1288
1289 /* Inode used, but not marked used in bitmap */
1290 #define PR_5_INODE_USED                 0x050009
1291
1292 /* Inode bitmap differences end */
1293 #define PR_5_INODE_BITMAP_END           0x05000A
1294
1295 /* Free inodes count for group wrong */
1296 #define PR_5_FREE_INODE_COUNT_GROUP     0x05000B
1297
1298 /* Directories count for group wrong */
1299 #define PR_5_FREE_DIR_COUNT_GROUP       0x05000C
1300
1301 /* Free inodes count wrong */
1302 #define PR_5_FREE_INODE_COUNT   0x05000D
1303
1304 /* Free blocks count for group wrong */
1305 #define PR_5_FREE_BLOCK_COUNT_GROUP     0x05000E
1306
1307 /* Free blocks count wrong */
1308 #define PR_5_FREE_BLOCK_COUNT           0x05000F
1309
1310 /* Programming error: bitmap endpoints don't match */
1311 #define PR_5_BMAP_ENDPOINTS             0x050010
1312
1313 /* Internal error: fudging end of bitmap */
1314 #define PR_5_FUDGE_BITMAP_ERROR         0x050011
1315
1316 /* Error copying in replacement inode bitmap */
1317 #define PR_5_COPY_IBITMAP_ERROR         0x050012
1318
1319 /* Error copying in replacement block bitmap */
1320 #define PR_5_COPY_BBITMAP_ERROR         0x050013
1321
1322 /* Block range not used, but marked in bitmap */
1323 #define PR_5_BLOCK_RANGE_UNUSED         0x050014
1324
1325 /* Block range used, but not marked used in bitmap */
1326 #define PR_5_BLOCK_RANGE_USED           0x050015
1327
1328 /* Inode range not used, but marked in bitmap */
1329 #define PR_5_INODE_RANGE_UNUSED         0x050016
1330
1331 /* Inode rangeused, but not marked used in bitmap */
1332 #define PR_5_INODE_RANGE_USED           0x050017
1333
1334 /*
1335  * Function declarations
1336  */
1337 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
1338 static int end_problem_latch(e2fsck_t ctx, int mask);
1339 static int set_latch_flags(int mask, int setflags, int clearflags);
1340 static void clear_problem_context(struct problem_context *ctx);
1341
1342 /* message.c */
1343 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
1344                           struct problem_context *pctx, int first);
1345
1346 /*
1347  * Dictionary Abstract Data Type
1348  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
1349  *
1350  * Free Software License:
1351  *
1352  * All rights are reserved by the author, with the following exceptions:
1353  * Permission is granted to freely reproduce and distribute this software,
1354  * possibly in exchange for a fee, provided that this copyright notice appears
1355  * intact. Permission is also granted to adapt this software to produce
1356  * derivative works, as long as the modified versions carry this copyright
1357  * notice and additional notices stating that the work has been modified.
1358  * This source code may be translated into executable form and incorporated
1359  * into proprietary software; there is no requirement for such software to
1360  * contain a copyright notice related to this source.
1361  *
1362  * $Id: dict.h,v 1.22.2.6 2000/11/13 01:36:44 kaz Exp $
1363  * $Name: kazlib_1_20 $
1364  */
1365
1366 #ifndef DICT_H
1367 #define DICT_H
1368
1369 /*
1370  * Blurb for inclusion into C++ translation units
1371  */
1372
1373 typedef unsigned long dictcount_t;
1374 #define DICTCOUNT_T_MAX ULONG_MAX
1375
1376 /*
1377  * The dictionary is implemented as a red-black tree
1378  */
1379
1380 typedef enum { dnode_red, dnode_black } dnode_color_t;
1381
1382 typedef struct dnode_t {
1383     struct dnode_t *dict_left;
1384     struct dnode_t *dict_right;
1385     struct dnode_t *dict_parent;
1386     dnode_color_t dict_color;
1387     const void *dict_key;
1388     void *dict_data;
1389 } dnode_t;
1390
1391 typedef int (*dict_comp_t)(const void *, const void *);
1392 typedef dnode_t *(*dnode_alloc_t)(void *);
1393 typedef void (*dnode_free_t)(dnode_t *, void *);
1394
1395 typedef struct dict_t {
1396     dnode_t dict_nilnode;
1397     dictcount_t dict_nodecount;
1398     dictcount_t dict_maxcount;
1399     dict_comp_t dict_compare;
1400     dnode_alloc_t dict_allocnode;
1401     dnode_free_t dict_freenode;
1402     void *dict_context;
1403     int dict_dupes;
1404 } dict_t;
1405
1406 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
1407
1408 typedef struct dict_load_t {
1409     dict_t *dict_dictptr;
1410     dnode_t dict_nilnode;
1411 } dict_load_t;
1412
1413 static void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
1414 static void dict_free_nodes(dict_t *);
1415 static dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t);
1416 static dnode_t *dict_lookup(dict_t *, const void *);
1417 static void dict_insert(dict_t *, dnode_t *, const void *);
1418 static int dict_alloc_insert(dict_t *, const void *, void *);
1419 static dnode_t *dict_first(dict_t *);
1420 static dnode_t *dict_next(dict_t *, dnode_t *);
1421 static dictcount_t dict_count(dict_t *);
1422 static dnode_t *dnode_init(dnode_t *, void *);
1423 static void *dnode_get(dnode_t *);
1424 static const void *dnode_getkey(dnode_t *);
1425
1426 #define dict_count(D) ((D)->dict_nodecount)
1427 #define dnode_get(N) ((N)->dict_data)
1428 #define dnode_getkey(N) ((N)->dict_key)
1429
1430 #endif
1431
1432 /*
1433  * Compatibility header file for e2fsck which should be included
1434  * instead of linux/jfs.h
1435  *
1436  * Copyright (C) 2000 Stephen C. Tweedie
1437  */
1438
1439 /*
1440  * Pull in the definition of the e2fsck context structure
1441  */
1442
1443
1444 struct buffer_head {
1445         char            b_data[8192];
1446         e2fsck_t        b_ctx;
1447         io_channel      b_io;
1448         int             b_size;
1449         blk_t           b_blocknr;
1450         int             b_dirty;
1451         int             b_uptodate;
1452         int             b_err;
1453 };
1454
1455 struct inode {
1456         e2fsck_t        i_ctx;
1457         ext2_ino_t      i_ino;
1458         struct ext2_inode i_ext2;
1459 };
1460
1461 struct kdev_s {
1462         e2fsck_t        k_ctx;
1463         int             k_dev;
1464 };
1465
1466 #define K_DEV_FS        1
1467 #define K_DEV_JOURNAL   2
1468
1469 typedef struct kdev_s *kdev_t;
1470
1471 #define lock_buffer(bh) do {} while(0)
1472 #define unlock_buffer(bh) do {} while(0)
1473 #define buffer_req(bh) 1
1474 #define do_readahead(journal, start) do {} while(0)
1475
1476 static e2fsck_t e2fsck_global_ctx;  /* Try your very best not to use this! */
1477
1478 typedef struct {
1479         int     object_length;
1480 } kmem_cache_t;
1481
1482 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
1483 #define kmem_cache_free(cache,obj) free(obj)
1484 #define kmem_cache_create(name,len,a,b,c,d) do_cache_create(len)
1485 #define kmem_cache_destroy(cache) do_cache_destroy(cache)
1486 #define kmalloc(len,flags) malloc(len)
1487 #define kfree(p) free(p)
1488
1489 /*
1490  * We use the standard libext2fs portability tricks for inline
1491  * functions.
1492  */
1493
1494 static _INLINE_ kmem_cache_t * do_cache_create(int len)
1495 {
1496         kmem_cache_t *new_cache;
1497         new_cache = malloc(sizeof(*new_cache));
1498         if (new_cache)
1499                 new_cache->object_length = len;
1500         return new_cache;
1501 }
1502
1503 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
1504 {
1505         free(cache);
1506 }
1507
1508 /*
1509  * Now pull in the real linux/jfs.h definitions.
1510  */
1511 #include "ext2fs/kernel-jbd.h"
1512
1513 /*
1514  * Kernel compatibility functions are defined in journal.c
1515  */
1516 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys);
1517 static struct buffer_head *getblk(kdev_t ctx, blk_t blocknr, int blocksize);
1518 static void sync_blockdev(kdev_t kdev);
1519 static void ll_rw_block(int rw, int dummy, struct buffer_head *bh[]);
1520 static void mark_buffer_dirty(struct buffer_head *bh);
1521 static void mark_buffer_uptodate(struct buffer_head *bh, int val);
1522 static void brelse(struct buffer_head *bh);
1523 static int buffer_uptodate(struct buffer_head *bh);
1524 static void wait_on_buffer(struct buffer_head *bh);
1525
1526 /*
1527  * Define newer 2.5 interfaces
1528  */
1529 #define __getblk(dev, blocknr, blocksize) getblk(dev, blocknr, blocksize)
1530 #define set_buffer_uptodate(bh) mark_buffer_uptodate(bh, 1)
1531
1532 /*
1533  * badblocks.c --- replace/append bad blocks to the bad block inode
1534  *
1535  * Copyright (C) 1993, 1994 Theodore Ts'o.  This file may be
1536  * redistributed under the terms of the GNU Public License.
1537  */
1538
1539 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
1540                                  void *priv_data);
1541
1542
1543 static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk)
1544 {
1545         printf(_("Bad block %u out of range; ignored.\n"), blk);
1546         return;
1547 }
1548
1549 void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
1550                           int replace_bad_blocks)
1551 {
1552         ext2_filsys fs = ctx->fs;
1553         errcode_t       retval;
1554         badblocks_list  bb_list = 0;
1555         FILE            *f;
1556         char            buf[1024];
1557
1558         e2fsck_read_bitmaps(ctx);
1559
1560         /*
1561          * Make sure the bad block inode is sane.  If there are any
1562          * illegal blocks, clear them.
1563          */
1564         retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
1565                                       check_bb_inode_blocks, 0);
1566         if (retval) {
1567                 com_err("ext2fs_block_iterate", retval,
1568                         _("while sanity checking the bad blocks inode"));
1569                 goto fatal;
1570         }
1571
1572         /*
1573          * If we're appending to the bad blocks inode, read in the
1574          * current bad blocks.
1575          */
1576         if (!replace_bad_blocks) {
1577                 retval = ext2fs_read_bb_inode(fs, &bb_list);
1578                 if (retval) {
1579                         com_err("ext2fs_read_bb_inode", retval,
1580                                 _("while reading the bad blocks inode"));
1581                         goto fatal;
1582                 }
1583         }
1584
1585         /*
1586          * Now read in the bad blocks from the file; if
1587          * bad_blocks_file is null, then try to run the badblocks
1588          * command.
1589          */
1590         if (bad_blocks_file) {
1591                 f = fopen(bad_blocks_file, "r");
1592                 if (!f) {
1593                         com_err("read_bad_blocks_file", errno,
1594                                 _("while trying to open %s"), bad_blocks_file);
1595                         goto fatal;
1596                 }
1597         } else {
1598                 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
1599                         (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
1600                         (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
1601                         fs->device_name, fs->super->s_blocks_count);
1602                 f = popen(buf, "r");
1603                 if (!f) {
1604                         com_err("read_bad_blocks_file", errno,
1605                                 _("while trying popen '%s'"), buf);
1606                         goto fatal;
1607                 }
1608         }
1609         retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
1610         if (bad_blocks_file)
1611                 fclose(f);
1612         else
1613                 pclose(f);
1614         if (retval) {
1615                 com_err("ext2fs_read_bb_FILE", retval,
1616                         _("while reading in list of bad blocks from file"));
1617                 goto fatal;
1618         }
1619
1620         /*
1621          * Finally, update the bad blocks from the bad_block_map
1622          */
1623         retval = ext2fs_update_bb_inode(fs, bb_list);
1624         if (retval) {
1625                 com_err("ext2fs_update_bb_inode", retval,
1626                         _("while updating bad block inode"));
1627                 goto fatal;
1628         }
1629
1630         ext2fs_badblocks_list_free(bb_list);
1631         return;
1632
1633 fatal:
1634         ctx->flags |= E2F_FLAG_ABORT;
1635         return;
1636
1637 }
1638
1639 static int check_bb_inode_blocks(ext2_filsys fs,
1640                                  blk_t *block_nr,
1641                                  int blockcnt EXT2FS_ATTR((unused)),
1642                                  void *priv_data EXT2FS_ATTR((unused)))
1643 {
1644         if (!*block_nr)
1645                 return 0;
1646
1647         /*
1648          * If the block number is outrageous, clear it and ignore it.
1649          */
1650         if (*block_nr >= fs->super->s_blocks_count ||
1651             *block_nr < fs->super->s_first_data_block) {
1652                 printf(_("Warning illegal block %u found in bad block inode.  Cleared.\n"), *block_nr);
1653                 *block_nr = 0;
1654                 return BLOCK_CHANGED;
1655         }
1656
1657         return 0;
1658 }
1659
1660 /*
1661  * Dictionary Abstract Data Type
1662  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
1663  *
1664  * Free Software License:
1665  *
1666  * All rights are reserved by the author, with the following exceptions:
1667  * Permission is granted to freely reproduce and distribute this software,
1668  * possibly in exchange for a fee, provided that this copyright notice appears
1669  * intact. Permission is also granted to adapt this software to produce
1670  * derivative works, as long as the modified versions carry this copyright
1671  * notice and additional notices stating that the work has been modified.
1672  * This source code may be translated into executable form and incorporated
1673  * into proprietary software; there is no requirement for such software to
1674  * contain a copyright notice related to this source.
1675  *
1676  * $Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $
1677  * $Name: kazlib_1_20 $
1678  */
1679
1680
1681 /*
1682  * These macros provide short convenient names for structure members,
1683  * which are embellished with dict_ prefixes so that they are
1684  * properly confined to the documented namespace. It's legal for a
1685  * program which uses dict to define, for instance, a macro called ``parent''.
1686  * Such a macro would interfere with the dnode_t struct definition.
1687  * In general, highly portable and reusable C modules which expose their
1688  * structures need to confine structure member names to well-defined spaces.
1689  * The resulting identifiers aren't necessarily convenient to use, nor
1690  * readable, in the implementation, however!
1691  */
1692
1693 #define left dict_left
1694 #define right dict_right
1695 #define parent dict_parent
1696 #define color dict_color
1697 #define key dict_key
1698 #define data dict_data
1699
1700 #define nilnode dict_nilnode
1701 #define nodecount dict_nodecount
1702 #define maxcount dict_maxcount
1703 #define compare dict_compare
1704 #define allocnode dict_allocnode
1705 #define freenode dict_freenode
1706 #define context dict_context
1707 #define dupes dict_dupes
1708
1709 #define dictptr dict_dictptr
1710
1711 #define dict_root(D) ((D)->nilnode.left)
1712 #define dict_nil(D) (&(D)->nilnode)
1713 #define DICT_DEPTH_MAX 64
1714
1715 static dnode_t *dnode_alloc(void *context);
1716 static void dnode_free(dnode_t *node, void *context);
1717
1718 /*
1719  * Perform a ``left rotation'' adjustment on the tree.  The given node P and
1720  * its right child C are rearranged so that the P instead becomes the left
1721  * child of C.   The left subtree of C is inherited as the new right subtree
1722  * for P.  The ordering of the keys within the tree is thus preserved.
1723  */
1724
1725 static void rotate_left(dnode_t *upper)
1726 {
1727     dnode_t *lower, *lowleft, *upparent;
1728
1729     lower = upper->right;
1730     upper->right = lowleft = lower->left;
1731     lowleft->parent = upper;
1732
1733     lower->parent = upparent = upper->parent;
1734
1735     /* don't need to check for root node here because root->parent is
1736        the sentinel nil node, and root->parent->left points back to root */
1737
1738     if (upper == upparent->left) {
1739         upparent->left = lower;
1740     } else {
1741         assert (upper == upparent->right);
1742         upparent->right = lower;
1743     }
1744
1745     lower->left = upper;
1746     upper->parent = lower;
1747 }
1748
1749 /*
1750  * This operation is the ``mirror'' image of rotate_left. It is
1751  * the same procedure, but with left and right interchanged.
1752  */
1753
1754 static void rotate_right(dnode_t *upper)
1755 {
1756     dnode_t *lower, *lowright, *upparent;
1757
1758     lower = upper->left;
1759     upper->left = lowright = lower->right;
1760     lowright->parent = upper;
1761
1762     lower->parent = upparent = upper->parent;
1763
1764     if (upper == upparent->right) {
1765         upparent->right = lower;
1766     } else {
1767         assert (upper == upparent->left);
1768         upparent->left = lower;
1769     }
1770
1771     lower->right = upper;
1772     upper->parent = lower;
1773 }
1774
1775 /*
1776  * Do a postorder traversal of the tree rooted at the specified
1777  * node and free everything under it.  Used by dict_free().
1778  */
1779
1780 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
1781 {
1782     if (node == nil)
1783         return;
1784     free_nodes(dict, node->left, nil);
1785     free_nodes(dict, node->right, nil);
1786     dict->freenode(node, dict->context);
1787 }
1788
1789 /*
1790  * Verify that the tree contains the given node. This is done by
1791  * traversing all of the nodes and comparing their pointers to the
1792  * given pointer. Returns 1 if the node is found, otherwise
1793  * returns zero. It is intended for debugging purposes.
1794  */
1795
1796 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
1797 {
1798     if (root != nil) {
1799         return root == node
1800                 || verify_dict_has_node(nil, root->left, node)
1801                 || verify_dict_has_node(nil, root->right, node);
1802     }
1803     return 0;
1804 }
1805
1806
1807 /*
1808  * Select a different set of node allocator routines.
1809  */
1810
1811 void dict_set_allocator(dict_t *dict, dnode_alloc_t al,
1812         dnode_free_t fr, void *context)
1813 {
1814     assert (dict_count(dict) == 0);
1815     assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL));
1816
1817     dict->allocnode = al ? al : dnode_alloc;
1818     dict->freenode = fr ? fr : dnode_free;
1819     dict->context = context;
1820 }
1821
1822 /*
1823  * Free all the nodes in the dictionary by using the dictionary's
1824  * installed free routine. The dictionary is emptied.
1825  */
1826
1827 void dict_free_nodes(dict_t *dict)
1828 {
1829     dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
1830     free_nodes(dict, root, nil);
1831     dict->nodecount = 0;
1832     dict->nilnode.left = &dict->nilnode;
1833     dict->nilnode.right = &dict->nilnode;
1834 }
1835
1836 /*
1837  * Initialize a user-supplied dictionary object.
1838  */
1839
1840 dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
1841 {
1842     dict->compare = comp;
1843     dict->allocnode = dnode_alloc;
1844     dict->freenode = dnode_free;
1845     dict->context = NULL;
1846     dict->nodecount = 0;
1847     dict->maxcount = maxcount;
1848     dict->nilnode.left = &dict->nilnode;
1849     dict->nilnode.right = &dict->nilnode;
1850     dict->nilnode.parent = &dict->nilnode;
1851     dict->nilnode.color = dnode_black;
1852     dict->dupes = 0;
1853     return dict;
1854 }
1855
1856 /*
1857  * Locate a node in the dictionary having the given key.
1858  * If the node is not found, a null a pointer is returned (rather than
1859  * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
1860  * located node is returned.
1861  */
1862
1863 dnode_t *dict_lookup(dict_t *dict, const void *key)
1864 {
1865     dnode_t *root = dict_root(dict);
1866     dnode_t *nil = dict_nil(dict);
1867     dnode_t *saved;
1868     int result;
1869
1870     /* simple binary search adapted for trees that contain duplicate keys */
1871
1872     while (root != nil) {
1873         result = dict->compare(key, root->key);
1874         if (result < 0)
1875             root = root->left;
1876         else if (result > 0)
1877             root = root->right;
1878         else {
1879             if (!dict->dupes) { /* no duplicates, return match          */
1880                 return root;
1881             } else {            /* could be dupes, find leftmost one    */
1882                 do {
1883                     saved = root;
1884                     root = root->left;
1885                     while (root != nil && dict->compare(key, root->key))
1886                         root = root->right;
1887                 } while (root != nil);
1888                 return saved;
1889             }
1890         }
1891     }
1892
1893     return NULL;
1894 }
1895
1896 /*
1897  * Insert a node into the dictionary. The node should have been
1898  * initialized with a data field. All other fields are ignored.
1899  * The behavior is undefined if the user attempts to insert into
1900  * a dictionary that is already full (for which the dict_isfull()
1901  * function returns true).
1902  */
1903
1904 void dict_insert(dict_t *dict, dnode_t *node, const void *key)
1905 {
1906     dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
1907     dnode_t *parent = nil, *uncle, *grandpa;
1908     int result = -1;
1909
1910     node->key = key;
1911
1912     /* basic binary tree insert */
1913
1914     while (where != nil) {
1915         parent = where;
1916         result = dict->compare(key, where->key);
1917         /* trap attempts at duplicate key insertion unless it's explicitly allowed */
1918         assert (dict->dupes || result != 0);
1919         if (result < 0)
1920             where = where->left;
1921         else
1922             where = where->right;
1923     }
1924
1925     assert (where == nil);
1926
1927     if (result < 0)
1928         parent->left = node;
1929     else
1930         parent->right = node;
1931
1932     node->parent = parent;
1933     node->left = nil;
1934     node->right = nil;
1935
1936     dict->nodecount++;
1937
1938     /* red black adjustments */
1939
1940     node->color = dnode_red;
1941
1942     while (parent->color == dnode_red) {
1943         grandpa = parent->parent;
1944         if (parent == grandpa->left) {
1945             uncle = grandpa->right;
1946             if (uncle->color == dnode_red) {    /* red parent, red uncle */
1947                 parent->color = dnode_black;
1948                 uncle->color = dnode_black;
1949                 grandpa->color = dnode_red;
1950                 node = grandpa;
1951                 parent = grandpa->parent;
1952             } else {                            /* red parent, black uncle */
1953                 if (node == parent->right) {
1954                     rotate_left(parent);
1955                     parent = node;
1956                     assert (grandpa == parent->parent);
1957                     /* rotation between parent and child preserves grandpa */
1958                 }
1959                 parent->color = dnode_black;
1960                 grandpa->color = dnode_red;
1961                 rotate_right(grandpa);
1962                 break;
1963             }
1964         } else {        /* symmetric cases: parent == parent->parent->right */
1965             uncle = grandpa->left;
1966             if (uncle->color == dnode_red) {
1967                 parent->color = dnode_black;
1968                 uncle->color = dnode_black;
1969                 grandpa->color = dnode_red;
1970                 node = grandpa;
1971                 parent = grandpa->parent;
1972             } else {
1973                 if (node == parent->left) {
1974                     rotate_right(parent);
1975                     parent = node;
1976                     assert (grandpa == parent->parent);
1977                 }
1978                 parent->color = dnode_black;
1979                 grandpa->color = dnode_red;
1980                 rotate_left(grandpa);
1981                 break;
1982             }
1983         }
1984     }
1985
1986     dict_root(dict)->color = dnode_black;
1987
1988 }
1989
1990 /*
1991  * Allocate a node using the dictionary's allocator routine, give it
1992  * the data item.
1993  */
1994
1995 int dict_alloc_insert(dict_t *dict, const void *key, void *data)
1996 {
1997     dnode_t *node = dict->allocnode(dict->context);
1998
1999     if (node) {
2000         dnode_init(node, data);
2001         dict_insert(dict, node, key);
2002         return 1;
2003     }
2004     return 0;
2005 }
2006
2007 /*
2008  * Return the node with the lowest (leftmost) key. If the dictionary is empty
2009  * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
2010  */
2011
2012 dnode_t *dict_first(dict_t *dict)
2013 {
2014     dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
2015
2016     if (root != nil)
2017         while ((left = root->left) != nil)
2018             root = left;
2019
2020     return (root == nil) ? NULL : root;
2021 }
2022
2023 /*
2024  * Return the given node's successor node---the node which has the
2025  * next key in the the left to right ordering. If the node has
2026  * no successor, a null pointer is returned rather than a pointer to
2027  * the nil node.
2028  */
2029
2030 dnode_t *dict_next(dict_t *dict, dnode_t *curr)
2031 {
2032     dnode_t *nil = dict_nil(dict), *parent, *left;
2033
2034     if (curr->right != nil) {
2035         curr = curr->right;
2036         while ((left = curr->left) != nil)
2037             curr = left;
2038         return curr;
2039     }
2040
2041     parent = curr->parent;
2042
2043     while (parent != nil && curr == parent->right) {
2044         curr = parent;
2045         parent = curr->parent;
2046     }
2047
2048     return (parent == nil) ? NULL : parent;
2049 }
2050
2051 #undef dict_count
2052 #undef dnode_get
2053 #undef dnode_getkey
2054
2055 dictcount_t dict_count(dict_t *dict)
2056 {
2057     return dict->nodecount;
2058 }
2059
2060 static dnode_t *dnode_alloc(void *context EXT2FS_ATTR((unused)))
2061 {
2062     return malloc(sizeof *dnode_alloc(NULL));
2063 }
2064
2065 static void dnode_free(dnode_t *node, void *context EXT2FS_ATTR((unused)))
2066 {
2067     free(node);
2068 }
2069
2070 dnode_t *dnode_init(dnode_t *dnode, void *data)
2071 {
2072     dnode->data = data;
2073     dnode->parent = NULL;
2074     dnode->left = NULL;
2075     dnode->right = NULL;
2076     return dnode;
2077 }
2078
2079 void *dnode_get(dnode_t *dnode)
2080 {
2081     return dnode->data;
2082 }
2083
2084 const void *dnode_getkey(dnode_t *dnode)
2085 {
2086     return dnode->key;
2087 }
2088
2089 #undef left
2090 #undef right
2091 #undef parent
2092 #undef color
2093 #undef key
2094 #undef data
2095
2096 #undef nilnode
2097 #undef nodecount
2098 #undef maxcount
2099 #undef compare
2100 #undef allocnode
2101 #undef freenode
2102 #undef context
2103 #undef dupes
2104
2105 #undef dictptr
2106
2107
2108 /*
2109  * dirinfo.c --- maintains the directory information table for e2fsck.
2110  *
2111  * Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
2112  * under the terms of the GNU Public License.
2113  */
2114
2115 /*
2116  * This subroutine is called during pass1 to create a directory info
2117  * entry.  During pass1, the passed-in parent is 0; it will get filled
2118  * in during pass2.
2119  */
2120 void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
2121 {
2122         struct dir_info *dir;
2123         int             i, j;
2124         ext2_ino_t      num_dirs;
2125         errcode_t       retval;
2126         unsigned long   old_size;
2127
2128 #if 0
2129         printf("add_dir_info for inode %lu...\n", ino);
2130 #endif
2131         if (!ctx->dir_info) {
2132                 ctx->dir_info_count = 0;
2133                 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
2134                 if (retval)
2135                         num_dirs = 1024;        /* Guess */
2136                 ctx->dir_info_size = num_dirs + 10;
2137                 ctx->dir_info  = (struct dir_info *)
2138                         e2fsck_allocate_memory(ctx, ctx->dir_info_size
2139                                                * sizeof (struct dir_info),
2140                                                "directory map");
2141         }
2142
2143         if (ctx->dir_info_count >= ctx->dir_info_size) {
2144                 old_size = ctx->dir_info_size * sizeof(struct dir_info);
2145                 ctx->dir_info_size += 10;
2146                 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
2147                                            sizeof(struct dir_info),
2148                                            &ctx->dir_info);
2149                 if (retval) {
2150                         ctx->dir_info_size -= 10;
2151                         return;
2152                 }
2153         }
2154
2155         /*
2156          * Normally, add_dir_info is called with each inode in
2157          * sequential order; but once in a while (like when pass 3
2158          * needs to recreate the root directory or lost+found
2159          * directory) it is called out of order.  In those cases, we
2160          * need to move the dir_info entries down to make room, since
2161          * the dir_info array needs to be sorted by inode number for
2162          * get_dir_info()'s sake.
2163          */
2164         if (ctx->dir_info_count &&
2165             ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
2166                 for (i = ctx->dir_info_count-1; i > 0; i--)
2167                         if (ctx->dir_info[i-1].ino < ino)
2168                                 break;
2169                 dir = &ctx->dir_info[i];
2170                 if (dir->ino != ino)
2171                         for (j = ctx->dir_info_count++; j > i; j--)
2172                                 ctx->dir_info[j] = ctx->dir_info[j-1];
2173         } else
2174                 dir = &ctx->dir_info[ctx->dir_info_count++];
2175
2176         dir->ino = ino;
2177         dir->dotdot = parent;
2178         dir->parent = parent;
2179 }
2180
2181 /*
2182  * get_dir_info() --- given an inode number, try to find the directory
2183  * information entry for it.
2184  */
2185 struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2186 {
2187         int     low, high, mid;
2188
2189         low = 0;
2190         high = ctx->dir_info_count-1;
2191         if (!ctx->dir_info)
2192                 return 0;
2193         if (ino == ctx->dir_info[low].ino)
2194                 return &ctx->dir_info[low];
2195         if  (ino == ctx->dir_info[high].ino)
2196                 return &ctx->dir_info[high];
2197
2198         while (low < high) {
2199                 mid = (low+high)/2;
2200                 if (mid == low || mid == high)
2201                         break;
2202                 if (ino == ctx->dir_info[mid].ino)
2203                         return &ctx->dir_info[mid];
2204                 if (ino < ctx->dir_info[mid].ino)
2205                         high = mid;
2206                 else
2207                         low = mid;
2208         }
2209         return 0;
2210 }
2211
2212 /*
2213  * Free the dir_info structure when it isn't needed any more.
2214  */
2215 void e2fsck_free_dir_info(e2fsck_t ctx)
2216 {
2217         if (ctx->dir_info) {
2218                 ext2fs_free_mem(&ctx->dir_info);
2219                 ctx->dir_info = 0;
2220         }
2221         ctx->dir_info_size = 0;
2222         ctx->dir_info_count = 0;
2223 }
2224
2225 /*
2226  * Return the count of number of directories in the dir_info structure
2227  */
2228 int e2fsck_get_num_dirinfo(e2fsck_t ctx)
2229 {
2230         return ctx->dir_info_count;
2231 }
2232
2233 /*
2234  * A simple interator function
2235  */
2236 struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
2237 {
2238         if (*control >= ctx->dir_info_count)
2239                 return 0;
2240
2241         return(ctx->dir_info + (*control)++);
2242 }
2243 /*
2244  * dirinfo.c --- maintains the directory information table for e2fsck.
2245  *
2246  * Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
2247  * under the terms of the GNU Public License.
2248  */
2249
2250 #ifdef ENABLE_HTREE
2251
2252 /*
2253  * This subroutine is called during pass1 to create a directory info
2254  * entry.  During pass1, the passed-in parent is 0; it will get filled
2255  * in during pass2.
2256  */
2257 void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
2258 {
2259         struct dx_dir_info *dir;
2260         int             i, j;
2261         errcode_t       retval;
2262         unsigned long   old_size;
2263
2264 #if 0
2265         printf("add_dx_dir_info for inode %lu...\n", ino);
2266 #endif
2267         if (!ctx->dx_dir_info) {
2268                 ctx->dx_dir_info_count = 0;
2269                 ctx->dx_dir_info_size = 100; /* Guess */
2270                 ctx->dx_dir_info  = (struct dx_dir_info *)
2271                         e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
2272                                                * sizeof (struct dx_dir_info),
2273                                                "directory map");
2274         }
2275
2276         if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
2277                 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
2278                 ctx->dx_dir_info_size += 10;
2279                 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
2280                                            sizeof(struct dx_dir_info),
2281                                            &ctx->dx_dir_info);
2282                 if (retval) {
2283                         ctx->dx_dir_info_size -= 10;
2284                         return;
2285                 }
2286         }
2287
2288         /*
2289          * Normally, add_dx_dir_info is called with each inode in
2290          * sequential order; but once in a while (like when pass 3
2291          * needs to recreate the root directory or lost+found
2292          * directory) it is called out of order.  In those cases, we
2293          * need to move the dx_dir_info entries down to make room, since
2294          * the dx_dir_info array needs to be sorted by inode number for
2295          * get_dx_dir_info()'s sake.
2296          */
2297         if (ctx->dx_dir_info_count &&
2298             ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
2299                 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
2300                         if (ctx->dx_dir_info[i-1].ino < ino)
2301                                 break;
2302                 dir = &ctx->dx_dir_info[i];
2303                 if (dir->ino != ino)
2304                         for (j = ctx->dx_dir_info_count++; j > i; j--)
2305                                 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
2306         } else
2307                 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
2308
2309         dir->ino = ino;
2310         dir->numblocks = num_blocks;
2311         dir->hashversion = 0;
2312         dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
2313                                        * sizeof (struct dx_dirblock_info),
2314                                        "dx_block info array");
2315
2316 }
2317
2318 /*
2319  * get_dx_dir_info() --- given an inode number, try to find the directory
2320  * information entry for it.
2321  */
2322 struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2323 {
2324         int     low, high, mid;
2325
2326         low = 0;
2327         high = ctx->dx_dir_info_count-1;
2328         if (!ctx->dx_dir_info)
2329                 return 0;
2330         if (ino == ctx->dx_dir_info[low].ino)
2331                 return &ctx->dx_dir_info[low];
2332         if  (ino == ctx->dx_dir_info[high].ino)
2333                 return &ctx->dx_dir_info[high];
2334
2335         while (low < high) {
2336                 mid = (low+high)/2;
2337                 if (mid == low || mid == high)
2338                         break;
2339                 if (ino == ctx->dx_dir_info[mid].ino)
2340                         return &ctx->dx_dir_info[mid];
2341                 if (ino < ctx->dx_dir_info[mid].ino)
2342                         high = mid;
2343                 else
2344                         low = mid;
2345         }
2346         return 0;
2347 }
2348
2349 /*
2350  * Free the dx_dir_info structure when it isn't needed any more.
2351  */
2352 void e2fsck_free_dx_dir_info(e2fsck_t ctx)
2353 {
2354         int     i;
2355         struct dx_dir_info *dir;
2356
2357         if (ctx->dx_dir_info) {
2358                 dir = ctx->dx_dir_info;
2359                 for (i=0; i < ctx->dx_dir_info_count; i++) {
2360                         if (dir->dx_block) {
2361                                 ext2fs_free_mem(&dir->dx_block);
2362                                 dir->dx_block = 0;
2363                         }
2364                 }
2365                 ext2fs_free_mem(&ctx->dx_dir_info);
2366                 ctx->dx_dir_info = 0;
2367         }
2368         ctx->dx_dir_info_size = 0;
2369         ctx->dx_dir_info_count = 0;
2370 }
2371
2372 /*
2373  * A simple interator function
2374  */
2375 struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
2376 {
2377         if (*control >= ctx->dx_dir_info_count)
2378                 return 0;
2379
2380         return(ctx->dx_dir_info + (*control)++);
2381 }
2382
2383 #endif /* ENABLE_HTREE */
2384 /*
2385  * e2fsck.c - a consistency checker for the new extended file system.
2386  *
2387  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
2388  *
2389  * %Begin-Header%
2390  * This file may be redistributed under the terms of the GNU Public
2391  * License.
2392  * %End-Header%
2393  */
2394
2395 /*
2396  * This function allocates an e2fsck context
2397  */
2398 errcode_t e2fsck_allocate_context(e2fsck_t *ret)
2399 {
2400         e2fsck_t        context;
2401         errcode_t       retval;
2402
2403         retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
2404         if (retval)
2405                 return retval;
2406
2407         memset(context, 0, sizeof(struct e2fsck_struct));
2408
2409         context->process_inode_size = 256;
2410         context->ext_attr_ver = 2;
2411
2412         *ret = context;
2413         return 0;
2414 }
2415
2416 /*
2417  * This function resets an e2fsck context; it is called when e2fsck
2418  * needs to be restarted.
2419  */
2420 errcode_t e2fsck_reset_context(e2fsck_t ctx)
2421 {
2422         ctx->flags = 0;
2423         ctx->lost_and_found = 0;
2424         ctx->bad_lost_and_found = 0;
2425         if (ctx->inode_used_map) {
2426                 ext2fs_free_inode_bitmap(ctx->inode_used_map);
2427                 ctx->inode_used_map = 0;
2428         }
2429         if (ctx->inode_dir_map) {
2430                 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
2431                 ctx->inode_dir_map = 0;
2432         }
2433         if (ctx->inode_reg_map) {
2434                 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
2435                 ctx->inode_reg_map = 0;
2436         }
2437         if (ctx->block_found_map) {
2438                 ext2fs_free_block_bitmap(ctx->block_found_map);
2439                 ctx->block_found_map = 0;
2440         }
2441         if (ctx->inode_link_info) {
2442                 ext2fs_free_icount(ctx->inode_link_info);
2443                 ctx->inode_link_info = 0;
2444         }
2445         if (ctx->journal_io) {
2446                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2447                         io_channel_close(ctx->journal_io);
2448                 ctx->journal_io = 0;
2449         }
2450         if (ctx->fs && ctx->fs->dblist) {
2451                 ext2fs_free_dblist(ctx->fs->dblist);
2452                 ctx->fs->dblist = 0;
2453         }
2454         e2fsck_free_dir_info(ctx);
2455 #ifdef ENABLE_HTREE
2456         e2fsck_free_dx_dir_info(ctx);
2457 #endif
2458         if (ctx->refcount) {
2459                 ea_refcount_free(ctx->refcount);
2460                 ctx->refcount = 0;
2461         }
2462         if (ctx->refcount_extra) {
2463                 ea_refcount_free(ctx->refcount_extra);
2464                 ctx->refcount_extra = 0;
2465         }
2466         if (ctx->block_dup_map) {
2467                 ext2fs_free_block_bitmap(ctx->block_dup_map);
2468                 ctx->block_dup_map = 0;
2469         }
2470         if (ctx->block_ea_map) {
2471                 ext2fs_free_block_bitmap(ctx->block_ea_map);
2472                 ctx->block_ea_map = 0;
2473         }
2474         if (ctx->inode_bb_map) {
2475                 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
2476                 ctx->inode_bb_map = 0;
2477         }
2478         if (ctx->inode_bad_map) {
2479                 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
2480                 ctx->inode_bad_map = 0;
2481         }
2482         if (ctx->inode_imagic_map) {
2483                 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
2484                 ctx->inode_imagic_map = 0;
2485         }
2486         if (ctx->dirs_to_hash) {
2487                 ext2fs_u32_list_free(ctx->dirs_to_hash);
2488                 ctx->dirs_to_hash = 0;
2489         }
2490
2491         /*
2492          * Clear the array of invalid meta-data flags
2493          */
2494         if (ctx->invalid_inode_bitmap_flag) {
2495                 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
2496                 ctx->invalid_inode_bitmap_flag = 0;
2497         }
2498         if (ctx->invalid_block_bitmap_flag) {
2499                 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
2500                 ctx->invalid_block_bitmap_flag = 0;
2501         }
2502         if (ctx->invalid_inode_table_flag) {
2503                 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
2504                 ctx->invalid_inode_table_flag = 0;
2505         }
2506
2507         /* Clear statistic counters */
2508         ctx->fs_directory_count = 0;
2509         ctx->fs_regular_count = 0;
2510         ctx->fs_blockdev_count = 0;
2511         ctx->fs_chardev_count = 0;
2512         ctx->fs_links_count = 0;
2513         ctx->fs_symlinks_count = 0;
2514         ctx->fs_fast_symlinks_count = 0;
2515         ctx->fs_fifo_count = 0;
2516         ctx->fs_total_count = 0;
2517         ctx->fs_badblocks_count = 0;
2518         ctx->fs_sockets_count = 0;
2519         ctx->fs_ind_count = 0;
2520         ctx->fs_dind_count = 0;
2521         ctx->fs_tind_count = 0;
2522         ctx->fs_fragmented = 0;
2523         ctx->large_files = 0;
2524
2525         /* Reset the superblock to the user's requested value */
2526         ctx->superblock = ctx->use_superblock;
2527
2528         return 0;
2529 }
2530
2531 void e2fsck_free_context(e2fsck_t ctx)
2532 {
2533         if (!ctx)
2534                 return;
2535
2536         e2fsck_reset_context(ctx);
2537         if (ctx->blkid)
2538                 blkid_put_cache(ctx->blkid);
2539
2540         ext2fs_free_mem(&ctx);
2541 }
2542
2543 /*
2544  * This function runs through the e2fsck passes and calls them all,
2545  * returning restart, abort, or cancel as necessary...
2546  */
2547 typedef void (*pass_t)(e2fsck_t ctx);
2548
2549 static pass_t e2fsck_passes[] = {
2550         e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
2551         e2fsck_pass5, 0 };
2552
2553 #define E2F_FLAG_RUN_RETURN     (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
2554
2555 int e2fsck_run(e2fsck_t ctx)
2556 {
2557         int     i;
2558         pass_t  e2fsck_pass;
2559
2560         if (setjmp(ctx->abort_loc)) {
2561                 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
2562                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
2563         }
2564         ctx->flags |= E2F_FLAG_SETJMP_OK;
2565
2566         for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
2567                 if (ctx->flags & E2F_FLAG_RUN_RETURN)
2568                         break;
2569                 e2fsck_pass(ctx);
2570                 if (ctx->progress)
2571                         (void) (ctx->progress)(ctx, 0, 0, 0);
2572         }
2573         ctx->flags &= ~E2F_FLAG_SETJMP_OK;
2574
2575         if (ctx->flags & E2F_FLAG_RUN_RETURN)
2576                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
2577         return 0;
2578 }
2579 /*
2580  * ea_refcount.c
2581  *
2582  * Copyright (C) 2001 Theodore Ts'o.  This file may be
2583  * redistributed under the terms of the GNU Public License.
2584  */
2585
2586 /*
2587  * The strategy we use for keeping track of EA refcounts is as
2588  * follows.  We keep a sorted array of first EA blocks and its
2589  * reference counts.  Once the refcount has dropped to zero, it is
2590  * removed from the array to save memory space.  Once the EA block is
2591  * checked, its bit is set in the block_ea_map bitmap.
2592  */
2593 struct ea_refcount_el {
2594         blk_t   ea_blk;
2595         int     ea_count;
2596 };
2597
2598 struct ea_refcount {
2599         blk_t           count;
2600         blk_t           size;
2601         blk_t           cursor;
2602         struct ea_refcount_el   *list;
2603 };
2604
2605 void ea_refcount_free(ext2_refcount_t refcount)
2606 {
2607         if (!refcount)
2608                 return;
2609
2610         if (refcount->list)
2611                 ext2fs_free_mem(&refcount->list);
2612         ext2fs_free_mem(&refcount);
2613 }
2614
2615 errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
2616 {
2617         ext2_refcount_t refcount;
2618         errcode_t       retval;
2619         size_t          bytes;
2620
2621         retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
2622         if (retval)
2623                 return retval;
2624         memset(refcount, 0, sizeof(struct ea_refcount));
2625
2626         if (!size)
2627                 size = 500;
2628         refcount->size = size;
2629         bytes = (size_t) (size * sizeof(struct ea_refcount_el));
2630 #ifdef DEBUG
2631         printf("Refcount allocated %d entries, %d bytes.\n",
2632                refcount->size, bytes);
2633 #endif
2634         retval = ext2fs_get_mem(bytes, &refcount->list);
2635         if (retval)
2636                 goto errout;
2637         memset(refcount->list, 0, bytes);
2638
2639         refcount->count = 0;
2640         refcount->cursor = 0;
2641
2642         *ret = refcount;
2643         return 0;
2644
2645 errout:
2646         ea_refcount_free(refcount);
2647         return(retval);
2648 }
2649
2650 /*
2651  * collapse_refcount() --- go through the refcount array, and get rid
2652  * of any count == zero entries
2653  */
2654 static void refcount_collapse(ext2_refcount_t refcount)
2655 {
2656         unsigned int    i, j;
2657         struct ea_refcount_el   *list;
2658
2659         list = refcount->list;
2660         for (i = 0, j = 0; i < refcount->count; i++) {
2661                 if (list[i].ea_count) {
2662                         if (i != j)
2663                                 list[j] = list[i];
2664                         j++;
2665                 }
2666         }
2667 #if defined(DEBUG) || defined(TEST_PROGRAM)
2668         printf("Refcount_collapse: size was %d, now %d\n",
2669                refcount->count, j);
2670 #endif
2671         refcount->count = j;
2672 }
2673
2674
2675 /*
2676  * insert_refcount_el() --- Insert a new entry into the sorted list at a
2677  *      specified position.
2678  */
2679 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
2680                                                  blk_t blk, int pos)
2681 {
2682         struct ea_refcount_el   *el;
2683         errcode_t               retval;
2684         blk_t                   new_size = 0;
2685         int                     num;
2686
2687         if (refcount->count >= refcount->size) {
2688                 new_size = refcount->size + 100;
2689 #ifdef DEBUG
2690                 printf("Reallocating refcount %d entries...\n", new_size);
2691 #endif
2692                 retval = ext2fs_resize_mem((size_t) refcount->size *
2693                                            sizeof(struct ea_refcount_el),
2694                                            (size_t) new_size *
2695                                            sizeof(struct ea_refcount_el),
2696                                            &refcount->list);
2697                 if (retval)
2698                         return 0;
2699                 refcount->size = new_size;
2700         }
2701         num = (int) refcount->count - pos;
2702         if (num < 0)
2703                 return 0;       /* should never happen */
2704         if (num) {
2705                 memmove(&refcount->list[pos+1], &refcount->list[pos],
2706                         sizeof(struct ea_refcount_el) * num);
2707         }
2708         refcount->count++;
2709         el = &refcount->list[pos];
2710         el->ea_count = 0;
2711         el->ea_blk = blk;
2712         return el;
2713 }
2714
2715
2716 /*
2717  * get_refcount_el() --- given an block number, try to find refcount
2718  *      information in the sorted list.  If the create flag is set,
2719  *      and we can't find an entry, create one in the sorted list.
2720  */
2721 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
2722                                               blk_t blk, int create)
2723 {
2724         float   range;
2725         int     low, high, mid;
2726         blk_t   lowval, highval;
2727
2728         if (!refcount || !refcount->list)
2729                 return 0;
2730 retry:
2731         low = 0;
2732         high = (int) refcount->count-1;
2733         if (create && ((refcount->count == 0) ||
2734                        (blk > refcount->list[high].ea_blk))) {
2735                 if (refcount->count >= refcount->size)
2736                         refcount_collapse(refcount);
2737
2738                 return insert_refcount_el(refcount, blk,
2739                                           (unsigned) refcount->count);
2740         }
2741         if (refcount->count == 0)
2742                 return 0;
2743
2744         if (refcount->cursor >= refcount->count)
2745                 refcount->cursor = 0;
2746         if (blk == refcount->list[refcount->cursor].ea_blk)
2747                 return &refcount->list[refcount->cursor++];
2748 #ifdef DEBUG
2749         printf("Non-cursor get_refcount_el: %u\n", blk);
2750 #endif
2751         while (low <= high) {
2752 #if 0
2753                 mid = (low+high)/2;
2754 #else
2755                 if (low == high)
2756                         mid = low;
2757                 else {
2758                         /* Interpolate for efficiency */
2759                         lowval = refcount->list[low].ea_blk;
2760                         highval = refcount->list[high].ea_blk;
2761
2762                         if (blk < lowval)
2763                                 range = 0;
2764                         else if (blk > highval)
2765                                 range = 1;
2766                         else
2767                                 range = ((float) (blk - lowval)) /
2768                                         (highval - lowval);
2769                         mid = low + ((int) (range * (high-low)));
2770                 }
2771 #endif
2772                 if (blk == refcount->list[mid].ea_blk) {
2773                         refcount->cursor = mid+1;
2774                         return &refcount->list[mid];
2775                 }
2776                 if (blk < refcount->list[mid].ea_blk)
2777                         high = mid-1;
2778                 else
2779                         low = mid+1;
2780         }
2781         /*
2782          * If we need to create a new entry, it should be right at
2783          * low (where high will be left at low-1).
2784          */
2785         if (create) {
2786                 if (refcount->count >= refcount->size) {
2787                         refcount_collapse(refcount);
2788                         if (refcount->count < refcount->size)
2789                                 goto retry;
2790                 }
2791                 return insert_refcount_el(refcount, blk, low);
2792         }
2793         return 0;
2794 }
2795
2796 errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
2797 {
2798         struct ea_refcount_el   *el;
2799
2800         el = get_refcount_el(refcount, blk, 1);
2801         if (!el)
2802                 return EXT2_ET_NO_MEMORY;
2803         el->ea_count++;
2804
2805         if (ret)
2806                 *ret = el->ea_count;
2807         return 0;
2808 }
2809
2810 errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
2811 {
2812         struct ea_refcount_el   *el;
2813
2814         el = get_refcount_el(refcount, blk, 0);
2815         if (!el || el->ea_count == 0)
2816                 return EXT2_ET_INVALID_ARGUMENT;
2817
2818         el->ea_count--;
2819
2820         if (ret)
2821                 *ret = el->ea_count;
2822         return 0;
2823 }
2824
2825 errcode_t ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
2826 {
2827         struct ea_refcount_el   *el;
2828
2829         /*
2830          * Get the refcount element
2831          */
2832         el = get_refcount_el(refcount, blk, count ? 1 : 0);
2833         if (!el)
2834                 return count ? EXT2_ET_NO_MEMORY : 0;
2835         el->ea_count = count;
2836         return 0;
2837 }
2838
2839 void ea_refcount_intr_begin(ext2_refcount_t refcount)
2840 {
2841         refcount->cursor = 0;
2842 }
2843
2844
2845 blk_t ea_refcount_intr_next(ext2_refcount_t refcount,
2846                                 int *ret)
2847 {
2848         struct ea_refcount_el   *list;
2849
2850         while (1) {
2851                 if (refcount->cursor >= refcount->count)
2852                         return 0;
2853                 list = refcount->list;
2854                 if (list[refcount->cursor].ea_count) {
2855                         if (ret)
2856                                 *ret = list[refcount->cursor].ea_count;
2857                         return list[refcount->cursor++].ea_blk;
2858                 }
2859                 refcount->cursor++;
2860         }
2861 }
2862
2863
2864 /*
2865  * ehandler.c --- handle bad block errors which come up during the
2866  *      course of an e2fsck session.
2867  *
2868  * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
2869  * under the terms of the GNU Public License.
2870  */
2871
2872
2873 static const char *operation;
2874
2875 static errcode_t e2fsck_handle_read_error(io_channel channel,
2876                                           unsigned long block,
2877                                           int count,
2878                                           void *data,
2879                                           size_t size EXT2FS_ATTR((unused)),
2880                                           int actual EXT2FS_ATTR((unused)),
2881                                           errcode_t error)
2882 {
2883         int     i;
2884         char    *p;
2885         ext2_filsys fs = (ext2_filsys) channel->app_data;
2886         e2fsck_t ctx;
2887
2888         ctx = (e2fsck_t) fs->priv_data;
2889
2890         /*
2891          * If more than one block was read, try reading each block
2892          * separately.  We could use the actual bytes read to figure
2893          * out where to start, but we don't bother.
2894          */
2895         if (count > 1) {
2896                 p = (char *) data;
2897                 for (i=0; i < count; i++, p += channel->block_size, block++) {
2898                         error = io_channel_read_blk(channel, block,
2899                                                     1, p);
2900                         if (error)
2901                                 return error;
2902                 }
2903                 return 0;
2904         }
2905         if (operation)
2906                 printf(_("Error reading block %lu (%s) while %s.  "), block,
2907                        error_message(error), operation);
2908         else
2909                 printf(_("Error reading block %lu (%s).  "), block,
2910                        error_message(error));
2911         preenhalt(ctx);
2912         if (ask(ctx, _("Ignore error"), 1)) {
2913                 if (ask(ctx, _("Force rewrite"), 1))
2914                         io_channel_write_blk(channel, block, 1, data);
2915                 return 0;
2916         }
2917
2918         return error;
2919 }
2920
2921 static errcode_t e2fsck_handle_write_error(io_channel channel,
2922                                             unsigned long block,
2923                                             int count,
2924                                             const void *data,
2925                                             size_t size EXT2FS_ATTR((unused)),
2926                                             int actual EXT2FS_ATTR((unused)),
2927                                             errcode_t error)
2928 {
2929         int             i;
2930         const char      *p;
2931         ext2_filsys fs = (ext2_filsys) channel->app_data;
2932         e2fsck_t ctx;
2933
2934         ctx = (e2fsck_t) fs->priv_data;
2935
2936         /*
2937          * If more than one block was written, try writing each block
2938          * separately.  We could use the actual bytes read to figure
2939          * out where to start, but we don't bother.
2940          */
2941         if (count > 1) {
2942                 p = (const char *) data;
2943                 for (i=0; i < count; i++, p += channel->block_size, block++) {
2944                         error = io_channel_write_blk(channel, block,
2945                                                      1, p);
2946                         if (error)
2947                                 return error;
2948                 }
2949                 return 0;
2950         }
2951
2952         if (operation)
2953                 printf(_("Error writing block %lu (%s) while %s.  "), block,
2954                        error_message(error), operation);
2955         else
2956                 printf(_("Error writing block %lu (%s).  "), block,
2957                        error_message(error));
2958         preenhalt(ctx);
2959         if (ask(ctx, _("Ignore error"), 1))
2960                 return 0;
2961
2962         return error;
2963 }
2964
2965 const char *ehandler_operation(const char *op)
2966 {
2967         const char *ret = operation;
2968
2969         operation = op;
2970         return ret;
2971 }
2972
2973 void ehandler_init(io_channel channel)
2974 {
2975         channel->read_error = e2fsck_handle_read_error;
2976         channel->write_error = e2fsck_handle_write_error;
2977 }
2978 /*
2979  * journal.c --- code for handling the "ext3" journal
2980  *
2981  * Copyright (C) 2000 Andreas Dilger
2982  * Copyright (C) 2000 Theodore Ts'o
2983  *
2984  * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
2985  * Copyright (C) 1999 Red Hat Software
2986  *
2987  * This file may be redistributed under the terms of the
2988  * GNU General Public License version 2 or at your discretion
2989  * any later version.
2990  */
2991
2992 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
2993
2994
2995 #ifdef __CONFIG_JBD_DEBUG__E2FS         /* Enabled by configure --enable-jfs-debug */
2996 static int bh_count = 0;
2997 #endif
2998
2999 /*
3000  * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
3001  * This creates a larger static binary, and a smaller binary using
3002  * shared libraries.  It's also probably slightly less CPU-efficient,
3003  * which is why it's not on by default.  But, it's a good way of
3004  * testing the functions in inode_io.c and fileio.c.
3005  */
3006 #undef USE_INODE_IO
3007
3008 /* Kernel compatibility functions for handling the journal.  These allow us
3009  * to use the recovery.c file virtually unchanged from the kernel, so we
3010  * don't have to do much to keep kernel and user recovery in sync.
3011  */
3012 int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
3013 {
3014 #ifdef USE_INODE_IO
3015         *phys = block;
3016         return 0;
3017 #else
3018         struct inode    *inode = journal->j_inode;
3019         errcode_t       retval;
3020         blk_t           pblk;
3021
3022         if (!inode) {
3023                 *phys = block;
3024                 return 0;
3025         }
3026
3027         retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
3028                             &inode->i_ext2, NULL, 0, block, &pblk);
3029         *phys = pblk;
3030         return (retval);
3031 #endif
3032 }
3033
3034 struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
3035 {
3036         struct buffer_head *bh;
3037
3038         bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
3039         if (!bh)
3040                 return NULL;
3041
3042         jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n",
3043                   (unsigned long) blocknr, blocksize, ++bh_count);
3044
3045         bh->b_ctx = kdev->k_ctx;
3046         if (kdev->k_dev == K_DEV_FS)
3047                 bh->b_io = kdev->k_ctx->fs->io;
3048         else
3049                 bh->b_io = kdev->k_ctx->journal_io;
3050         bh->b_size = blocksize;
3051         bh->b_blocknr = blocknr;
3052
3053         return bh;
3054 }
3055
3056 void sync_blockdev(kdev_t kdev)
3057 {
3058         io_channel      io;
3059
3060         if (kdev->k_dev == K_DEV_FS)
3061                 io = kdev->k_ctx->fs->io;
3062         else
3063                 io = kdev->k_ctx->journal_io;
3064
3065         io_channel_flush(io);
3066 }
3067
3068 void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
3069 {
3070         int retval;
3071         struct buffer_head *bh;
3072
3073         for (; nr > 0; --nr) {
3074                 bh = *bhp++;
3075                 if (rw == READ && !bh->b_uptodate) {
3076                         jfs_debug(3, "reading block %lu/%p\n",
3077                                   (unsigned long) bh->b_blocknr, (void *) bh);
3078                         retval = io_channel_read_blk(bh->b_io,
3079                                                      bh->b_blocknr,
3080                                                      1, bh->b_data);
3081                         if (retval) {
3082                                 com_err(bh->b_ctx->device_name, retval,
3083                                         "while reading block %lu\n",
3084                                         (unsigned long) bh->b_blocknr);
3085                                 bh->b_err = retval;
3086                                 continue;
3087                         }
3088                         bh->b_uptodate = 1;
3089                 } else if (rw == WRITE && bh->b_dirty) {
3090                         jfs_debug(3, "writing block %lu/%p\n",
3091                                   (unsigned long) bh->b_blocknr, (void *) bh);
3092                         retval = io_channel_write_blk(bh->b_io,
3093                                                       bh->b_blocknr,
3094                                                       1, bh->b_data);
3095                         if (retval) {
3096                                 com_err(bh->b_ctx->device_name, retval,
3097                                         "while writing block %lu\n",
3098                                         (unsigned long) bh->b_blocknr);
3099                                 bh->b_err = retval;
3100                                 continue;
3101                         }
3102                         bh->b_dirty = 0;
3103                         bh->b_uptodate = 1;
3104                 } else {
3105                         jfs_debug(3, "no-op %s for block %lu\n",
3106                                   rw == READ ? "read" : "write",
3107                                   (unsigned long) bh->b_blocknr);
3108                 }
3109         }
3110 }
3111
3112 void mark_buffer_dirty(struct buffer_head *bh)
3113 {
3114         bh->b_dirty = 1;
3115 }
3116
3117 static void mark_buffer_clean(struct buffer_head * bh)
3118 {
3119         bh->b_dirty = 0;
3120 }
3121
3122 void brelse(struct buffer_head *bh)
3123 {
3124         if (bh->b_dirty)
3125                 ll_rw_block(WRITE, 1, &bh);
3126         jfs_debug(3, "freeing block %lu/%p (total %d)\n",
3127                   (unsigned long) bh->b_blocknr, (void *) bh, --bh_count);
3128         ext2fs_free_mem(&bh);
3129 }
3130
3131 int buffer_uptodate(struct buffer_head *bh)
3132 {
3133         return bh->b_uptodate;
3134 }
3135
3136 void mark_buffer_uptodate(struct buffer_head *bh, int val)
3137 {
3138         bh->b_uptodate = val;
3139 }
3140
3141 void wait_on_buffer(struct buffer_head *bh)
3142 {
3143         if (!bh->b_uptodate)
3144                 ll_rw_block(READ, 1, &bh);
3145 }
3146
3147
3148 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
3149 {
3150         ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
3151
3152         /* if we had an error doing journal recovery, we need a full fsck */
3153         if (error)
3154                 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
3155         ext2fs_mark_super_dirty(ctx->fs);
3156 }
3157
3158 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
3159 {
3160         struct ext2_super_block *sb = ctx->fs->super;
3161         struct ext2_super_block jsuper;
3162         struct problem_context  pctx;
3163         struct buffer_head      *bh;
3164         struct inode            *j_inode = NULL;
3165         struct kdev_s           *dev_fs = NULL, *dev_journal;
3166         const char              *journal_name = 0;
3167         journal_t               *journal = NULL;
3168         errcode_t               retval = 0;
3169         io_manager              io_ptr = 0;
3170         unsigned long           start = 0;
3171         blk_t                   blk;
3172         int                     ext_journal = 0;
3173         int                     tried_backup_jnl = 0;
3174         int                     i;
3175
3176         clear_problem_context(&pctx);
3177
3178         journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
3179         if (!journal) {
3180                 return EXT2_ET_NO_MEMORY;
3181         }
3182
3183         dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
3184         if (!dev_fs) {
3185                 retval = EXT2_ET_NO_MEMORY;
3186                 goto errout;
3187         }
3188         dev_journal = dev_fs+1;
3189
3190         dev_fs->k_ctx = dev_journal->k_ctx = ctx;
3191         dev_fs->k_dev = K_DEV_FS;
3192         dev_journal->k_dev = K_DEV_JOURNAL;
3193
3194         journal->j_dev = dev_journal;
3195         journal->j_fs_dev = dev_fs;
3196         journal->j_inode = NULL;
3197         journal->j_blocksize = ctx->fs->blocksize;
3198
3199         if (uuid_is_null(sb->s_journal_uuid)) {
3200                 if (!sb->s_journal_inum)
3201                         return EXT2_ET_BAD_INODE_NUM;
3202                 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
3203                                                  "journal inode");
3204                 if (!j_inode) {
3205                         retval = EXT2_ET_NO_MEMORY;
3206                         goto errout;
3207                 }
3208
3209                 j_inode->i_ctx = ctx;
3210                 j_inode->i_ino = sb->s_journal_inum;
3211
3212                 if ((retval = ext2fs_read_inode(ctx->fs,
3213                                                 sb->s_journal_inum,
3214                                                 &j_inode->i_ext2))) {
3215                 try_backup_journal:
3216                         if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
3217                             tried_backup_jnl)
3218                                 goto errout;
3219                         memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
3220                         memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
3221                                EXT2_N_BLOCKS*4);
3222                         j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
3223                         j_inode->i_ext2.i_links_count = 1;
3224                         j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
3225                         tried_backup_jnl++;
3226                 }
3227                 if (!j_inode->i_ext2.i_links_count ||
3228                     !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
3229                         retval = EXT2_ET_NO_JOURNAL;
3230                         goto try_backup_journal;
3231                 }
3232                 if (j_inode->i_ext2.i_size / journal->j_blocksize <
3233                     JFS_MIN_JOURNAL_BLOCKS) {
3234                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
3235                         goto try_backup_journal;
3236                 }
3237                 for (i=0; i < EXT2_N_BLOCKS; i++) {
3238                         blk = j_inode->i_ext2.i_block[i];
3239                         if (!blk) {
3240                                 if (i < EXT2_NDIR_BLOCKS) {
3241                                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
3242                                         goto try_backup_journal;
3243                                 }
3244                                 continue;
3245                         }
3246                         if (blk < sb->s_first_data_block ||
3247                             blk >= sb->s_blocks_count) {
3248                                 retval = EXT2_ET_BAD_BLOCK_NUM;
3249                                 goto try_backup_journal;
3250                         }
3251                 }
3252                 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
3253
3254 #ifdef USE_INODE_IO
3255                 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
3256                                                  &j_inode->i_ext2,
3257                                                  &journal_name);
3258                 if (retval)
3259                         goto errout;
3260
3261                 io_ptr = inode_io_manager;
3262 #else
3263                 journal->j_inode = j_inode;
3264                 ctx->journal_io = ctx->fs->io;
3265                 if ((retval = journal_bmap(journal, 0, &start)) != 0)
3266                         goto errout;
3267 #endif
3268         } else {
3269                 ext_journal = 1;
3270                 if (!ctx->journal_name) {
3271                         char uuid[37];
3272
3273                         uuid_unparse(sb->s_journal_uuid, uuid);
3274                         ctx->journal_name = blkid_get_devname(ctx->blkid,
3275                                                               "UUID", uuid);
3276                         if (!ctx->journal_name)
3277                                 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
3278                 }
3279                 journal_name = ctx->journal_name;
3280
3281                 if (!journal_name) {
3282                         fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
3283                         return EXT2_ET_LOAD_EXT_JOURNAL;
3284                 }
3285
3286                 jfs_debug(1, "Using journal file %s\n", journal_name);
3287                 io_ptr = unix_io_manager;
3288         }
3289
3290 #if 0
3291         test_io_backing_manager = io_ptr;
3292         io_ptr = test_io_manager;
3293 #endif
3294 #ifndef USE_INODE_IO
3295         if (ext_journal)
3296 #endif
3297                 retval = io_ptr->open(journal_name, IO_FLAG_RW,
3298                                       &ctx->journal_io);
3299         if (retval)
3300                 goto errout;
3301
3302         io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
3303
3304         if (ext_journal) {
3305                 if (ctx->fs->blocksize == 1024)
3306                         start = 1;
3307                 bh = getblk(dev_journal, start, ctx->fs->blocksize);
3308                 if (!bh) {
3309                         retval = EXT2_ET_NO_MEMORY;
3310                         goto errout;
3311                 }
3312                 ll_rw_block(READ, 1, &bh);
3313                 if ((retval = bh->b_err) != 0)
3314                         goto errout;
3315                 memcpy(&jsuper, start ? bh->b_data :  bh->b_data + 1024,
3316                        sizeof(jsuper));
3317                 brelse(bh);
3318 #ifdef EXT2FS_ENABLE_SWAPFS
3319                 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
3320                         ext2fs_swap_super(&jsuper);
3321 #endif
3322                 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
3323                     !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
3324                         fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
3325                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
3326                         goto errout;
3327                 }
3328                 /* Make sure the journal UUID is correct */
3329                 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
3330                            sizeof(jsuper.s_uuid))) {
3331                         fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
3332                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
3333                         goto errout;
3334                 }
3335
3336                 journal->j_maxlen = jsuper.s_blocks_count;
3337                 start++;
3338         }
3339
3340         if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
3341                 retval = EXT2_ET_NO_MEMORY;
3342                 goto errout;
3343         }
3344
3345         journal->j_sb_buffer = bh;
3346         journal->j_superblock = (journal_superblock_t *)bh->b_data;
3347
3348 #ifdef USE_INODE_IO
3349         if (j_inode)
3350                 ext2fs_free_mem(&j_inode);
3351 #endif
3352
3353         *ret_journal = journal;
3354         return 0;
3355
3356 errout:
3357         if (dev_fs)
3358                 ext2fs_free_mem(&dev_fs);
3359         if (j_inode)
3360                 ext2fs_free_mem(&j_inode);
3361         if (journal)
3362                 ext2fs_free_mem(&journal);
3363         return retval;
3364
3365 }
3366
3367 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
3368                                               struct problem_context *pctx)
3369 {
3370         struct ext2_super_block *sb = ctx->fs->super;
3371         int recover = ctx->fs->super->s_feature_incompat &
3372                 EXT3_FEATURE_INCOMPAT_RECOVER;
3373         int has_journal = ctx->fs->super->s_feature_compat &
3374                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3375
3376         if (has_journal || sb->s_journal_inum) {
3377                 /* The journal inode is bogus, remove and force full fsck */
3378                 pctx->ino = sb->s_journal_inum;
3379                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
3380                         if (has_journal && sb->s_journal_inum)
3381                                 printf("*** ext3 journal has been deleted - "
3382                                        "filesystem is now ext2 only ***\n\n");
3383                         sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3384                         sb->s_journal_inum = 0;
3385                         ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
3386                         e2fsck_clear_recover(ctx, 1);
3387                         return 0;
3388                 }
3389                 return EXT2_ET_BAD_INODE_NUM;
3390         } else if (recover) {
3391                 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
3392                         e2fsck_clear_recover(ctx, 1);
3393                         return 0;
3394                 }
3395                 return EXT2_ET_UNSUPP_FEATURE;
3396         }
3397         return 0;
3398 }
3399
3400 #define V1_SB_SIZE      0x0024
3401 static void clear_v2_journal_fields(journal_t *journal)
3402 {
3403         e2fsck_t ctx = journal->j_dev->k_ctx;
3404         struct problem_context pctx;
3405
3406         clear_problem_context(&pctx);
3407
3408         if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
3409                 return;
3410
3411         memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
3412                ctx->fs->blocksize-V1_SB_SIZE);
3413         mark_buffer_dirty(journal->j_sb_buffer);
3414 }
3415
3416
3417 static errcode_t e2fsck_journal_load(journal_t *journal)
3418 {
3419         e2fsck_t ctx = journal->j_dev->k_ctx;
3420         journal_superblock_t *jsb;
3421         struct buffer_head *jbh = journal->j_sb_buffer;
3422         struct problem_context pctx;
3423
3424         clear_problem_context(&pctx);
3425
3426         ll_rw_block(READ, 1, &jbh);
3427         if (jbh->b_err) {
3428                 com_err(ctx->device_name, jbh->b_err,
3429                         _("reading journal superblock\n"));
3430                 return jbh->b_err;
3431         }
3432
3433         jsb = journal->j_superblock;
3434         /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
3435         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
3436                 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3437
3438         switch (ntohl(jsb->s_header.h_blocktype)) {
3439         case JFS_SUPERBLOCK_V1:
3440                 journal->j_format_version = 1;
3441                 if (jsb->s_feature_compat ||
3442                     jsb->s_feature_incompat ||
3443                     jsb->s_feature_ro_compat ||
3444                     jsb->s_nr_users)
3445                         clear_v2_journal_fields(journal);
3446                 break;
3447
3448         case JFS_SUPERBLOCK_V2:
3449                 journal->j_format_version = 2;
3450                 if (ntohl(jsb->s_nr_users) > 1 &&
3451                     uuid_is_null(ctx->fs->super->s_journal_uuid))
3452                         clear_v2_journal_fields(journal);
3453                 if (ntohl(jsb->s_nr_users) > 1) {
3454                         fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
3455                         return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3456                 }
3457                 break;
3458
3459         /*
3460          * These should never appear in a journal super block, so if
3461          * they do, the journal is badly corrupted.
3462          */
3463         case JFS_DESCRIPTOR_BLOCK:
3464         case JFS_COMMIT_BLOCK:
3465         case JFS_REVOKE_BLOCK:
3466                 return EXT2_ET_CORRUPT_SUPERBLOCK;
3467
3468         /* If we don't understand the superblock major type, but there
3469          * is a magic number, then it is likely to be a new format we
3470          * just don't understand, so leave it alone. */
3471         default:
3472                 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3473         }
3474
3475         if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
3476                 return EXT2_ET_UNSUPP_FEATURE;
3477
3478         if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
3479                 return EXT2_ET_RO_UNSUPP_FEATURE;
3480
3481         /* We have now checked whether we know enough about the journal
3482          * format to be able to proceed safely, so any other checks that
3483          * fail we should attempt to recover from. */
3484         if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
3485                 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3486                         _("%s: no valid journal superblock found\n"),
3487                         ctx->device_name);
3488                 return EXT2_ET_CORRUPT_SUPERBLOCK;
3489         }
3490
3491         if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
3492                 journal->j_maxlen = ntohl(jsb->s_maxlen);
3493         else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
3494                 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3495                         _("%s: journal too short\n"),
3496                         ctx->device_name);
3497                 return EXT2_ET_CORRUPT_SUPERBLOCK;
3498         }
3499
3500         journal->j_tail_sequence = ntohl(jsb->s_sequence);
3501         journal->j_transaction_sequence = journal->j_tail_sequence;
3502         journal->j_tail = ntohl(jsb->s_start);
3503         journal->j_first = ntohl(jsb->s_first);
3504         journal->j_last = ntohl(jsb->s_maxlen);
3505
3506         return 0;
3507 }
3508
3509 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
3510                                        journal_t *journal)
3511 {
3512         char *p;
3513         union {
3514                 uuid_t uuid;
3515                 __u32 val[4];
3516         } u;
3517         __u32 new_seq = 0;
3518         int i;
3519
3520         /* Leave a valid existing V1 superblock signature alone.
3521          * Anything unrecognisable we overwrite with a new V2
3522          * signature. */
3523
3524         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
3525             jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
3526                 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
3527                 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
3528         }
3529
3530         /* Zero out everything else beyond the superblock header */
3531
3532         p = ((char *) jsb) + sizeof(journal_header_t);
3533         memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
3534
3535         jsb->s_blocksize = htonl(ctx->fs->blocksize);
3536         jsb->s_maxlen = htonl(journal->j_maxlen);
3537         jsb->s_first = htonl(1);
3538
3539         /* Initialize the journal sequence number so that there is "no"
3540          * chance we will find old "valid" transactions in the journal.
3541          * This avoids the need to zero the whole journal (slow to do,
3542          * and risky when we are just recovering the filesystem).
3543          */
3544         uuid_generate(u.uuid);
3545         for (i = 0; i < 4; i ++)
3546                 new_seq ^= u.val[i];
3547         jsb->s_sequence = htonl(new_seq);
3548
3549         mark_buffer_dirty(journal->j_sb_buffer);
3550         ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
3551 }
3552
3553 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
3554                                                   journal_t *journal,
3555                                                   struct problem_context *pctx)
3556 {
3557         struct ext2_super_block *sb = ctx->fs->super;
3558         int recover = ctx->fs->super->s_feature_incompat &
3559                 EXT3_FEATURE_INCOMPAT_RECOVER;
3560
3561         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
3562                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
3563                         e2fsck_journal_reset_super(ctx, journal->j_superblock,
3564                                                    journal);
3565                         journal->j_transaction_sequence = 1;
3566                         e2fsck_clear_recover(ctx, recover);
3567                         return 0;
3568                 }
3569                 return EXT2_ET_CORRUPT_SUPERBLOCK;
3570         } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
3571                 return EXT2_ET_CORRUPT_SUPERBLOCK;
3572
3573         return 0;
3574 }
3575
3576 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
3577                                    int reset, int drop)
3578 {
3579         journal_superblock_t *jsb;
3580
3581         if (drop)
3582                 mark_buffer_clean(journal->j_sb_buffer);
3583         else if (!(ctx->options & E2F_OPT_READONLY)) {
3584                 jsb = journal->j_superblock;
3585                 jsb->s_sequence = htonl(journal->j_transaction_sequence);
3586                 if (reset)
3587                         jsb->s_start = 0; /* this marks the journal as empty */
3588                 mark_buffer_dirty(journal->j_sb_buffer);
3589         }
3590         brelse(journal->j_sb_buffer);
3591
3592         if (ctx->journal_io) {
3593                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
3594                         io_channel_close(ctx->journal_io);
3595                 ctx->journal_io = 0;
3596         }
3597
3598 #ifndef USE_INODE_IO
3599         if (journal->j_inode)
3600                 ext2fs_free_mem(&journal->j_inode);
3601 #endif
3602         if (journal->j_fs_dev)
3603                 ext2fs_free_mem(&journal->j_fs_dev);
3604         ext2fs_free_mem(&journal);
3605 }
3606
3607 /*
3608  * This function makes sure that the superblock fields regarding the
3609  * journal are consistent.
3610  */
3611 int e2fsck_check_ext3_journal(e2fsck_t ctx)
3612 {
3613         struct ext2_super_block *sb = ctx->fs->super;
3614         journal_t *journal;
3615         int recover = ctx->fs->super->s_feature_incompat &
3616                 EXT3_FEATURE_INCOMPAT_RECOVER;
3617         struct problem_context pctx;
3618         problem_t problem;
3619         int reset = 0, force_fsck = 0;
3620         int retval;
3621
3622         /* If we don't have any journal features, don't do anything more */
3623         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3624             !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
3625             uuid_is_null(sb->s_journal_uuid))
3626                 return 0;
3627
3628         clear_problem_context(&pctx);
3629         pctx.num = sb->s_journal_inum;
3630
3631         retval = e2fsck_get_journal(ctx, &journal);
3632         if (retval) {
3633                 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
3634                     (retval == EXT2_ET_BAD_BLOCK_NUM) ||
3635                     (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
3636                     (retval == EXT2_ET_NO_JOURNAL))
3637                         return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3638                 return retval;
3639         }
3640
3641         retval = e2fsck_journal_load(journal);
3642         if (retval) {
3643                 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
3644                     ((retval == EXT2_ET_UNSUPP_FEATURE) &&
3645                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
3646                                   &pctx))) ||
3647                     ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
3648                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
3649                                   &pctx))) ||
3650                     ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
3651                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
3652                         retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
3653                                                                   &pctx);
3654                 e2fsck_journal_release(ctx, journal, 0, 1);
3655                 return retval;
3656         }
3657
3658         /*
3659          * We want to make the flags consistent here.  We will not leave with
3660          * needs_recovery set but has_journal clear.  We can't get in a loop
3661          * with -y, -n, or -p, only if a user isn't making up their mind.
3662          */
3663 no_has_journal:
3664         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
3665                 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
3666                 pctx.str = "inode";
3667                 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
3668                         if (recover &&
3669                             !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
3670                                 goto no_has_journal;
3671                         /*
3672                          * Need a full fsck if we are releasing a
3673                          * journal stored on a reserved inode.
3674                          */
3675                         force_fsck = recover ||
3676                                 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
3677                         /* Clear all of the journal fields */
3678                         sb->s_journal_inum = 0;
3679                         sb->s_journal_dev = 0;
3680                         memset(sb->s_journal_uuid, 0,
3681                                sizeof(sb->s_journal_uuid));
3682                         e2fsck_clear_recover(ctx, force_fsck);
3683                 } else if (!(ctx->options & E2F_OPT_READONLY)) {
3684                         sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3685                         ext2fs_mark_super_dirty(ctx->fs);
3686                 }
3687         }
3688
3689         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
3690             !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
3691             journal->j_superblock->s_start != 0) {
3692                 /* Print status information */
3693                 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
3694                 if (ctx->superblock)
3695                         problem = PR_0_JOURNAL_RUN_DEFAULT;
3696                 else
3697                         problem = PR_0_JOURNAL_RUN;
3698                 if (fix_problem(ctx, problem, &pctx)) {
3699                         ctx->options |= E2F_OPT_FORCE;
3700                         sb->s_feature_incompat |=
3701                                 EXT3_FEATURE_INCOMPAT_RECOVER;
3702                         ext2fs_mark_super_dirty(ctx->fs);
3703                 } else if (fix_problem(ctx,
3704                                        PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
3705                         reset = 1;
3706                         sb->s_state &= ~EXT2_VALID_FS;
3707                         ext2fs_mark_super_dirty(ctx->fs);
3708                 }
3709                 /*
3710                  * If the user answers no to the above question, we
3711                  * ignore the fact that journal apparently has data;
3712                  * accidentally replaying over valid data would be far
3713                  * worse than skipping a questionable recovery.
3714                  *
3715                  * XXX should we abort with a fatal error here?  What
3716                  * will the ext3 kernel code do if a filesystem with
3717                  * !NEEDS_RECOVERY but with a non-zero
3718                  * journal->j_superblock->s_start is mounted?
3719                  */
3720         }
3721
3722         e2fsck_journal_release(ctx, journal, reset, 0);
3723         return retval;
3724 }
3725
3726 static errcode_t recover_ext3_journal(e2fsck_t ctx)
3727 {
3728         journal_t *journal;
3729         int retval;
3730
3731         journal_init_revoke_caches();
3732         retval = e2fsck_get_journal(ctx, &journal);
3733         if (retval)
3734                 return retval;
3735
3736         retval = e2fsck_journal_load(journal);
3737         if (retval)
3738                 goto errout;
3739
3740         retval = journal_init_revoke(journal, 1024);
3741         if (retval)
3742                 goto errout;
3743
3744         retval = -journal_recover(journal);
3745         if (retval)
3746                 goto errout;
3747
3748         if (journal->j_superblock->s_errno) {
3749                 ctx->fs->super->s_state |= EXT2_ERROR_FS;
3750                 ext2fs_mark_super_dirty(ctx->fs);
3751                 journal->j_superblock->s_errno = 0;
3752                 mark_buffer_dirty(journal->j_sb_buffer);
3753         }
3754
3755 errout:
3756         journal_destroy_revoke(journal);
3757         journal_destroy_revoke_caches();
3758         e2fsck_journal_release(ctx, journal, 1, 0);
3759         return retval;
3760 }
3761
3762 int e2fsck_run_ext3_journal(e2fsck_t ctx)
3763 {
3764         io_manager io_ptr = ctx->fs->io->manager;
3765         int blocksize = ctx->fs->blocksize;
3766         errcode_t       retval, recover_retval;
3767
3768         printf(_("%s: recovering journal\n"), ctx->device_name);
3769         if (ctx->options & E2F_OPT_READONLY) {
3770                 printf(_("%s: won't do journal recovery while read-only\n"),
3771                        ctx->device_name);
3772                 return EXT2_ET_FILE_RO;
3773         }
3774
3775         if (ctx->fs->flags & EXT2_FLAG_DIRTY)
3776                 ext2fs_flush(ctx->fs);  /* Force out any modifications */
3777
3778         recover_retval = recover_ext3_journal(ctx);
3779
3780         /*
3781          * Reload the filesystem context to get up-to-date data from disk
3782          * because journal recovery will change the filesystem under us.
3783          */
3784         ext2fs_close(ctx->fs);
3785         retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
3786                              ctx->superblock, blocksize, io_ptr,
3787                              &ctx->fs);
3788
3789         if (retval) {
3790                 com_err(ctx->program_name, retval,
3791                         _("while trying to re-open %s"),
3792                         ctx->device_name);
3793                 fatal_error(ctx, 0);
3794         }
3795         ctx->fs->priv_data = ctx;
3796
3797         /* Set the superblock flags */
3798         e2fsck_clear_recover(ctx, recover_retval);
3799         return recover_retval;
3800 }
3801
3802 /*
3803  * This function will move the journal inode from a visible file in
3804  * the filesystem directory hierarchy to the reserved inode if necessary.
3805  */
3806 static const char * const journal_names[] = {
3807         ".journal", "journal", ".journal.dat", "journal.dat", 0 };
3808
3809 void e2fsck_move_ext3_journal(e2fsck_t ctx)
3810 {
3811         struct ext2_super_block *sb = ctx->fs->super;
3812         struct problem_context  pctx;
3813         struct ext2_inode       inode;
3814         ext2_filsys             fs = ctx->fs;
3815         ext2_ino_t              ino;
3816         errcode_t               retval;
3817         const char * const *    cpp;
3818         int                     group, mount_flags;
3819
3820         clear_problem_context(&pctx);
3821
3822         /*
3823          * If the filesystem is opened read-only, or there is no
3824          * journal, then do nothing.
3825          */
3826         if ((ctx->options & E2F_OPT_READONLY) ||
3827             (sb->s_journal_inum == 0) ||
3828             !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
3829                 return;
3830
3831         /*
3832          * Read in the journal inode
3833          */
3834         if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
3835                 return;
3836
3837         /*
3838          * If it's necessary to backup the journal inode, do so.
3839          */
3840         if ((sb->s_jnl_backup_type == 0) ||
3841             ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
3842              memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
3843                 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
3844                         memcpy(sb->s_jnl_blocks, inode.i_block,
3845                                EXT2_N_BLOCKS*4);
3846                         sb->s_jnl_blocks[16] = inode.i_size;
3847                         sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
3848                         ext2fs_mark_super_dirty(fs);
3849                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3850                 }
3851         }
3852
3853         /*
3854          * If the journal is already the hidden inode, then do nothing
3855          */
3856         if (sb->s_journal_inum == EXT2_JOURNAL_INO)
3857                 return;
3858
3859         /*
3860          * The journal inode had better have only one link and not be readable.
3861          */
3862         if (inode.i_links_count != 1)
3863                 return;
3864
3865         /*
3866          * If the filesystem is mounted, or we can't tell whether
3867          * or not it's mounted, do nothing.
3868          */
3869         retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
3870         if (retval || (mount_flags & EXT2_MF_MOUNTED))
3871                 return;
3872
3873         /*
3874          * If we can't find the name of the journal inode, then do
3875          * nothing.
3876          */
3877         for (cpp = journal_names; *cpp; cpp++) {
3878                 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
3879                                        strlen(*cpp), 0, &ino);
3880                 if ((retval == 0) && (ino == sb->s_journal_inum))
3881                         break;
3882         }
3883         if (*cpp == 0)
3884                 return;
3885
3886         /* We need the inode bitmap to be loaded */
3887         retval = ext2fs_read_bitmaps(fs);
3888         if (retval)
3889                 return;
3890
3891         pctx.str = *cpp;
3892         if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
3893                 return;
3894
3895         /*
3896          * OK, we've done all the checks, let's actually move the
3897          * journal inode.  Errors at this point mean we need to force
3898          * an ext2 filesystem check.
3899          */
3900         if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
3901                 goto err_out;
3902         if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
3903                 goto err_out;
3904         sb->s_journal_inum = EXT2_JOURNAL_INO;
3905         ext2fs_mark_super_dirty(fs);
3906         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3907         inode.i_links_count = 0;
3908         inode.i_dtime = time(0);
3909         if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
3910                 goto err_out;
3911
3912         group = ext2fs_group_of_ino(fs, ino);
3913         ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
3914         ext2fs_mark_ib_dirty(fs);
3915         fs->group_desc[group].bg_free_inodes_count++;
3916         fs->super->s_free_inodes_count++;
3917         return;
3918
3919 err_out:
3920         pctx.errcode = retval;
3921         fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
3922         fs->super->s_state &= ~EXT2_VALID_FS;
3923         ext2fs_mark_super_dirty(fs);
3924         return;
3925 }
3926
3927 /*
3928  * message.c --- print e2fsck messages (with compression)
3929  *
3930  * Copyright 1996, 1997 by Theodore Ts'o
3931  *
3932  * %Begin-Header%
3933  * This file may be redistributed under the terms of the GNU Public
3934  * License.
3935  * %End-Header%
3936  *
3937  * print_e2fsck_message() prints a message to the user, using
3938  * compression techniques and expansions of abbreviations.
3939  *
3940  * The following % expansions are supported:
3941  *
3942  *      %b      <blk>                   block number
3943  *      %B      <blkcount>              integer
3944  *      %c      <blk2>                  block number
3945  *      %Di     <dirent>->ino           inode number
3946  *      %Dn     <dirent>->name          string
3947  *      %Dr     <dirent>->rec_len
3948  *      %Dl     <dirent>->name_len
3949  *      %Dt     <dirent>->filetype
3950  *      %d      <dir>                   inode number
3951  *      %g      <group>                 integer
3952  *      %i      <ino>                   inode number
3953  *      %Is     <inode> -> i_size
3954  *      %IS     <inode> -> i_extra_isize
3955  *      %Ib     <inode> -> i_blocks
3956  *      %Il     <inode> -> i_links_count
3957  *      %Im     <inode> -> i_mode
3958  *      %IM     <inode> -> i_mtime
3959  *      %IF     <inode> -> i_faddr
3960  *      %If     <inode> -> i_file_acl
3961  *      %Id     <inode> -> i_dir_acl
3962  *      %Iu     <inode> -> i_uid
3963  *      %Ig     <inode> -> i_gid
3964  *      %j      <ino2>                  inode number
3965  *      %m      <com_err error message>
3966  *      %N      <num>
3967  *      %p      ext2fs_get_pathname of directory <ino>
3968  *      %P      ext2fs_get_pathname of <dirent>->ino with <ino2> as
3969  *                      the containing directory.  (If dirent is NULL
3970  *                      then return the pathname of directory <ino2>)
3971  *      %q      ext2fs_get_pathname of directory <dir>
3972  *      %Q      ext2fs_get_pathname of directory <ino> with <dir> as
3973  *                      the containing directory.
3974  *      %s      <str>                   miscellaneous string
3975  *      %S      backup superblock
3976  *      %X      <num> hexadecimal format
3977  *
3978  * The following '@' expansions are supported:
3979  *
3980  *      @a      extended attribute
3981  *      @A      error allocating
3982  *      @b      block
3983  *      @B      bitmap
3984  *      @c      compress
3985  *      @C      conflicts with some other fs block
3986  *      @D      deleted
3987  *      @d      directory
3988  *      @e      entry
3989  *      @E      Entry '%Dn' in %p (%i)
3990  *      @f      filesystem
3991  *      @F      for @i %i (%Q) is
3992  *      @g      group
3993  *      @h      HTREE directory inode
3994  *      @i      inode
3995  *      @I      illegal
3996  *      @j      journal
3997  *      @l      lost+found
3998  *      @L      is a link
3999  *      @o      orphaned
4000  *      @p      problem in
4001  *      @r      root inode
4002  *      @s      should be
4003  *      @S      superblock
4004  *      @u      unattached
4005  *      @v      device
4006  *      @z      zero-length
4007  */
4008
4009
4010 /*
4011  * This structure defines the abbreviations used by the text strings
4012  * below.  The first character in the string is the index letter.  An
4013  * abbreviation of the form '@<i>' is expanded by looking up the index
4014  * letter <i> in the table below.
4015  */
4016 static const char *abbrevs[] = {
4017         N_("aextended attribute"),
4018         N_("Aerror allocating"),
4019         N_("bblock"),
4020         N_("Bbitmap"),
4021         N_("ccompress"),
4022         N_("Cconflicts with some other fs @b"),
4023         N_("iinode"),
4024         N_("Iillegal"),
4025         N_("jjournal"),
4026         N_("Ddeleted"),
4027         N_("ddirectory"),
4028         N_("eentry"),
4029         N_("E@e '%Dn' in %p (%i)"),
4030         N_("ffilesystem"),
4031         N_("Ffor @i %i (%Q) is"),
4032         N_("ggroup"),
4033         N_("hHTREE @d @i"),
4034         N_("llost+found"),
4035         N_("Lis a link"),
4036         N_("oorphaned"),
4037         N_("pproblem in"),
4038         N_("rroot @i"),
4039         N_("sshould be"),
4040         N_("Ssuper@b"),
4041         N_("uunattached"),
4042         N_("vdevice"),
4043         N_("zzero-length"),
4044         "@@",
4045         0
4046         };
4047
4048 /*
4049  * Give more user friendly names to the "special" inodes.
4050  */
4051 #define num_special_inodes      11
4052 static const char *special_inode_name[] =
4053 {
4054         N_("<The NULL inode>"),                 /* 0 */
4055         N_("<The bad blocks inode>"),           /* 1 */
4056         "/",                                    /* 2 */
4057         N_("<The ACL index inode>"),            /* 3 */
4058         N_("<The ACL data inode>"),             /* 4 */
4059         N_("<The boot loader inode>"),          /* 5 */
4060         N_("<The undelete directory inode>"),   /* 6 */
4061         N_("<The group descriptor inode>"),     /* 7 */
4062         N_("<The journal inode>"),              /* 8 */
4063         N_("<Reserved inode 9>"),               /* 9 */
4064         N_("<Reserved inode 10>"),              /* 10 */
4065 };
4066
4067 /*
4068  * This function does "safe" printing.  It will convert non-printable
4069  * ASCII characters using '^' and M- notation.
4070  */
4071 static void safe_print(const char *cp, int len)
4072 {
4073         unsigned char   ch;
4074
4075         if (len < 0)
4076                 len = strlen(cp);
4077
4078         while (len--) {
4079                 ch = *cp++;
4080                 if (ch > 128) {
4081                         fputs("M-", stdout);
4082                         ch -= 128;
4083                 }
4084                 if ((ch < 32) || (ch == 0x7f)) {
4085                         fputc('^', stdout);
4086                         ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
4087                 }
4088                 fputc(ch, stdout);
4089         }
4090 }
4091
4092
4093 /*
4094  * This function prints a pathname, using the ext2fs_get_pathname
4095  * function
4096  */
4097 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
4098 {
4099         errcode_t       retval;
4100         char            *path;
4101
4102         if (!dir && (ino < num_special_inodes)) {
4103                 fputs(_(special_inode_name[ino]), stdout);
4104                 return;
4105         }
4106
4107         retval = ext2fs_get_pathname(fs, dir, ino, &path);
4108         if (retval)
4109                 fputs("???", stdout);
4110         else {
4111                 safe_print(path, -1);
4112                 ext2fs_free_mem(&path);
4113         }
4114 }
4115
4116 /*
4117  * This function handles the '@' expansion.  We allow recursive
4118  * expansion; an @ expression can contain further '@' and '%'
4119  * expressions.
4120  */
4121 static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch,
4122                                           struct problem_context *pctx,
4123                                           int *first)
4124 {
4125         const char **cpp, *str;
4126
4127         /* Search for the abbreviation */
4128         for (cpp = abbrevs; *cpp; cpp++) {
4129                 if (ch == *cpp[0])
4130                         break;
4131         }
4132         if (*cpp) {
4133                 str = _(*cpp) + 1;
4134                 if (*first && islower(*str)) {
4135                         *first = 0;
4136                         fputc(toupper(*str++), stdout);
4137                 }
4138                 print_e2fsck_message(ctx, str, pctx, *first);
4139         } else
4140                 printf("@%c", ch);
4141 }
4142
4143 /*
4144  * This function expands '%IX' expressions
4145  */
4146 static _INLINE_ void expand_inode_expression(char ch,
4147                                              struct problem_context *ctx)
4148 {
4149         struct ext2_inode       *inode;
4150         struct ext2_inode_large *large_inode;
4151         char *                  time_str;
4152         time_t                  t;
4153         int                     do_gmt = -1;
4154
4155         if (!ctx || !ctx->inode)
4156                 goto no_inode;
4157
4158         inode = ctx->inode;
4159         large_inode = (struct ext2_inode_large *) inode;
4160
4161         switch (ch) {
4162         case 's':
4163                 if (LINUX_S_ISDIR(inode->i_mode))
4164                         printf("%u", inode->i_size);
4165                 else {
4166 #ifdef EXT2_NO_64_TYPE
4167                         if (inode->i_size_high)
4168                                 printf("0x%x%08x", inode->i_size_high,
4169                                        inode->i_size);
4170                         else
4171                                 printf("%u", inode->i_size);
4172 #else
4173                         printf("%llu", (inode->i_size |
4174                                         ((__u64) inode->i_size_high << 32)));
4175 #endif
4176                 }
4177                 break;
4178         case 'S':
4179                 printf("%u", large_inode->i_extra_isize);
4180                 break;
4181         case 'b':
4182                 printf("%u", inode->i_blocks);
4183                 break;
4184         case 'l':
4185                 printf("%d", inode->i_links_count);
4186                 break;
4187         case 'm':
4188                 printf("0%o", inode->i_mode);
4189                 break;
4190         case 'M':
4191                 /* The diet libc doesn't respect the TZ environemnt variable */
4192                 if (do_gmt == -1) {
4193                         time_str = getenv("TZ");
4194                         if (!time_str)
4195                                 time_str = "";
4196                         do_gmt = !strcmp(time_str, "GMT");
4197                 }
4198                 t = inode->i_mtime;
4199                 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
4200                 printf("%.24s", time_str);
4201                 break;
4202         case 'F':
4203                 printf("%u", inode->i_faddr);
4204                 break;
4205         case 'f':
4206                 printf("%u", inode->i_file_acl);
4207                 break;
4208         case 'd':
4209                 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
4210                               inode->i_dir_acl : 0));
4211                 break;
4212         case 'u':
4213                 printf("%d", (inode->i_uid |
4214                               (inode->osd2.linux2.l_i_uid_high << 16)));
4215                 break;
4216         case 'g':
4217                 printf("%d", (inode->i_gid |
4218                               (inode->osd2.linux2.l_i_gid_high << 16)));
4219                 break;
4220         default:
4221         no_inode:
4222                 printf("%%I%c", ch);
4223                 break;
4224         }
4225 }
4226
4227 /*
4228  * This function expands '%dX' expressions
4229  */
4230 static _INLINE_ void expand_dirent_expression(char ch,
4231                                               struct problem_context *ctx)
4232 {
4233         struct ext2_dir_entry   *dirent;
4234         int     len;
4235
4236         if (!ctx || !ctx->dirent)
4237                 goto no_dirent;
4238
4239         dirent = ctx->dirent;
4240
4241         switch (ch) {
4242         case 'i':
4243                 printf("%u", dirent->inode);
4244                 break;
4245         case 'n':
4246                 len = dirent->name_len & 0xFF;
4247                 if (len > EXT2_NAME_LEN)
4248                         len = EXT2_NAME_LEN;
4249                 if (len > dirent->rec_len)
4250                         len = dirent->rec_len;
4251                 safe_print(dirent->name, len);
4252                 break;
4253         case 'r':
4254                 printf("%u", dirent->rec_len);
4255                 break;
4256         case 'l':
4257                 printf("%u", dirent->name_len & 0xFF);
4258                 break;
4259         case 't':
4260                 printf("%u", dirent->name_len >> 8);
4261                 break;
4262         default:
4263         no_dirent:
4264                 printf("%%D%c", ch);
4265                 break;
4266         }
4267 }
4268
4269 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
4270                                                struct problem_context *ctx)
4271 {
4272         if (!ctx)
4273                 goto no_context;
4274
4275         switch (ch) {
4276         case '%':
4277                 fputc('%', stdout);
4278                 break;
4279         case 'b':
4280                 printf("%u", ctx->blk);
4281                 break;
4282         case 'B':
4283 #ifdef EXT2_NO_64_TYPE
4284                 printf("%d", ctx->blkcount);
4285 #else
4286                 printf("%lld", ctx->blkcount);
4287 #endif
4288                 break;
4289         case 'c':
4290                 printf("%u", ctx->blk2);
4291                 break;
4292         case 'd':
4293                 printf("%u", ctx->dir);
4294                 break;
4295         case 'g':
4296                 printf("%d", ctx->group);
4297                 break;
4298         case 'i':
4299                 printf("%u", ctx->ino);
4300                 break;
4301         case 'j':
4302                 printf("%u", ctx->ino2);
4303                 break;
4304         case 'm':
4305                 printf("%s", error_message(ctx->errcode));
4306                 break;
4307         case 'N':
4308 #ifdef EXT2_NO_64_TYPE
4309                 printf("%u", ctx->num);
4310 #else
4311                 printf("%llu", ctx->num);
4312 #endif
4313                 break;
4314         case 'p':
4315                 print_pathname(fs, ctx->ino, 0);
4316                 break;
4317         case 'P':
4318                 print_pathname(fs, ctx->ino2,
4319                                ctx->dirent ? ctx->dirent->inode : 0);
4320                 break;
4321         case 'q':
4322                 print_pathname(fs, ctx->dir, 0);
4323                 break;
4324         case 'Q':
4325                 print_pathname(fs, ctx->dir, ctx->ino);
4326                 break;
4327         case 'S':
4328                 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
4329                 break;
4330         case 's':
4331                 printf("%s", ctx->str ? ctx->str : "NULL");
4332                 break;
4333         case 'X':
4334 #ifdef EXT2_NO_64_TYPE
4335                 printf("0x%x", ctx->num);
4336 #else
4337                 printf("0x%llx", ctx->num);
4338 #endif
4339                 break;
4340         default:
4341         no_context:
4342                 printf("%%%c", ch);
4343                 break;
4344         }
4345 }
4346
4347 void print_e2fsck_message(e2fsck_t ctx, const char *msg,
4348                           struct problem_context *pctx, int first)
4349 {
4350         ext2_filsys fs = ctx->fs;
4351         const char *    cp;
4352         int             i;
4353
4354         e2fsck_clear_progbar(ctx);
4355         for (cp = msg; *cp; cp++) {
4356                 if (cp[0] == '@') {
4357                         cp++;
4358                         expand_at_expression(ctx, *cp, pctx, &first);
4359                 } else if (cp[0] == '%' && cp[1] == 'I') {
4360                         cp += 2;
4361                         expand_inode_expression(*cp, pctx);
4362                 } else if (cp[0] == '%' && cp[1] == 'D') {
4363                         cp += 2;
4364                         expand_dirent_expression(*cp, pctx);
4365                 } else if ((cp[0] == '%')) {
4366                         cp++;
4367                         expand_percent_expression(fs, *cp, pctx);
4368                 } else {
4369                         for (i=0; cp[i]; i++)
4370                                 if ((cp[i] == '@') || cp[i] == '%')
4371                                         break;
4372                         printf("%.*s", i, cp);
4373                         cp += i-1;
4374                 }
4375                 first = 0;
4376         }
4377 }
4378 /*
4379  * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
4380  *
4381  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
4382  *
4383  * %Begin-Header%
4384  * This file may be redistributed under the terms of the GNU Public
4385  * License.
4386  * %End-Header%
4387  *
4388  * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
4389  * and applies the following tests to each inode:
4390  *
4391  *      - The mode field of the inode must be legal.
4392  *      - The size and block count fields of the inode are correct.
4393  *      - A data block must not be used by another inode
4394  *
4395  * Pass 1 also gathers the collects the following information:
4396  *
4397  *      - A bitmap of which inodes are in use.          (inode_used_map)
4398  *      - A bitmap of which inodes are directories.     (inode_dir_map)
4399  *      - A bitmap of which inodes are regular files.   (inode_reg_map)
4400  *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
4401  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
4402  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
4403  *      - A bitmap of which blocks are in use.          (block_found_map)
4404  *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
4405  *      - The data blocks of the directory inodes.      (dir_map)
4406  *
4407  * Pass 1 is designed to stash away enough information so that the
4408  * other passes should not need to read in the inode information
4409  * during the normal course of a filesystem check.  (Althogh if an
4410  * inconsistency is detected, other passes may need to read in an
4411  * inode to fix it.)
4412  *
4413  * Note that pass 1B will be invoked if there are any duplicate blocks
4414  * found.
4415  */
4416
4417
4418 static int process_block(ext2_filsys fs, blk_t  *blocknr,
4419                          e2_blkcnt_t blockcnt, blk_t ref_blk,
4420                          int ref_offset, void *priv_data);
4421 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
4422                              e2_blkcnt_t blockcnt, blk_t ref_blk,
4423                              int ref_offset, void *priv_data);
4424 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4425                          char *block_buf);
4426 static void mark_table_blocks(e2fsck_t ctx);
4427 static void alloc_bb_map(e2fsck_t ctx);
4428 static void alloc_imagic_map(e2fsck_t ctx);
4429 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
4430 static void handle_fs_bad_blocks(e2fsck_t ctx);
4431 static void process_inodes(e2fsck_t ctx, char *block_buf);
4432 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
4433 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
4434                                   dgrp_t group, void * priv_data);
4435 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4436                                     char *block_buf, int adjust_sign);
4437 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
4438
4439 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
4440                                struct ext2_inode * inode, int bufsize,
4441                                const char *proc);
4442
4443 struct process_block_struct_1 {
4444         ext2_ino_t      ino;
4445         unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
4446                                 fragmented:1, compressed:1, bbcheck:1;
4447         blk_t           num_blocks;
4448         blk_t           max_blocks;
4449         e2_blkcnt_t     last_block;
4450         int             num_illegal_blocks;
4451         blk_t           previous_block;
4452         struct ext2_inode *inode;
4453         struct problem_context *pctx;
4454         ext2fs_block_bitmap fs_meta_blocks;
4455         e2fsck_t        ctx;
4456 };
4457
4458 struct process_inode_block {
4459         ext2_ino_t ino;
4460         struct ext2_inode inode;
4461 };
4462
4463 struct scan_callback_struct {
4464         e2fsck_t        ctx;
4465         char            *block_buf;
4466 };
4467
4468 /*
4469  * For the inodes to process list.
4470  */
4471 static struct process_inode_block *inodes_to_process;
4472 static int process_inode_count;
4473
4474 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
4475                             EXT2_MIN_BLOCK_LOG_SIZE + 1];
4476
4477 /*
4478  * Free all memory allocated by pass1 in preparation for restarting
4479  * things.
4480  */
4481 static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
4482 {
4483         ext2fs_free_mem(&inodes_to_process);
4484         inodes_to_process = 0;
4485 }
4486
4487 /*
4488  * Check to make sure a device inode is real.  Returns 1 if the device
4489  * checks out, 0 if not.
4490  *
4491  * Note: this routine is now also used to check FIFO's and Sockets,
4492  * since they have the same requirement; the i_block fields should be
4493  * zero.
4494  */
4495 int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
4496 {
4497         int     i;
4498
4499         /*
4500          * If i_blocks is non-zero, or the index flag is set, then
4501          * this is a bogus device/fifo/socket
4502          */
4503         if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
4504             (inode->i_flags & EXT2_INDEX_FL))
4505                 return 0;
4506
4507         /*
4508          * We should be able to do the test below all the time, but
4509          * because the kernel doesn't forcibly clear the device
4510          * inode's additional i_block fields, there are some rare
4511          * occasions when a legitimate device inode will have non-zero
4512          * additional i_block fields.  So for now, we only complain
4513          * when the immutable flag is set, which should never happen
4514          * for devices.  (And that's when the problem is caused, since
4515          * you can't set or clear immutable flags for devices.)  Once
4516          * the kernel has been fixed we can change this...
4517          */
4518         if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
4519                 for (i=4; i < EXT2_N_BLOCKS; i++)
4520                         if (inode->i_block[i])
4521                                 return 0;
4522         }
4523         return 1;
4524 }
4525
4526 /*
4527  * Check to make sure a symlink inode is real.  Returns 1 if the symlink
4528  * checks out, 0 if not.
4529  */
4530 int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode,
4531                                char *buf)
4532 {
4533         unsigned int len;
4534         int i;
4535         blk_t   blocks;
4536
4537         if ((inode->i_size_high || inode->i_size == 0) ||
4538             (inode->i_flags & EXT2_INDEX_FL))
4539                 return 0;
4540
4541         blocks = ext2fs_inode_data_blocks(fs, inode);
4542         if (blocks) {
4543                 if ((inode->i_size >= fs->blocksize) ||
4544                     (blocks != fs->blocksize >> 9) ||
4545                     (inode->i_block[0] < fs->super->s_first_data_block) ||
4546                     (inode->i_block[0] >= fs->super->s_blocks_count))
4547                         return 0;
4548
4549                 for (i = 1; i < EXT2_N_BLOCKS; i++)
4550                         if (inode->i_block[i])
4551                                 return 0;
4552
4553                 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
4554                         return 0;
4555
4556                 len = strnlen(buf, fs->blocksize);
4557                 if (len == fs->blocksize)
4558                         return 0;
4559         } else {
4560                 if (inode->i_size >= sizeof(inode->i_block))
4561                         return 0;
4562
4563                 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
4564                 if (len == sizeof(inode->i_block))
4565                         return 0;
4566         }
4567         if (len != inode->i_size)
4568                 return 0;
4569         return 1;
4570 }
4571
4572 /*
4573  * If the immutable (or append-only) flag is set on the inode, offer
4574  * to clear it.
4575  */
4576 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
4577 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
4578 {
4579         if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
4580                 return;
4581
4582         if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
4583                 return;
4584
4585         pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
4586         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4587 }
4588
4589 /*
4590  * If device, fifo or socket, check size is zero -- if not offer to
4591  * clear it
4592  */
4593 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
4594 {
4595         struct ext2_inode *inode = pctx->inode;
4596
4597         if ((inode->i_size == 0) && (inode->i_size_high == 0))
4598                 return;
4599
4600         if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
4601                 return;
4602
4603         inode->i_size = 0;
4604         inode->i_size_high = 0;
4605         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4606 }
4607
4608 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
4609 {
4610         struct ext2_super_block *sb = ctx->fs->super;
4611         struct ext2_inode_large *inode;
4612         struct ext2_ext_attr_entry *entry;
4613         char *start, *end;
4614         int storage_size, remain, offs;
4615         int problem = 0;
4616
4617         inode = (struct ext2_inode_large *) pctx->inode;
4618         storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
4619                 inode->i_extra_isize;
4620         start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4621                 inode->i_extra_isize + sizeof(__u32);
4622         end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
4623         entry = (struct ext2_ext_attr_entry *) start;
4624
4625         /* scan all entry's headers first */
4626
4627         /* take finish entry 0UL into account */
4628         remain = storage_size - sizeof(__u32);
4629         offs = end - start;
4630
4631         while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
4632
4633                 /* header eats this space */
4634                 remain -= sizeof(struct ext2_ext_attr_entry);
4635
4636                 /* is attribute name valid? */
4637                 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
4638                         pctx->num = entry->e_name_len;
4639                         problem = PR_1_ATTR_NAME_LEN;
4640                         goto fix;
4641                 }
4642
4643                 /* attribute len eats this space */
4644                 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
4645
4646                 /* check value size */
4647                 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
4648                         pctx->num = entry->e_value_size;
4649                         problem = PR_1_ATTR_VALUE_SIZE;
4650                         goto fix;
4651                 }
4652
4653                 /* check value placement */
4654                 if (entry->e_value_offs +
4655                     EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
4656                         printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
4657                         pctx->num = entry->e_value_offs;
4658                         problem = PR_1_ATTR_VALUE_OFFSET;
4659                         goto fix;
4660                 }
4661
4662                 /* e_value_block must be 0 in inode's ea */
4663                 if (entry->e_value_block != 0) {
4664                         pctx->num = entry->e_value_block;
4665                         problem = PR_1_ATTR_VALUE_BLOCK;
4666                         goto fix;
4667                 }
4668
4669                 /* e_hash must be 0 in inode's ea */
4670                 if (entry->e_hash != 0) {
4671                         pctx->num = entry->e_hash;
4672                         problem = PR_1_ATTR_HASH;
4673                         goto fix;
4674                 }
4675
4676                 remain -= entry->e_value_size;
4677                 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
4678
4679                 entry = EXT2_EXT_ATTR_NEXT(entry);
4680         }
4681 fix:
4682         /*
4683          * it seems like a corruption. it's very unlikely we could repair
4684          * EA(s) in automatic fashion -bzzz
4685          */
4686 #if 0
4687         problem = PR_1_ATTR_HASH;
4688 #endif
4689         if (problem == 0 || !fix_problem(ctx, problem, pctx))
4690                 return;
4691
4692         /* simple remove all possible EA(s) */
4693         *((__u32 *)start) = 0UL;
4694         e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
4695                                 EXT2_INODE_SIZE(sb), "pass1");
4696 }
4697
4698 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
4699 {
4700         struct ext2_super_block *sb = ctx->fs->super;
4701         struct ext2_inode_large *inode;
4702         __u32 *eamagic;
4703         int min, max;
4704
4705         inode = (struct ext2_inode_large *) pctx->inode;
4706         if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
4707                 /* this isn't large inode. so, nothing to check */
4708                 return;
4709         }
4710
4711 #if 0
4712         printf("inode #%u, i_extra_size %d\n", pctx->ino,
4713                         inode->i_extra_isize);
4714 #endif
4715         /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
4716         min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
4717         max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
4718         /*
4719          * For now we will allow i_extra_isize to be 0, but really
4720          * implementations should never allow i_extra_isize to be 0
4721          */
4722         if (inode->i_extra_isize &&
4723             (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
4724                 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
4725                         return;
4726                 inode->i_extra_isize = min;
4727                 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
4728                                         EXT2_INODE_SIZE(sb), "pass1");
4729                 return;
4730         }
4731
4732         eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4733                         inode->i_extra_isize);
4734         if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
4735                 /* it seems inode has an extended attribute(s) in body */
4736                 check_ea_in_inode(ctx, pctx);
4737         }
4738 }
4739
4740 void e2fsck_pass1(e2fsck_t ctx)
4741 {
4742         int     i;
4743         __u64   max_sizes;
4744         ext2_filsys fs = ctx->fs;
4745         ext2_ino_t      ino;
4746         struct ext2_inode *inode;
4747         ext2_inode_scan scan;
4748         char            *block_buf;
4749 #ifdef RESOURCE_TRACK
4750         struct resource_track   rtrack;
4751 #endif
4752         unsigned char   frag, fsize;
4753         struct          problem_context pctx;
4754         struct          scan_callback_struct scan_struct;
4755         struct ext2_super_block *sb = ctx->fs->super;
4756         int             imagic_fs;
4757         int             busted_fs_time = 0;
4758         int             inode_size;
4759
4760 #ifdef RESOURCE_TRACK
4761         init_resource_track(&rtrack);
4762 #endif
4763         clear_problem_context(&pctx);
4764
4765         if (!(ctx->options & E2F_OPT_PREEN))
4766                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
4767
4768         if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4769             !(ctx->options & E2F_OPT_NO)) {
4770                 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
4771                         ctx->dirs_to_hash = 0;
4772         }
4773
4774 #ifdef MTRACE
4775         mtrace_print("Pass 1");
4776 #endif
4777
4778 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
4779
4780         for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
4781                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
4782                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
4783                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
4784                 max_sizes = (max_sizes * (1UL << i)) - 1;
4785                 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
4786         }
4787 #undef EXT2_BPP
4788
4789         imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
4790
4791         /*
4792          * Allocate bitmaps structures
4793          */
4794         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
4795                                               &ctx->inode_used_map);
4796         if (pctx.errcode) {
4797                 pctx.num = 1;
4798                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4799                 ctx->flags |= E2F_FLAG_ABORT;
4800                 return;
4801         }
4802         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4803                                 _("directory inode map"), &ctx->inode_dir_map);
4804         if (pctx.errcode) {
4805                 pctx.num = 2;
4806                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4807                 ctx->flags |= E2F_FLAG_ABORT;
4808                 return;
4809         }
4810         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4811                         _("regular file inode map"), &ctx->inode_reg_map);
4812         if (pctx.errcode) {
4813                 pctx.num = 6;
4814                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4815                 ctx->flags |= E2F_FLAG_ABORT;
4816                 return;
4817         }
4818         pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
4819                                               &ctx->block_found_map);
4820         if (pctx.errcode) {
4821                 pctx.num = 1;
4822                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4823                 ctx->flags |= E2F_FLAG_ABORT;
4824                 return;
4825         }
4826         pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
4827                                              &ctx->inode_link_info);
4828         if (pctx.errcode) {
4829                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
4830                 ctx->flags |= E2F_FLAG_ABORT;
4831                 return;
4832         }
4833         inode_size = EXT2_INODE_SIZE(fs->super);
4834         inode = (struct ext2_inode *)
4835                 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
4836
4837         inodes_to_process = (struct process_inode_block *)
4838                 e2fsck_allocate_memory(ctx,
4839                                        (ctx->process_inode_size *
4840                                         sizeof(struct process_inode_block)),
4841                                        "array of inodes to process");
4842         process_inode_count = 0;
4843
4844         pctx.errcode = ext2fs_init_dblist(fs, 0);
4845         if (pctx.errcode) {
4846                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
4847                 ctx->flags |= E2F_FLAG_ABORT;
4848                 return;
4849         }
4850
4851         /*
4852          * If the last orphan field is set, clear it, since the pass1
4853          * processing will automatically find and clear the orphans.
4854          * In the future, we may want to try using the last_orphan
4855          * linked list ourselves, but for now, we clear it so that the
4856          * ext3 mount code won't get confused.
4857          */
4858         if (!(ctx->options & E2F_OPT_READONLY)) {
4859                 if (fs->super->s_last_orphan) {
4860                         fs->super->s_last_orphan = 0;
4861                         ext2fs_mark_super_dirty(fs);
4862                 }
4863         }
4864
4865         mark_table_blocks(ctx);
4866         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
4867                                                     "block interate buffer");
4868         e2fsck_use_inode_shortcuts(ctx, 1);
4869         ehandler_operation(_("doing inode scan"));
4870         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4871                                               &scan);
4872         if (pctx.errcode) {
4873                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4874                 ctx->flags |= E2F_FLAG_ABORT;
4875                 return;
4876         }
4877         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
4878         ctx->stashed_inode = inode;
4879         scan_struct.ctx = ctx;
4880         scan_struct.block_buf = block_buf;
4881         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
4882         if (ctx->progress)
4883                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
4884                         return;
4885         if (fs->super->s_wtime < fs->super->s_inodes_count)
4886                 busted_fs_time = 1;
4887
4888         while (1) {
4889                 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
4890                                                           inode, inode_size);
4891                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4892                         return;
4893                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
4894                         if (!ctx->inode_bb_map)
4895                                 alloc_bb_map(ctx);
4896                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
4897                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4898                         continue;
4899                 }
4900                 if (pctx.errcode) {
4901                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4902                         ctx->flags |= E2F_FLAG_ABORT;
4903                         return;
4904                 }
4905                 if (!ino)
4906                         break;
4907                 pctx.ino = ino;
4908                 pctx.inode = inode;
4909                 ctx->stashed_ino = ino;
4910                 if (inode->i_links_count) {
4911                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
4912                                            ino, inode->i_links_count);
4913                         if (pctx.errcode) {
4914                                 pctx.num = inode->i_links_count;
4915                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
4916                                 ctx->flags |= E2F_FLAG_ABORT;
4917                                 return;
4918                         }
4919                 }
4920                 if (ino == EXT2_BAD_INO) {
4921                         struct process_block_struct_1 pb;
4922
4923                         pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
4924                                                           &pb.fs_meta_blocks);
4925                         if (pctx.errcode) {
4926                                 pctx.num = 4;
4927                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4928                                 ctx->flags |= E2F_FLAG_ABORT;
4929                                 return;
4930                         }
4931                         pb.ino = EXT2_BAD_INO;
4932                         pb.num_blocks = pb.last_block = 0;
4933                         pb.num_illegal_blocks = 0;
4934                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
4935                         pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
4936                         pb.inode = inode;
4937                         pb.pctx = &pctx;
4938                         pb.ctx = ctx;
4939                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
4940                                      block_buf, process_bad_block, &pb);
4941                         ext2fs_free_block_bitmap(pb.fs_meta_blocks);
4942                         if (pctx.errcode) {
4943                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
4944                                 ctx->flags |= E2F_FLAG_ABORT;
4945                                 return;
4946                         }
4947                         if (pb.bbcheck)
4948                                 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
4949                                 ctx->flags |= E2F_FLAG_ABORT;
4950                                 return;
4951                         }
4952                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4953                         clear_problem_context(&pctx);
4954                         continue;
4955                 } else if (ino == EXT2_ROOT_INO) {
4956                         /*
4957                          * Make sure the root inode is a directory; if
4958                          * not, offer to clear it.  It will be
4959                          * regnerated in pass #3.
4960                          */
4961                         if (!LINUX_S_ISDIR(inode->i_mode)) {
4962                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
4963                                         inode->i_dtime = time(0);
4964                                         inode->i_links_count = 0;
4965                                         ext2fs_icount_store(ctx->inode_link_info,
4966                                                             ino, 0);
4967                                         e2fsck_write_inode(ctx, ino, inode,
4968                                                            "pass1");
4969                                 }
4970
4971                         }
4972                         /*
4973                          * If dtime is set, offer to clear it.  mke2fs
4974                          * version 0.2b created filesystems with the
4975                          * dtime field set for the root and lost+found
4976                          * directories.  We won't worry about
4977                          * /lost+found, since that can be regenerated
4978                          * easily.  But we will fix the root directory
4979                          * as a special case.
4980                          */
4981                         if (inode->i_dtime && inode->i_links_count) {
4982                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
4983                                         inode->i_dtime = 0;
4984                                         e2fsck_write_inode(ctx, ino, inode,
4985                                                            "pass1");
4986                                 }
4987                         }
4988                 } else if (ino == EXT2_JOURNAL_INO) {
4989                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4990                         if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
4991                                 if (!LINUX_S_ISREG(inode->i_mode) &&
4992                                     fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
4993                                                 &pctx)) {
4994                                         inode->i_mode = LINUX_S_IFREG;
4995                                         e2fsck_write_inode(ctx, ino, inode,
4996                                                            "pass1");
4997                                 }
4998                                 check_blocks(ctx, &pctx, block_buf);
4999                                 continue;
5000                         }
5001                         if ((inode->i_links_count || inode->i_blocks ||
5002                              inode->i_blocks || inode->i_block[0]) &&
5003                             fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
5004                                         &pctx)) {
5005                                 memset(inode, 0, inode_size);
5006                                 ext2fs_icount_store(ctx->inode_link_info,
5007                                                     ino, 0);
5008                                 e2fsck_write_inode_full(ctx, ino, inode,
5009                                                         inode_size, "pass1");
5010                         }
5011                 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
5012                         int     problem = 0;
5013
5014                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
5015                         if (ino == EXT2_BOOT_LOADER_INO) {
5016                                 if (LINUX_S_ISDIR(inode->i_mode))
5017                                         problem = PR_1_RESERVED_BAD_MODE;
5018                         } else if (ino == EXT2_RESIZE_INO) {
5019                                 if (inode->i_mode &&
5020                                     !LINUX_S_ISREG(inode->i_mode))
5021                                         problem = PR_1_RESERVED_BAD_MODE;
5022                         } else {
5023                                 if (inode->i_mode != 0)
5024                                         problem = PR_1_RESERVED_BAD_MODE;
5025                         }
5026                         if (problem) {
5027                                 if (fix_problem(ctx, problem, &pctx)) {
5028                                         inode->i_mode = 0;
5029                                         e2fsck_write_inode(ctx, ino, inode,
5030                                                            "pass1");
5031                                 }
5032                         }
5033                         check_blocks(ctx, &pctx, block_buf);
5034                         continue;
5035                 }
5036                 /*
5037                  * Check for inodes who might have been part of the
5038                  * orphaned list linked list.  They should have gotten
5039                  * dealt with by now, unless the list had somehow been
5040                  * corrupted.
5041                  *
5042                  * FIXME: In the future, inodes which are still in use
5043                  * (and which are therefore) pending truncation should
5044                  * be handled specially.  Right now we just clear the
5045                  * dtime field, and the normal e2fsck handling of
5046                  * inodes where i_size and the inode blocks are
5047                  * inconsistent is to fix i_size, instead of releasing
5048                  * the extra blocks.  This won't catch the inodes that
5049                  * was at the end of the orphan list, but it's better
5050                  * than nothing.  The right answer is that there
5051                  * shouldn't be any bugs in the orphan list handling.  :-)
5052                  */
5053                 if (inode->i_dtime && !busted_fs_time &&
5054                     inode->i_dtime < ctx->fs->super->s_inodes_count) {
5055                         if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
5056                                 inode->i_dtime = inode->i_links_count ?
5057                                         0 : time(0);
5058                                 e2fsck_write_inode(ctx, ino, inode,
5059                                                    "pass1");
5060                         }
5061                 }
5062
5063                 /*
5064                  * This code assumes that deleted inodes have
5065                  * i_links_count set to 0.
5066                  */
5067                 if (!inode->i_links_count) {
5068                         if (!inode->i_dtime && inode->i_mode) {
5069                                 if (fix_problem(ctx,
5070                                             PR_1_ZERO_DTIME, &pctx)) {
5071                                         inode->i_dtime = time(0);
5072                                         e2fsck_write_inode(ctx, ino, inode,
5073                                                            "pass1");
5074                                 }
5075                         }
5076                         continue;
5077                 }
5078                 /*
5079                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
5080                  * deleted files.  Oops.
5081                  *
5082                  * Since all new ext2 implementations get this right,
5083                  * we now assume that the case of non-zero
5084                  * i_links_count and non-zero dtime means that we
5085                  * should keep the file, not delete it.
5086                  *
5087                  */
5088                 if (inode->i_dtime) {
5089                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
5090                                 inode->i_dtime = 0;
5091                                 e2fsck_write_inode(ctx, ino, inode, "pass1");
5092                         }
5093                 }
5094
5095                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
5096                 switch (fs->super->s_creator_os) {
5097                     case EXT2_OS_LINUX:
5098                         frag = inode->osd2.linux2.l_i_frag;
5099                         fsize = inode->osd2.linux2.l_i_fsize;
5100                         break;
5101                     case EXT2_OS_HURD:
5102                         frag = inode->osd2.hurd2.h_i_frag;
5103                         fsize = inode->osd2.hurd2.h_i_fsize;
5104                         break;
5105                     case EXT2_OS_MASIX:
5106                         frag = inode->osd2.masix2.m_i_frag;
5107                         fsize = inode->osd2.masix2.m_i_fsize;
5108                         break;
5109                     default:
5110                         frag = fsize = 0;
5111                 }
5112
5113                 if (inode->i_faddr || frag || fsize ||
5114                     (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
5115                         mark_inode_bad(ctx, ino);
5116                 if (inode->i_flags & EXT2_IMAGIC_FL) {
5117                         if (imagic_fs) {
5118                                 if (!ctx->inode_imagic_map)
5119                                         alloc_imagic_map(ctx);
5120                                 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
5121                                                          ino);
5122                         } else {
5123                                 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
5124                                         inode->i_flags &= ~EXT2_IMAGIC_FL;
5125                                         e2fsck_write_inode(ctx, ino,
5126                                                            inode, "pass1");
5127                                 }
5128                         }
5129                 }
5130
5131                 check_inode_extra_space(ctx, &pctx);
5132
5133                 if (LINUX_S_ISDIR(inode->i_mode)) {
5134                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
5135                         e2fsck_add_dir_info(ctx, ino, 0);
5136                         ctx->fs_directory_count++;
5137                 } else if (LINUX_S_ISREG (inode->i_mode)) {
5138                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
5139                         ctx->fs_regular_count++;
5140                 } else if (LINUX_S_ISCHR (inode->i_mode) &&
5141                            e2fsck_pass1_check_device_inode(fs, inode)) {
5142                         check_immutable(ctx, &pctx);
5143                         check_size(ctx, &pctx);
5144                         ctx->fs_chardev_count++;
5145                 } else if (LINUX_S_ISBLK (inode->i_mode) &&
5146                            e2fsck_pass1_check_device_inode(fs, inode)) {
5147                         check_immutable(ctx, &pctx);
5148                         check_size(ctx, &pctx);
5149                         ctx->fs_blockdev_count++;
5150                 } else if (LINUX_S_ISLNK (inode->i_mode) &&
5151                            e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
5152                         check_immutable(ctx, &pctx);
5153                         ctx->fs_symlinks_count++;
5154                         if (ext2fs_inode_data_blocks(fs, inode) == 0) {
5155                                 ctx->fs_fast_symlinks_count++;
5156                                 check_blocks(ctx, &pctx, block_buf);
5157                                 continue;
5158                         }
5159                 }
5160                 else if (LINUX_S_ISFIFO (inode->i_mode) &&
5161                          e2fsck_pass1_check_device_inode(fs, inode)) {
5162                         check_immutable(ctx, &pctx);
5163                         check_size(ctx, &pctx);
5164                         ctx->fs_fifo_count++;
5165                 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
5166                            e2fsck_pass1_check_device_inode(fs, inode)) {
5167                         check_immutable(ctx, &pctx);
5168                         check_size(ctx, &pctx);
5169                         ctx->fs_sockets_count++;
5170                 } else
5171                         mark_inode_bad(ctx, ino);
5172                 if (inode->i_block[EXT2_IND_BLOCK])
5173                         ctx->fs_ind_count++;
5174                 if (inode->i_block[EXT2_DIND_BLOCK])
5175                         ctx->fs_dind_count++;
5176                 if (inode->i_block[EXT2_TIND_BLOCK])
5177                         ctx->fs_tind_count++;
5178                 if (inode->i_block[EXT2_IND_BLOCK] ||
5179                     inode->i_block[EXT2_DIND_BLOCK] ||
5180                     inode->i_block[EXT2_TIND_BLOCK] ||
5181                     inode->i_file_acl) {
5182                         inodes_to_process[process_inode_count].ino = ino;
5183                         inodes_to_process[process_inode_count].inode = *inode;
5184                         process_inode_count++;
5185                 } else
5186                         check_blocks(ctx, &pctx, block_buf);
5187
5188                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5189                         return;
5190
5191                 if (process_inode_count >= ctx->process_inode_size) {
5192                         process_inodes(ctx, block_buf);
5193
5194                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5195                                 return;
5196                 }
5197         }
5198         process_inodes(ctx, block_buf);
5199         ext2fs_close_inode_scan(scan);
5200         ehandler_operation(0);
5201
5202         /*
5203          * If any extended attribute blocks' reference counts need to
5204          * be adjusted, either up (ctx->refcount_extra), or down
5205          * (ctx->refcount), then fix them.
5206          */
5207         if (ctx->refcount) {
5208                 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
5209                 ea_refcount_free(ctx->refcount);
5210                 ctx->refcount = 0;
5211         }
5212         if (ctx->refcount_extra) {
5213                 adjust_extattr_refcount(ctx, ctx->refcount_extra,
5214                                         block_buf, +1);
5215                 ea_refcount_free(ctx->refcount_extra);
5216                 ctx->refcount_extra = 0;
5217         }
5218
5219         if (ctx->invalid_bitmaps)
5220                 handle_fs_bad_blocks(ctx);
5221
5222         /* We don't need the block_ea_map any more */
5223         if (ctx->block_ea_map) {
5224                 ext2fs_free_block_bitmap(ctx->block_ea_map);
5225                 ctx->block_ea_map = 0;
5226         }
5227
5228         if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
5229                 ext2fs_block_bitmap save_bmap;
5230
5231                 save_bmap = fs->block_map;
5232                 fs->block_map = ctx->block_found_map;
5233                 clear_problem_context(&pctx);
5234                 pctx.errcode = ext2fs_create_resize_inode(fs);
5235                 if (pctx.errcode) {
5236                         fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
5237                         /* Should never get here */
5238                         ctx->flags |= E2F_FLAG_ABORT;
5239                         return;
5240                 }
5241                 fs->block_map = save_bmap;
5242                 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
5243         }
5244
5245         if (ctx->flags & E2F_FLAG_RESTART) {
5246                 /*
5247                  * Only the master copy of the superblock and block
5248                  * group descriptors are going to be written during a
5249                  * restart, so set the superblock to be used to be the
5250                  * master superblock.
5251                  */
5252                 ctx->use_superblock = 0;
5253                 unwind_pass1(fs);
5254                 goto endit;
5255         }
5256
5257         if (ctx->block_dup_map) {
5258                 if (ctx->options & E2F_OPT_PREEN) {
5259                         clear_problem_context(&pctx);
5260                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
5261                 }
5262                 e2fsck_pass1_dupblocks(ctx, block_buf);
5263         }
5264         ext2fs_free_mem(&inodes_to_process);
5265 endit:
5266         e2fsck_use_inode_shortcuts(ctx, 0);
5267
5268         ext2fs_free_mem(&block_buf);
5269         ext2fs_free_mem(&inode);
5270
5271 #ifdef RESOURCE_TRACK
5272         if (ctx->options & E2F_OPT_TIME2) {
5273                 e2fsck_clear_progbar(ctx);
5274                 print_resource_track(_("Pass 1"), &rtrack);
5275         }
5276 #endif
5277 }
5278
5279 /*
5280  * When the inode_scan routines call this callback at the end of the
5281  * glock group, call process_inodes.
5282  */
5283 static errcode_t scan_callback(ext2_filsys fs,
5284                                ext2_inode_scan scan EXT2FS_ATTR((unused)),
5285                                dgrp_t group, void * priv_data)
5286 {
5287         struct scan_callback_struct *scan_struct;
5288         e2fsck_t ctx;
5289
5290         scan_struct = (struct scan_callback_struct *) priv_data;
5291         ctx = scan_struct->ctx;
5292
5293         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
5294
5295         if (ctx->progress)
5296                 if ((ctx->progress)(ctx, 1, group+1,
5297                                     ctx->fs->group_desc_count))
5298                         return EXT2_ET_CANCEL_REQUESTED;
5299
5300         return 0;
5301 }
5302
5303 /*
5304  * Process the inodes in the "inodes to process" list.
5305  */
5306 static void process_inodes(e2fsck_t ctx, char *block_buf)
5307 {
5308         int                     i;
5309         struct ext2_inode       *old_stashed_inode;
5310         ext2_ino_t              old_stashed_ino;
5311         const char              *old_operation;
5312         char                    buf[80];
5313         struct problem_context  pctx;
5314
5315 #if 0
5316         printf("begin process_inodes: ");
5317 #endif
5318         if (process_inode_count == 0)
5319                 return;
5320         old_operation = ehandler_operation(0);
5321         old_stashed_inode = ctx->stashed_inode;
5322         old_stashed_ino = ctx->stashed_ino;
5323         qsort(inodes_to_process, process_inode_count,
5324                       sizeof(struct process_inode_block), process_inode_cmp);
5325         clear_problem_context(&pctx);
5326         for (i=0; i < process_inode_count; i++) {
5327                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
5328                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
5329
5330 #if 0
5331                 printf("%u ", pctx.ino);
5332 #endif
5333                 sprintf(buf, _("reading indirect blocks of inode %u"),
5334                         pctx.ino);
5335                 ehandler_operation(buf);
5336                 check_blocks(ctx, &pctx, block_buf);
5337                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5338                         break;
5339         }
5340         ctx->stashed_inode = old_stashed_inode;
5341         ctx->stashed_ino = old_stashed_ino;
5342         process_inode_count = 0;
5343 #if 0
5344         printf("end process inodes\n");
5345 #endif
5346         ehandler_operation(old_operation);
5347 }
5348
5349 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
5350 {
5351         const struct process_inode_block *ib_a =
5352                 (const struct process_inode_block *) a;
5353         const struct process_inode_block *ib_b =
5354                 (const struct process_inode_block *) b;
5355         int     ret;
5356
5357         ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
5358                ib_b->inode.i_block[EXT2_IND_BLOCK]);
5359         if (ret == 0)
5360                 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
5361         return ret;
5362 }
5363
5364 /*
5365  * Mark an inode as being bad in some what
5366  */
5367 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
5368 {
5369         struct          problem_context pctx;
5370
5371         if (!ctx->inode_bad_map) {
5372                 clear_problem_context(&pctx);
5373
5374                 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5375                             _("bad inode map"), &ctx->inode_bad_map);
5376                 if (pctx.errcode) {
5377                         pctx.num = 3;
5378                         fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5379                         /* Should never get here */
5380                         ctx->flags |= E2F_FLAG_ABORT;
5381                         return;
5382                 }
5383         }
5384         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
5385 }
5386
5387
5388 /*
5389  * This procedure will allocate the inode "bb" (badblock) map table
5390  */
5391 static void alloc_bb_map(e2fsck_t ctx)
5392 {
5393         struct          problem_context pctx;
5394
5395         clear_problem_context(&pctx);
5396         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5397                                               _("inode in bad block map"),
5398                                               &ctx->inode_bb_map);
5399         if (pctx.errcode) {
5400                 pctx.num = 4;
5401                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5402                 /* Should never get here */
5403                 ctx->flags |= E2F_FLAG_ABORT;
5404                 return;
5405         }
5406 }
5407
5408 /*
5409  * This procedure will allocate the inode imagic table
5410  */
5411 static void alloc_imagic_map(e2fsck_t ctx)
5412 {
5413         struct          problem_context pctx;
5414
5415         clear_problem_context(&pctx);
5416         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5417                                               _("imagic inode map"),
5418                                               &ctx->inode_imagic_map);
5419         if (pctx.errcode) {
5420                 pctx.num = 5;
5421                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5422                 /* Should never get here */
5423                 ctx->flags |= E2F_FLAG_ABORT;
5424                 return;
5425         }
5426 }
5427
5428 /*
5429  * Marks a block as in use, setting the dup_map if it's been set
5430  * already.  Called by process_block and process_bad_block.
5431  *
5432  * WARNING: Assumes checks have already been done to make sure block
5433  * is valid.  This is true in both process_block and process_bad_block.
5434  */
5435 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
5436 {
5437         struct          problem_context pctx;
5438
5439         clear_problem_context(&pctx);
5440
5441         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
5442                 if (!ctx->block_dup_map) {
5443                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
5444                               _("multiply claimed block map"),
5445                               &ctx->block_dup_map);
5446                         if (pctx.errcode) {
5447                                 pctx.num = 3;
5448                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
5449                                             &pctx);
5450                                 /* Should never get here */
5451                                 ctx->flags |= E2F_FLAG_ABORT;
5452                                 return;
5453                         }
5454                 }
5455                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
5456         } else {
5457                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
5458         }
5459 }
5460
5461 /*
5462  * Adjust the extended attribute block's reference counts at the end
5463  * of pass 1, either by subtracting out references for EA blocks that
5464  * are still referenced in ctx->refcount, or by adding references for
5465  * EA blocks that had extra references as accounted for in
5466  * ctx->refcount_extra.
5467  */
5468 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
5469                                     char *block_buf, int adjust_sign)
5470 {
5471         struct ext2_ext_attr_header     *header;
5472         struct problem_context          pctx;
5473         ext2_filsys                     fs = ctx->fs;
5474         blk_t                           blk;
5475         __u32                           should_be;
5476         int                             count;
5477
5478         clear_problem_context(&pctx);
5479
5480         ea_refcount_intr_begin(refcount);
5481         while (1) {
5482                 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
5483                         break;
5484                 pctx.blk = blk;
5485                 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5486                 if (pctx.errcode) {
5487                         fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
5488                         return;
5489                 }
5490                 header = (struct ext2_ext_attr_header *) block_buf;
5491                 pctx.blkcount = header->h_refcount;
5492                 should_be = header->h_refcount + adjust_sign * count;
5493                 pctx.num = should_be;
5494                 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
5495                         header->h_refcount = should_be;
5496                         pctx.errcode = ext2fs_write_ext_attr(fs, blk,
5497                                                              block_buf);
5498                         if (pctx.errcode) {
5499                                 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
5500                                 continue;
5501                         }
5502                 }
5503         }
5504 }
5505
5506 /*
5507  * Handle processing the extended attribute blocks
5508  */
5509 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
5510                            char *block_buf)
5511 {
5512         ext2_filsys fs = ctx->fs;
5513         ext2_ino_t      ino = pctx->ino;
5514         struct ext2_inode *inode = pctx->inode;
5515         blk_t           blk;
5516         char *          end;
5517         struct ext2_ext_attr_header *header;
5518         struct ext2_ext_attr_entry *entry;
5519         int             count;
5520         region_t        region;
5521
5522         blk = inode->i_file_acl;
5523         if (blk == 0)
5524                 return 0;
5525
5526         /*
5527          * If the Extended attribute flag isn't set, then a non-zero
5528          * file acl means that the inode is corrupted.
5529          *
5530          * Or if the extended attribute block is an invalid block,
5531          * then the inode is also corrupted.
5532          */
5533         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
5534             (blk < fs->super->s_first_data_block) ||
5535             (blk >= fs->super->s_blocks_count)) {
5536                 mark_inode_bad(ctx, ino);
5537                 return 0;
5538         }
5539
5540         /* If ea bitmap hasn't been allocated, create it */
5541         if (!ctx->block_ea_map) {
5542                 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
5543                                                       _("ext attr block map"),
5544                                                       &ctx->block_ea_map);
5545                 if (pctx->errcode) {
5546                         pctx->num = 2;
5547                         fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
5548                         ctx->flags |= E2F_FLAG_ABORT;
5549                         return 0;
5550                 }
5551         }
5552
5553         /* Create the EA refcount structure if necessary */
5554         if (!ctx->refcount) {
5555                 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
5556                 if (pctx->errcode) {
5557                         pctx->num = 1;
5558                         fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5559                         ctx->flags |= E2F_FLAG_ABORT;
5560                         return 0;
5561                 }
5562         }
5563
5564 #if 0
5565         /* Debugging text */
5566         printf("Inode %u has EA block %u\n", ino, blk);
5567 #endif
5568
5569         /* Have we seen this EA block before? */
5570         if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
5571                 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
5572                         return 1;
5573                 /* Ooops, this EA was referenced more than it stated */
5574                 if (!ctx->refcount_extra) {
5575                         pctx->errcode = ea_refcount_create(0,
5576                                            &ctx->refcount_extra);
5577                         if (pctx->errcode) {
5578                                 pctx->num = 2;
5579                                 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5580                                 ctx->flags |= E2F_FLAG_ABORT;
5581                                 return 0;
5582                         }
5583                 }
5584                 ea_refcount_increment(ctx->refcount_extra, blk, 0);
5585                 return 1;
5586         }
5587
5588         /*
5589          * OK, we haven't seen this EA block yet.  So we need to
5590          * validate it
5591          */
5592         pctx->blk = blk;
5593         pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5594         if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
5595                 goto clear_extattr;
5596         header = (struct ext2_ext_attr_header *) block_buf;
5597         pctx->blk = inode->i_file_acl;
5598         if (((ctx->ext_attr_ver == 1) &&
5599              (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
5600             ((ctx->ext_attr_ver == 2) &&
5601              (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
5602                 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
5603                         goto clear_extattr;
5604         }
5605
5606         if (header->h_blocks != 1) {
5607                 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
5608                         goto clear_extattr;
5609         }
5610
5611         region = region_create(0, fs->blocksize);
5612         if (!region) {
5613                 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
5614                 ctx->flags |= E2F_FLAG_ABORT;
5615                 return 0;
5616         }
5617         if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
5618                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5619                         goto clear_extattr;
5620         }
5621
5622         entry = (struct ext2_ext_attr_entry *)(header+1);
5623         end = block_buf + fs->blocksize;
5624         while ((char *)entry < end && *(__u32 *)entry) {
5625                 if (region_allocate(region, (char *)entry - (char *)header,
5626                                    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
5627                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5628                                 goto clear_extattr;
5629                 }
5630                 if ((ctx->ext_attr_ver == 1 &&
5631                      (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
5632                     (ctx->ext_attr_ver == 2 &&
5633                      entry->e_name_index == 0)) {
5634                         if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
5635                                 goto clear_extattr;
5636                 }
5637                 if (entry->e_value_block != 0) {
5638                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
5639                                 goto clear_extattr;
5640                 }
5641                 if (entry->e_value_size &&
5642                     region_allocate(region, entry->e_value_offs,
5643                                     EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
5644                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5645                                 goto clear_extattr;
5646                 }
5647                 entry = EXT2_EXT_ATTR_NEXT(entry);
5648         }
5649         if (region_allocate(region, (char *)entry - (char *)header, 4)) {
5650                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5651                         goto clear_extattr;
5652         }
5653         region_free(region);
5654
5655         count = header->h_refcount - 1;
5656         if (count)
5657                 ea_refcount_store(ctx->refcount, blk, count);
5658         mark_block_used(ctx, blk);
5659         ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
5660
5661         return 1;
5662
5663 clear_extattr:
5664         inode->i_file_acl = 0;
5665         e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
5666         return 0;
5667 }
5668
5669 /* Returns 1 if bad htree, 0 if OK */
5670 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
5671                         ext2_ino_t ino EXT2FS_ATTR((unused)),
5672                         struct ext2_inode *inode,
5673                         char *block_buf)
5674 {
5675         struct ext2_dx_root_info        *root;
5676         ext2_filsys                     fs = ctx->fs;
5677         errcode_t                       retval;
5678         blk_t                           blk;
5679
5680         if ((!LINUX_S_ISDIR(inode->i_mode) &&
5681              fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
5682             (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
5683              fix_problem(ctx, PR_1_HTREE_SET, pctx)))
5684                 return 1;
5685
5686         blk = inode->i_block[0];
5687         if (((blk == 0) ||
5688              (blk < fs->super->s_first_data_block) ||
5689              (blk >= fs->super->s_blocks_count)) &&
5690             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5691                 return 1;
5692
5693         retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
5694         if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5695                 return 1;
5696
5697         /* XXX should check that beginning matches a directory */
5698         root = (struct ext2_dx_root_info *) (block_buf + 24);
5699
5700         if ((root->reserved_zero || root->info_length < 8) &&
5701             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5702                 return 1;
5703
5704         pctx->num = root->hash_version;
5705         if ((root->hash_version != EXT2_HASH_LEGACY) &&
5706             (root->hash_version != EXT2_HASH_HALF_MD4) &&
5707             (root->hash_version != EXT2_HASH_TEA) &&
5708             fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
5709                 return 1;
5710
5711         if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
5712             fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
5713                 return 1;
5714
5715         pctx->num = root->indirect_levels;
5716         if ((root->indirect_levels > 1) &&
5717             fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
5718                 return 1;
5719
5720         return 0;
5721 }
5722
5723 /*
5724  * This subroutine is called on each inode to account for all of the
5725  * blocks used by that inode.
5726  */
5727 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
5728                          char *block_buf)
5729 {
5730         ext2_filsys fs = ctx->fs;
5731         struct process_block_struct_1 pb;
5732         ext2_ino_t      ino = pctx->ino;
5733         struct ext2_inode *inode = pctx->inode;
5734         int             bad_size = 0;
5735         int             dirty_inode = 0;
5736         __u64           size;
5737
5738         pb.ino = ino;
5739         pb.num_blocks = 0;
5740         pb.last_block = -1;
5741         pb.num_illegal_blocks = 0;
5742         pb.suppress = 0; pb.clear = 0;
5743         pb.fragmented = 0;
5744         pb.compressed = 0;
5745         pb.previous_block = 0;
5746         pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
5747         pb.is_reg = LINUX_S_ISREG(inode->i_mode);
5748         pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
5749         pb.inode = inode;
5750         pb.pctx = pctx;
5751         pb.ctx = ctx;
5752         pctx->ino = ino;
5753         pctx->errcode = 0;
5754
5755         if (inode->i_flags & EXT2_COMPRBLK_FL) {
5756                 if (fs->super->s_feature_incompat &
5757                     EXT2_FEATURE_INCOMPAT_COMPRESSION)
5758                         pb.compressed = 1;
5759                 else {
5760                         if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
5761                                 inode->i_flags &= ~EXT2_COMPRBLK_FL;
5762                                 dirty_inode++;
5763                         }
5764                 }
5765         }
5766
5767         if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
5768                 pb.num_blocks++;
5769
5770         if (ext2fs_inode_has_valid_blocks(inode))
5771                 pctx->errcode = ext2fs_block_iterate2(fs, ino,
5772                                        pb.is_dir ? BLOCK_FLAG_HOLE : 0,
5773                                        block_buf, process_block, &pb);
5774         end_problem_latch(ctx, PR_LATCH_BLOCK);
5775         end_problem_latch(ctx, PR_LATCH_TOOBIG);
5776         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5777                 goto out;
5778         if (pctx->errcode)
5779                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
5780
5781         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
5782                 ctx->fs_fragmented++;
5783
5784         if (pb.clear) {
5785                 inode->i_links_count = 0;
5786                 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5787                 inode->i_dtime = time(0);
5788                 dirty_inode++;
5789                 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5790                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5791                 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5792                 /*
5793                  * The inode was probably partially accounted for
5794                  * before processing was aborted, so we need to
5795                  * restart the pass 1 scan.
5796                  */
5797                 ctx->flags |= E2F_FLAG_RESTART;
5798                 goto out;
5799         }
5800
5801         if (inode->i_flags & EXT2_INDEX_FL) {
5802                 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
5803                         inode->i_flags &= ~EXT2_INDEX_FL;
5804                         dirty_inode++;
5805                 } else {
5806 #ifdef ENABLE_HTREE
5807                         e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
5808 #endif
5809                 }
5810         }
5811         if (ctx->dirs_to_hash && pb.is_dir &&
5812             !(inode->i_flags & EXT2_INDEX_FL) &&
5813             ((inode->i_size / fs->blocksize) >= 3))
5814                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
5815
5816         if (!pb.num_blocks && pb.is_dir) {
5817                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
5818                         inode->i_links_count = 0;
5819                         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5820                         inode->i_dtime = time(0);
5821                         dirty_inode++;
5822                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5823                         ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5824                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5825                         ctx->fs_directory_count--;
5826                         goto out;
5827                 }
5828         }
5829
5830         pb.num_blocks *= (fs->blocksize / 512);
5831 #if 0
5832         printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
5833                ino, inode->i_size, pb.last_block, inode->i_blocks,
5834                pb.num_blocks);
5835 #endif
5836         if (pb.is_dir) {
5837                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
5838                 if (nblock > (pb.last_block + 1))
5839                         bad_size = 1;
5840                 else if (nblock < (pb.last_block + 1)) {
5841                         if (((pb.last_block + 1) - nblock) >
5842                             fs->super->s_prealloc_dir_blocks)
5843                                 bad_size = 2;
5844                 }
5845         } else {
5846                 size = EXT2_I_SIZE(inode);
5847                 if ((pb.last_block >= 0) &&
5848                     (size < (__u64) pb.last_block * fs->blocksize))
5849                         bad_size = 3;
5850                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
5851                         bad_size = 4;
5852         }
5853         /* i_size for symlinks is checked elsewhere */
5854         if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
5855                 pctx->num = (pb.last_block+1) * fs->blocksize;
5856                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
5857                         inode->i_size = pctx->num;
5858                         if (!LINUX_S_ISDIR(inode->i_mode))
5859                                 inode->i_size_high = pctx->num >> 32;
5860                         dirty_inode++;
5861                 }
5862                 pctx->num = 0;
5863         }
5864         if (LINUX_S_ISREG(inode->i_mode) &&
5865             (inode->i_size_high || inode->i_size & 0x80000000UL))
5866                 ctx->large_files++;
5867         if (pb.num_blocks != inode->i_blocks) {
5868                 pctx->num = pb.num_blocks;
5869                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
5870                         inode->i_blocks = pb.num_blocks;
5871                         dirty_inode++;
5872                 }
5873                 pctx->num = 0;
5874         }
5875 out:
5876         if (dirty_inode)
5877                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
5878 }
5879
5880 #if 0
5881 /*
5882  * Helper function called by process block when an illegal block is
5883  * found.  It returns a description about why the block is illegal
5884  */
5885 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
5886 {
5887         blk_t   super;
5888         int     i;
5889         static char     problem[80];
5890
5891         super = fs->super->s_first_data_block;
5892         strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
5893         if (block < super) {
5894                 sprintf(problem, "< FIRSTBLOCK (%u)", super);
5895                 return(problem);
5896         } else if (block >= fs->super->s_blocks_count) {
5897                 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
5898                 return(problem);
5899         }
5900         for (i = 0; i < fs->group_desc_count; i++) {
5901                 if (block == super) {
5902                         sprintf(problem, "is the superblock in group %d", i);
5903                         break;
5904                 }
5905                 if (block > super &&
5906                     block <= (super + fs->desc_blocks)) {
5907                         sprintf(problem, "is in the group descriptors "
5908                                 "of group %d", i);
5909                         break;
5910                 }
5911                 if (block == fs->group_desc[i].bg_block_bitmap) {
5912                         sprintf(problem, "is the block bitmap of group %d", i);
5913                         break;
5914                 }
5915                 if (block == fs->group_desc[i].bg_inode_bitmap) {
5916                         sprintf(problem, "is the inode bitmap of group %d", i);
5917                         break;
5918                 }
5919                 if (block >= fs->group_desc[i].bg_inode_table &&
5920                     (block < fs->group_desc[i].bg_inode_table
5921                      + fs->inode_blocks_per_group)) {
5922                         sprintf(problem, "is in the inode table of group %d",
5923                                 i);
5924                         break;
5925                 }
5926                 super += fs->super->s_blocks_per_group;
5927         }
5928         return(problem);
5929 }
5930 #endif
5931
5932 /*
5933  * This is a helper function for check_blocks().
5934  */
5935 static int process_block(ext2_filsys fs,
5936                   blk_t *block_nr,
5937                   e2_blkcnt_t blockcnt,
5938                   blk_t ref_block EXT2FS_ATTR((unused)),
5939                   int ref_offset EXT2FS_ATTR((unused)),
5940                   void *priv_data)
5941 {
5942         struct process_block_struct_1 *p;
5943         struct problem_context *pctx;
5944         blk_t   blk = *block_nr;
5945         int     ret_code = 0;
5946         int     problem = 0;
5947         e2fsck_t        ctx;
5948
5949         p = (struct process_block_struct_1 *) priv_data;
5950         pctx = p->pctx;
5951         ctx = p->ctx;
5952
5953         if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
5954                 /* todo: Check that the comprblk_fl is high, that the
5955                    blkaddr pattern looks right (all non-holes up to
5956                    first EXT2FS_COMPRESSED_BLKADDR, then all
5957                    EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
5958                    that the feature_incompat bit is high, and that the
5959                    inode is a regular file.  If we're doing a "full
5960                    check" (a concept introduced to e2fsck by e2compr,
5961                    meaning that we look at data blocks as well as
5962                    metadata) then call some library routine that
5963                    checks the compressed data.  I'll have to think
5964                    about this, because one particularly important
5965                    problem to be able to fix is to recalculate the
5966                    cluster size if necessary.  I think that perhaps
5967                    we'd better do most/all e2compr-specific checks
5968                    separately, after the non-e2compr checks.  If not
5969                    doing a full check, it may be useful to test that
5970                    the personality is linux; e.g. if it isn't then
5971                    perhaps this really is just an illegal block. */
5972                 return 0;
5973         }
5974
5975         if (blk == 0) {
5976                 if (p->is_dir == 0) {
5977                         /*
5978                          * Should never happen, since only directories
5979                          * get called with BLOCK_FLAG_HOLE
5980                          */
5981 #if DEBUG_E2FSCK
5982                         printf("process_block() called with blk == 0, "
5983                                "blockcnt=%d, inode %lu???\n",
5984                                blockcnt, p->ino);
5985 #endif
5986                         return 0;
5987                 }
5988                 if (blockcnt < 0)
5989                         return 0;
5990                 if (blockcnt * fs->blocksize < p->inode->i_size) {
5991 #if 0
5992                         printf("Missing block (#%d) in directory inode %lu!\n",
5993                                blockcnt, p->ino);
5994 #endif
5995                         goto mark_dir;
5996                 }
5997                 return 0;
5998         }
5999
6000 #if 0
6001         printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
6002                blockcnt);
6003 #endif
6004
6005         /*
6006          * Simplistic fragmentation check.  We merely require that the
6007          * file be contiguous.  (Which can never be true for really
6008          * big files that are greater than a block group.)
6009          */
6010         if (!HOLE_BLKADDR(p->previous_block)) {
6011                 if (p->previous_block+1 != blk)
6012                         p->fragmented = 1;
6013         }
6014         p->previous_block = blk;
6015
6016         if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
6017                 problem = PR_1_TOOBIG_DIR;
6018         if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
6019                 problem = PR_1_TOOBIG_REG;
6020         if (!p->is_dir && !p->is_reg && blockcnt > 0)
6021                 problem = PR_1_TOOBIG_SYMLINK;
6022
6023         if (blk < fs->super->s_first_data_block ||
6024             blk >= fs->super->s_blocks_count)
6025                 problem = PR_1_ILLEGAL_BLOCK_NUM;
6026
6027         if (problem) {
6028                 p->num_illegal_blocks++;
6029                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
6030                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
6031                                 p->clear = 1;
6032                                 return BLOCK_ABORT;
6033                         }
6034                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
6035                                 p->suppress = 1;
6036                                 set_latch_flags(PR_LATCH_BLOCK,
6037                                                 PRL_SUPPRESS, 0);
6038                         }
6039                 }
6040                 pctx->blk = blk;
6041                 pctx->blkcount = blockcnt;
6042                 if (fix_problem(ctx, problem, pctx)) {
6043                         blk = *block_nr = 0;
6044                         ret_code = BLOCK_CHANGED;
6045                         goto mark_dir;
6046                 } else
6047                         return 0;
6048         }
6049
6050         if (p->ino == EXT2_RESIZE_INO) {
6051                 /*
6052                  * The resize inode has already be sanity checked
6053                  * during pass #0 (the superblock checks).  All we
6054                  * have to do is mark the double indirect block as
6055                  * being in use; all of the other blocks are handled
6056                  * by mark_table_blocks()).
6057                  */
6058                 if (blockcnt == BLOCK_COUNT_DIND)
6059                         mark_block_used(ctx, blk);
6060         } else
6061                 mark_block_used(ctx, blk);
6062         p->num_blocks++;
6063         if (blockcnt >= 0)
6064                 p->last_block = blockcnt;
6065 mark_dir:
6066         if (p->is_dir && (blockcnt >= 0)) {
6067                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
6068                                                     blk, blockcnt);
6069                 if (pctx->errcode) {
6070                         pctx->blk = blk;
6071                         pctx->num = blockcnt;
6072                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
6073                         /* Should never get here */
6074                         ctx->flags |= E2F_FLAG_ABORT;
6075                         return BLOCK_ABORT;
6076                 }
6077         }
6078         return ret_code;
6079 }
6080
6081 static int process_bad_block(ext2_filsys fs,
6082                       blk_t *block_nr,
6083                       e2_blkcnt_t blockcnt,
6084                       blk_t ref_block EXT2FS_ATTR((unused)),
6085                       int ref_offset EXT2FS_ATTR((unused)),
6086                       void *priv_data)
6087 {
6088         struct process_block_struct_1 *p;
6089         blk_t           blk = *block_nr;
6090         blk_t           first_block;
6091         dgrp_t          i;
6092         struct problem_context *pctx;
6093         e2fsck_t        ctx;
6094
6095         /*
6096          * Note: This function processes blocks for the bad blocks
6097          * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
6098          */
6099
6100         if (!blk)
6101                 return 0;
6102
6103         p = (struct process_block_struct_1 *) priv_data;
6104         ctx = p->ctx;
6105         pctx = p->pctx;
6106
6107         pctx->ino = EXT2_BAD_INO;
6108         pctx->blk = blk;
6109         pctx->blkcount = blockcnt;
6110
6111         if ((blk < fs->super->s_first_data_block) ||
6112             (blk >= fs->super->s_blocks_count)) {
6113                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
6114                         *block_nr = 0;
6115                         return BLOCK_CHANGED;
6116                 } else
6117                         return 0;
6118         }
6119
6120         if (blockcnt < 0) {
6121                 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
6122                         p->bbcheck = 1;
6123                         if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
6124                                 *block_nr = 0;
6125                                 return BLOCK_CHANGED;
6126                         }
6127                 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
6128                                                     blk)) {
6129                         p->bbcheck = 1;
6130                         if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
6131                                         pctx)) {
6132                                 *block_nr = 0;
6133                                 return BLOCK_CHANGED;
6134                         }
6135                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6136                                 return BLOCK_ABORT;
6137                 } else
6138                         mark_block_used(ctx, blk);
6139                 return 0;
6140         }
6141 #if 0
6142         printf ("DEBUG: Marking %u as bad.\n", blk);
6143 #endif
6144         ctx->fs_badblocks_count++;
6145         /*
6146          * If the block is not used, then mark it as used and return.
6147          * If it is already marked as found, this must mean that
6148          * there's an overlap between the filesystem table blocks
6149          * (bitmaps and inode table) and the bad block list.
6150          */
6151         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
6152                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6153                 return 0;
6154         }
6155         /*
6156          * Try to find the where the filesystem block was used...
6157          */
6158         first_block = fs->super->s_first_data_block;
6159
6160         for (i = 0; i < fs->group_desc_count; i++ ) {
6161                 pctx->group = i;
6162                 pctx->blk = blk;
6163                 if (!ext2fs_bg_has_super(fs, i))
6164                         goto skip_super;
6165                 if (blk == first_block) {
6166                         if (i == 0) {
6167                                 if (fix_problem(ctx,
6168                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
6169                                                 pctx)) {
6170                                         *block_nr = 0;
6171                                         return BLOCK_CHANGED;
6172                                 }
6173                                 return 0;
6174                         }
6175                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
6176                         return 0;
6177                 }
6178                 if ((blk > first_block) &&
6179                     (blk <= first_block + fs->desc_blocks)) {
6180                         if (i == 0) {
6181                                 pctx->blk = *block_nr;
6182                                 if (fix_problem(ctx,
6183                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
6184                                         *block_nr = 0;
6185                                         return BLOCK_CHANGED;
6186                                 }
6187                                 return 0;
6188                         }
6189                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
6190                         return 0;
6191                 }
6192         skip_super:
6193                 if (blk == fs->group_desc[i].bg_block_bitmap) {
6194                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
6195                                 ctx->invalid_block_bitmap_flag[i]++;
6196                                 ctx->invalid_bitmaps++;
6197                         }
6198                         return 0;
6199                 }
6200                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
6201                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
6202                                 ctx->invalid_inode_bitmap_flag[i]++;
6203                                 ctx->invalid_bitmaps++;
6204                         }
6205                         return 0;
6206                 }
6207                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
6208                     (blk < (fs->group_desc[i].bg_inode_table +
6209                             fs->inode_blocks_per_group))) {
6210                         /*
6211                          * If there are bad blocks in the inode table,
6212                          * the inode scan code will try to do
6213                          * something reasonable automatically.
6214                          */
6215                         return 0;
6216                 }
6217                 first_block += fs->super->s_blocks_per_group;
6218         }
6219         /*
6220          * If we've gotten to this point, then the only
6221          * possibility is that the bad block inode meta data
6222          * is using a bad block.
6223          */
6224         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
6225             (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
6226             (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
6227                 p->bbcheck = 1;
6228                 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
6229                         *block_nr = 0;
6230                         return BLOCK_CHANGED;
6231                 }
6232                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6233                         return BLOCK_ABORT;
6234                 return 0;
6235         }
6236
6237         pctx->group = -1;
6238
6239         /* Warn user that the block wasn't claimed */
6240         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
6241
6242         return 0;
6243 }
6244
6245 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
6246                             const char *name, int num, blk_t *new_block)
6247 {
6248         ext2_filsys fs = ctx->fs;
6249         blk_t           old_block = *new_block;
6250         int             i;
6251         char            *buf;
6252         struct problem_context  pctx;
6253
6254         clear_problem_context(&pctx);
6255
6256         pctx.group = group;
6257         pctx.blk = old_block;
6258         pctx.str = name;
6259
6260         pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
6261                         first_block + fs->super->s_blocks_per_group,
6262                                         num, ctx->block_found_map, new_block);
6263         if (pctx.errcode) {
6264                 pctx.num = num;
6265                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
6266                 ext2fs_unmark_valid(fs);
6267                 return;
6268         }
6269         pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
6270         if (pctx.errcode) {
6271                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
6272                 ext2fs_unmark_valid(fs);
6273                 return;
6274         }
6275         ext2fs_mark_super_dirty(fs);
6276         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
6277         pctx.blk2 = *new_block;
6278         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
6279                           PR_1_RELOC_TO), &pctx);
6280         pctx.blk2 = 0;
6281         for (i = 0; i < num; i++) {
6282                 pctx.blk = i;
6283                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
6284                 if (old_block) {
6285                         pctx.errcode = io_channel_read_blk(fs->io,
6286                                    old_block + i, 1, buf);
6287                         if (pctx.errcode)
6288                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
6289                 } else
6290                         memset(buf, 0, fs->blocksize);
6291
6292                 pctx.blk = (*new_block) + i;
6293                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
6294                                               1, buf);
6295                 if (pctx.errcode)
6296                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
6297         }
6298         ext2fs_free_mem(&buf);
6299 }
6300
6301 /*
6302  * This routine gets called at the end of pass 1 if bad blocks are
6303  * detected in the superblock, group descriptors, inode_bitmaps, or
6304  * block bitmaps.  At this point, all of the blocks have been mapped
6305  * out, so we can try to allocate new block(s) to replace the bad
6306  * blocks.
6307  */
6308 static void handle_fs_bad_blocks(e2fsck_t ctx)
6309 {
6310         ext2_filsys fs = ctx->fs;
6311         dgrp_t          i;
6312         int             first_block = fs->super->s_first_data_block;
6313
6314         for (i = 0; i < fs->group_desc_count; i++) {
6315                 if (ctx->invalid_block_bitmap_flag[i]) {
6316                         new_table_block(ctx, first_block, i, _("block bitmap"),
6317                                         1, &fs->group_desc[i].bg_block_bitmap);
6318                 }
6319                 if (ctx->invalid_inode_bitmap_flag[i]) {
6320                         new_table_block(ctx, first_block, i, _("inode bitmap"),
6321                                         1, &fs->group_desc[i].bg_inode_bitmap);
6322                 }
6323                 if (ctx->invalid_inode_table_flag[i]) {
6324                         new_table_block(ctx, first_block, i, _("inode table"),
6325                                         fs->inode_blocks_per_group,
6326                                         &fs->group_desc[i].bg_inode_table);
6327                         ctx->flags |= E2F_FLAG_RESTART;
6328                 }
6329                 first_block += fs->super->s_blocks_per_group;
6330         }
6331         ctx->invalid_bitmaps = 0;
6332 }
6333
6334 /*
6335  * This routine marks all blocks which are used by the superblock,
6336  * group descriptors, inode bitmaps, and block bitmaps.
6337  */
6338 static void mark_table_blocks(e2fsck_t ctx)
6339 {
6340         ext2_filsys fs = ctx->fs;
6341         blk_t   block, b;
6342         dgrp_t  i;
6343         int     j;
6344         struct problem_context pctx;
6345
6346         clear_problem_context(&pctx);
6347
6348         block = fs->super->s_first_data_block;
6349         for (i = 0; i < fs->group_desc_count; i++) {
6350                 pctx.group = i;
6351
6352                 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
6353
6354                 /*
6355                  * Mark the blocks used for the inode table
6356                  */
6357                 if (fs->group_desc[i].bg_inode_table) {
6358                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
6359                              j < fs->inode_blocks_per_group;
6360                              j++, b++) {
6361                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6362                                                              b)) {
6363                                         pctx.blk = b;
6364                                         if (fix_problem(ctx,
6365                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
6366                                                 ctx->invalid_inode_table_flag[i]++;
6367                                                 ctx->invalid_bitmaps++;
6368                                         }
6369                                 } else {
6370                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
6371                                                              b);
6372                                 }
6373                         }
6374                 }
6375
6376                 /*
6377                  * Mark block used for the block bitmap
6378                  */
6379                 if (fs->group_desc[i].bg_block_bitmap) {
6380                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
6381                                      fs->group_desc[i].bg_block_bitmap)) {
6382                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
6383                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
6384                                         ctx->invalid_block_bitmap_flag[i]++;
6385                                         ctx->invalid_bitmaps++;
6386                                 }
6387                         } else {
6388                             ext2fs_mark_block_bitmap(ctx->block_found_map,
6389                                      fs->group_desc[i].bg_block_bitmap);
6390                     }
6391
6392                 }
6393                 /*
6394                  * Mark block used for the inode bitmap
6395                  */
6396                 if (fs->group_desc[i].bg_inode_bitmap) {
6397                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
6398                                      fs->group_desc[i].bg_inode_bitmap)) {
6399                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
6400                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
6401                                         ctx->invalid_inode_bitmap_flag[i]++;
6402                                         ctx->invalid_bitmaps++;
6403                                 }
6404                         } else {
6405                             ext2fs_mark_block_bitmap(ctx->block_found_map,
6406                                      fs->group_desc[i].bg_inode_bitmap);
6407                         }
6408                 }
6409                 block += fs->super->s_blocks_per_group;
6410         }
6411 }
6412
6413 /*
6414  * Thes subroutines short circuits ext2fs_get_blocks and
6415  * ext2fs_check_directory; we use them since we already have the inode
6416  * structure, so there's no point in letting the ext2fs library read
6417  * the inode again.
6418  */
6419 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
6420                                   blk_t *blocks)
6421 {
6422         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6423         int     i;
6424
6425         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6426                 return EXT2_ET_CALLBACK_NOTHANDLED;
6427
6428         for (i=0; i < EXT2_N_BLOCKS; i++)
6429                 blocks[i] = ctx->stashed_inode->i_block[i];
6430         return 0;
6431 }
6432
6433 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
6434                                   struct ext2_inode *inode)
6435 {
6436         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6437
6438         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6439                 return EXT2_ET_CALLBACK_NOTHANDLED;
6440         *inode = *ctx->stashed_inode;
6441         return 0;
6442 }
6443
6444 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
6445                             struct ext2_inode *inode)
6446 {
6447         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6448
6449         if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
6450                 *ctx->stashed_inode = *inode;
6451         return EXT2_ET_CALLBACK_NOTHANDLED;
6452 }
6453
6454 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
6455 {
6456         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6457
6458         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6459                 return EXT2_ET_CALLBACK_NOTHANDLED;
6460
6461         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
6462                 return EXT2_ET_NO_DIRECTORY;
6463         return 0;
6464 }
6465
6466 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
6467 {
6468         ext2_filsys fs = ctx->fs;
6469
6470         if (bool) {
6471                 fs->get_blocks = pass1_get_blocks;
6472                 fs->check_directory = pass1_check_directory;
6473                 fs->read_inode = pass1_read_inode;
6474                 fs->write_inode = pass1_write_inode;
6475                 ctx->stashed_ino = 0;
6476         } else {
6477                 fs->get_blocks = 0;
6478                 fs->check_directory = 0;
6479                 fs->read_inode = 0;
6480                 fs->write_inode = 0;
6481         }
6482 }
6483 /*
6484  * pass1b.c --- Pass #1b of e2fsck
6485  *
6486  * This file contains pass1B, pass1C, and pass1D of e2fsck.  They are
6487  * only invoked if pass 1 discovered blocks which are in use by more
6488  * than one inode.
6489  *
6490  * Pass1B scans the data blocks of all the inodes again, generating a
6491  * complete list of duplicate blocks and which inodes have claimed
6492  * them.
6493  *
6494  * Pass1C does a tree-traversal of the filesystem, to determine the
6495  * parent directories of these inodes.  This step is necessary so that
6496  * e2fsck can print out the pathnames of affected inodes.
6497  *
6498  * Pass1D is a reconciliation pass.  For each inode with duplicate
6499  * blocks, the user is prompted if s/he would like to clone the file
6500  * (so that the file gets a fresh copy of the duplicated blocks) or
6501  * simply to delete the file.
6502  *
6503  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6504  *
6505  * %Begin-Header%
6506  * This file may be redistributed under the terms of the GNU Public
6507  * License.
6508  * %End-Header%
6509  *
6510  */
6511
6512
6513 /* Needed for architectures where sizeof(int) != sizeof(void *) */
6514 #define INT_TO_VOIDPTR(val)  ((void *)(intptr_t)(val))
6515 #define VOIDPTR_TO_INT(ptr)  ((int)(intptr_t)(ptr))
6516
6517 /* Define an extension to the ext2 library's block count information */
6518 #define BLOCK_COUNT_EXTATTR     (-5)
6519
6520 struct block_el {
6521         blk_t   block;
6522         struct block_el *next;
6523 };
6524
6525 struct inode_el {
6526         ext2_ino_t      inode;
6527         struct inode_el *next;
6528 };
6529
6530 struct dup_block {
6531         int             num_bad;
6532         struct inode_el *inode_list;
6533 };
6534
6535 /*
6536  * This structure stores information about a particular inode which
6537  * is sharing blocks with other inodes.  This information is collected
6538  * to display to the user, so that the user knows what files he or she
6539  * is dealing with, when trying to decide how to resolve the conflict
6540  * of multiply-claimed blocks.
6541  */
6542 struct dup_inode {
6543         ext2_ino_t              dir;
6544         int                     num_dupblocks;
6545         struct ext2_inode       inode;
6546         struct block_el         *block_list;
6547 };
6548
6549 static int process_pass1b_block(ext2_filsys fs, blk_t   *blocknr,
6550                                 e2_blkcnt_t blockcnt, blk_t ref_blk,
6551                                 int ref_offset, void *priv_data);
6552 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6553                         struct dup_inode *dp, char *block_buf);
6554 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6555                       struct dup_inode *dp, char* block_buf);
6556 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
6557
6558 static void pass1b(e2fsck_t ctx, char *block_buf);
6559 static void pass1c(e2fsck_t ctx, char *block_buf);
6560 static void pass1d(e2fsck_t ctx, char *block_buf);
6561
6562 static int dup_inode_count = 0;
6563
6564 static dict_t blk_dict, ino_dict;
6565
6566 static ext2fs_inode_bitmap inode_dup_map;
6567
6568 static int dict_int_cmp(const void *a, const void *b)
6569 {
6570         intptr_t        ia, ib;
6571
6572         ia = (intptr_t)a;
6573         ib = (intptr_t)b;
6574
6575         return (ia-ib);
6576 }
6577
6578 /*
6579  * Add a duplicate block record
6580  */
6581 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
6582                      struct ext2_inode *inode)
6583 {
6584         dnode_t *n;
6585         struct dup_block        *db;
6586         struct dup_inode        *di;
6587         struct block_el         *blk_el;
6588         struct inode_el         *ino_el;
6589
6590         n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6591         if (n)
6592                 db = (struct dup_block *) dnode_get(n);
6593         else {
6594                 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
6595                          sizeof(struct dup_block), "duplicate block header");
6596                 db->num_bad = 0;
6597                 db->inode_list = 0;
6598                 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
6599         }
6600         ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
6601                          sizeof(struct inode_el), "inode element");
6602         ino_el->inode = ino;
6603         ino_el->next = db->inode_list;
6604         db->inode_list = ino_el;
6605         db->num_bad++;
6606
6607         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
6608         if (n)
6609                 di = (struct dup_inode *) dnode_get(n);
6610         else {
6611                 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
6612                          sizeof(struct dup_inode), "duplicate inode header");
6613                 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
6614                 di->num_dupblocks = 0;
6615                 di->block_list = 0;
6616                 di->inode = *inode;
6617                 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
6618         }
6619         blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
6620                          sizeof(struct block_el), "block element");
6621         blk_el->block = blk;
6622         blk_el->next = di->block_list;
6623         di->block_list = blk_el;
6624         di->num_dupblocks++;
6625 }
6626
6627 /*
6628  * Free a duplicate inode record
6629  */
6630 static void inode_dnode_free(dnode_t *node,
6631                              void *context EXT2FS_ATTR((unused)))
6632 {
6633         struct dup_inode        *di;
6634         struct block_el         *p, *next;
6635
6636         di = (struct dup_inode *) dnode_get(node);
6637         for (p = di->block_list; p; p = next) {
6638                 next = p->next;
6639                 free(p);
6640         }
6641         free(node);
6642 }
6643
6644 /*
6645  * Free a duplicate block record
6646  */
6647 static void block_dnode_free(dnode_t *node,
6648                              void *context EXT2FS_ATTR((unused)))
6649 {
6650         struct dup_block        *db;
6651         struct inode_el         *p, *next;
6652
6653         db = (struct dup_block *) dnode_get(node);
6654         for (p = db->inode_list; p; p = next) {
6655                 next = p->next;
6656                 free(p);
6657         }
6658         free(node);
6659 }
6660
6661
6662 /*
6663  * Main procedure for handling duplicate blocks
6664  */
6665 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
6666 {
6667         ext2_filsys             fs = ctx->fs;
6668         struct problem_context  pctx;
6669
6670         clear_problem_context(&pctx);
6671
6672         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
6673                       _("multiply claimed inode map"), &inode_dup_map);
6674         if (pctx.errcode) {
6675                 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
6676                 ctx->flags |= E2F_FLAG_ABORT;
6677                 return;
6678         }
6679
6680         dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6681         dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6682         dict_set_allocator(&ino_dict, NULL, inode_dnode_free, NULL);
6683         dict_set_allocator(&blk_dict, NULL, block_dnode_free, NULL);
6684
6685         pass1b(ctx, block_buf);
6686         pass1c(ctx, block_buf);
6687         pass1d(ctx, block_buf);
6688
6689         /*
6690          * Time to free all of the accumulated data structures that we
6691          * don't need anymore.
6692          */
6693         dict_free_nodes(&ino_dict);
6694         dict_free_nodes(&blk_dict);
6695 }
6696
6697 /*
6698  * Scan the inodes looking for inodes that contain duplicate blocks.
6699  */
6700 struct process_block_struct_1b {
6701         e2fsck_t        ctx;
6702         ext2_ino_t      ino;
6703         int             dup_blocks;
6704         struct ext2_inode *inode;
6705         struct problem_context *pctx;
6706 };
6707
6708 static void pass1b(e2fsck_t ctx, char *block_buf)
6709 {
6710         ext2_filsys fs = ctx->fs;
6711         ext2_ino_t ino;
6712         struct ext2_inode inode;
6713         ext2_inode_scan scan;
6714         struct process_block_struct_1b pb;
6715         struct problem_context pctx;
6716
6717         clear_problem_context(&pctx);
6718
6719         if (!(ctx->options & E2F_OPT_PREEN))
6720                 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
6721         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
6722                                               &scan);
6723         if (pctx.errcode) {
6724                 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6725                 ctx->flags |= E2F_FLAG_ABORT;
6726                 return;
6727         }
6728         ctx->stashed_inode = &inode;
6729         pb.ctx = ctx;
6730         pb.pctx = &pctx;
6731         pctx.str = "pass1b";
6732         while (1) {
6733                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
6734                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
6735                         continue;
6736                 if (pctx.errcode) {
6737                         fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6738                         ctx->flags |= E2F_FLAG_ABORT;
6739                         return;
6740                 }
6741                 if (!ino)
6742                         break;
6743                 pctx.ino = ctx->stashed_ino = ino;
6744                 if ((ino != EXT2_BAD_INO) &&
6745                     !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
6746                         continue;
6747
6748                 pb.ino = ino;
6749                 pb.dup_blocks = 0;
6750                 pb.inode = &inode;
6751
6752                 if (ext2fs_inode_has_valid_blocks(&inode) ||
6753                     (ino == EXT2_BAD_INO))
6754                         pctx.errcode = ext2fs_block_iterate2(fs, ino,
6755                                      0, block_buf, process_pass1b_block, &pb);
6756                 if (inode.i_file_acl)
6757                         process_pass1b_block(fs, &inode.i_file_acl,
6758                                              BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6759                 if (pb.dup_blocks) {
6760                         end_problem_latch(ctx, PR_LATCH_DBLOCK);
6761                         if (ino >= EXT2_FIRST_INODE(fs->super) ||
6762                             ino == EXT2_ROOT_INO)
6763                                 dup_inode_count++;
6764                 }
6765                 if (pctx.errcode)
6766                         fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6767         }
6768         ext2fs_close_inode_scan(scan);
6769         e2fsck_use_inode_shortcuts(ctx, 0);
6770 }
6771
6772 static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
6773                                 blk_t   *block_nr,
6774                                 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
6775                                 blk_t ref_blk EXT2FS_ATTR((unused)),
6776                                 int ref_offset EXT2FS_ATTR((unused)),
6777                                 void *priv_data)
6778 {
6779         struct process_block_struct_1b *p;
6780         e2fsck_t ctx;
6781
6782         if (HOLE_BLKADDR(*block_nr))
6783                 return 0;
6784         p = (struct process_block_struct_1b *) priv_data;
6785         ctx = p->ctx;
6786
6787         if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
6788                 return 0;
6789
6790         /* OK, this is a duplicate block */
6791         if (p->ino != EXT2_BAD_INO) {
6792                 p->pctx->blk = *block_nr;
6793                 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
6794         }
6795         p->dup_blocks++;
6796         ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
6797
6798         add_dupe(ctx, p->ino, *block_nr, p->inode);
6799
6800         return 0;
6801 }
6802
6803 /*
6804  * Pass 1c: Scan directories for inodes with duplicate blocks.  This
6805  * is used so that we can print pathnames when prompting the user for
6806  * what to do.
6807  */
6808 struct search_dir_struct {
6809         int             count;
6810         ext2_ino_t      first_inode;
6811         ext2_ino_t      max_inode;
6812 };
6813
6814 static int search_dirent_proc(ext2_ino_t dir, int entry,
6815                               struct ext2_dir_entry *dirent,
6816                               int offset EXT2FS_ATTR((unused)),
6817                               int blocksize EXT2FS_ATTR((unused)),
6818                               char *buf EXT2FS_ATTR((unused)),
6819                               void *priv_data)
6820 {
6821         struct search_dir_struct *sd;
6822         struct dup_inode        *p;
6823         dnode_t                 *n;
6824
6825         sd = (struct search_dir_struct *) priv_data;
6826
6827         if (dirent->inode > sd->max_inode)
6828                 /* Should abort this inode, but not everything */
6829                 return 0;
6830
6831         if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
6832             !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
6833                 return 0;
6834
6835         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
6836         if (!n)
6837                 return 0;
6838         p = (struct dup_inode *) dnode_get(n);
6839         p->dir = dir;
6840         sd->count--;
6841
6842         return(sd->count ? 0 : DIRENT_ABORT);
6843 }
6844
6845
6846 static void pass1c(e2fsck_t ctx, char *block_buf)
6847 {
6848         ext2_filsys fs = ctx->fs;
6849         struct search_dir_struct sd;
6850         struct problem_context pctx;
6851
6852         clear_problem_context(&pctx);
6853
6854         if (!(ctx->options & E2F_OPT_PREEN))
6855                 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
6856
6857         /*
6858          * Search through all directories to translate inodes to names
6859          * (by searching for the containing directory for that inode.)
6860          */
6861         sd.count = dup_inode_count;
6862         sd.first_inode = EXT2_FIRST_INODE(fs->super);
6863         sd.max_inode = fs->super->s_inodes_count;
6864         ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
6865                                   search_dirent_proc, &sd);
6866 }
6867
6868 static void pass1d(e2fsck_t ctx, char *block_buf)
6869 {
6870         ext2_filsys fs = ctx->fs;
6871         struct dup_inode        *p, *t;
6872         struct dup_block        *q;
6873         ext2_ino_t              *shared, ino;
6874         int     shared_len;
6875         int     i;
6876         int     file_ok;
6877         int     meta_data = 0;
6878         struct problem_context pctx;
6879         dnode_t *n, *m;
6880         struct block_el *s;
6881         struct inode_el *r;
6882
6883         clear_problem_context(&pctx);
6884
6885         if (!(ctx->options & E2F_OPT_PREEN))
6886                 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
6887         e2fsck_read_bitmaps(ctx);
6888
6889         pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
6890         fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
6891         shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
6892                                 sizeof(ext2_ino_t) * dict_count(&ino_dict),
6893                                 "Shared inode list");
6894         for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
6895                 p = (struct dup_inode *) dnode_get(n);
6896                 shared_len = 0;
6897                 file_ok = 1;
6898                 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
6899                 if (ino == EXT2_BAD_INO)
6900                         continue;
6901
6902                 /*
6903                  * Find all of the inodes which share blocks with this
6904                  * one.  First we find all of the duplicate blocks
6905                  * belonging to this inode, and then search each block
6906                  * get the list of inodes, and merge them together.
6907                  */
6908                 for (s = p->block_list; s; s = s->next) {
6909                         m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
6910                         if (!m)
6911                                 continue; /* Should never happen... */
6912                         q = (struct dup_block *) dnode_get(m);
6913                         if (q->num_bad > 1)
6914                                 file_ok = 0;
6915                         if (check_if_fs_block(ctx, s->block)) {
6916                                 file_ok = 0;
6917                                 meta_data = 1;
6918                         }
6919
6920                         /*
6921                          * Add all inodes used by this block to the
6922                          * shared[] --- which is a unique list, so
6923                          * if an inode is already in shared[], don't
6924                          * add it again.
6925                          */
6926                         for (r = q->inode_list; r; r = r->next) {
6927                                 if (r->inode == ino)
6928                                         continue;
6929                                 for (i = 0; i < shared_len; i++)
6930                                         if (shared[i] == r->inode)
6931                                                 break;
6932                                 if (i == shared_len) {
6933                                         shared[shared_len++] = r->inode;
6934                                 }
6935                         }
6936                 }
6937
6938                 /*
6939                  * Report the inode that we are working on
6940                  */
6941                 pctx.inode = &p->inode;
6942                 pctx.ino = ino;
6943                 pctx.dir = p->dir;
6944                 pctx.blkcount = p->num_dupblocks;
6945                 pctx.num = meta_data ? shared_len+1 : shared_len;
6946                 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
6947                 pctx.blkcount = 0;
6948                 pctx.num = 0;
6949
6950                 if (meta_data)
6951                         fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
6952
6953                 for (i = 0; i < shared_len; i++) {
6954                         m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
6955                         if (!m)
6956                                 continue; /* should never happen */
6957                         t = (struct dup_inode *) dnode_get(m);
6958                         /*
6959                          * Report the inode that we are sharing with
6960                          */
6961                         pctx.inode = &t->inode;
6962                         pctx.ino = shared[i];
6963                         pctx.dir = t->dir;
6964                         fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
6965                 }
6966                 if (file_ok) {
6967                         fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
6968                         continue;
6969                 }
6970                 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
6971                         pctx.errcode = clone_file(ctx, ino, p, block_buf);
6972                         if (pctx.errcode)
6973                                 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
6974                         else
6975                                 continue;
6976                 }
6977                 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
6978                         delete_file(ctx, ino, p, block_buf);
6979                 else
6980                         ext2fs_unmark_valid(fs);
6981         }
6982         ext2fs_free_mem(&shared);
6983 }
6984
6985 /*
6986  * Drop the refcount on the dup_block structure, and clear the entry
6987  * in the block_dup_map if appropriate.
6988  */
6989 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
6990 {
6991         p->num_bad--;
6992         if (p->num_bad <= 0 ||
6993             (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
6994                 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
6995 }
6996
6997 static int delete_file_block(ext2_filsys fs,
6998                              blk_t      *block_nr,
6999                              e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
7000                              blk_t ref_block EXT2FS_ATTR((unused)),
7001                              int ref_offset EXT2FS_ATTR((unused)),
7002                              void *priv_data)
7003 {
7004         struct process_block_struct_1b *pb;
7005         struct dup_block *p;
7006         dnode_t *n;
7007         e2fsck_t ctx;
7008
7009         pb = (struct process_block_struct_1b *) priv_data;
7010         ctx = pb->ctx;
7011
7012         if (HOLE_BLKADDR(*block_nr))
7013                 return 0;
7014
7015         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
7016                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
7017                 if (n) {
7018                         p = (struct dup_block *) dnode_get(n);
7019                         decrement_badcount(ctx, *block_nr, p);
7020                 } else
7021                         com_err("delete_file_block", 0,
7022                             _("internal error; can't find dup_blk for %d\n"),
7023                                 *block_nr);
7024         } else {
7025                 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
7026                 ext2fs_block_alloc_stats(fs, *block_nr, -1);
7027         }
7028
7029         return 0;
7030 }
7031
7032 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
7033                         struct dup_inode *dp, char* block_buf)
7034 {
7035         ext2_filsys fs = ctx->fs;
7036         struct process_block_struct_1b pb;
7037         struct ext2_inode       inode;
7038         struct problem_context  pctx;
7039         unsigned int            count;
7040
7041         clear_problem_context(&pctx);
7042         pctx.ino = pb.ino = ino;
7043         pb.dup_blocks = dp->num_dupblocks;
7044         pb.ctx = ctx;
7045         pctx.str = "delete_file";
7046
7047         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
7048         if (ext2fs_inode_has_valid_blocks(&inode))
7049                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7050                                                      delete_file_block, &pb);
7051         if (pctx.errcode)
7052                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
7053         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
7054         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
7055         if (ctx->inode_bad_map)
7056                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7057         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
7058
7059         /* Inode may have changed by block_iterate, so reread it */
7060         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
7061         inode.i_links_count = 0;
7062         inode.i_dtime = time(0);
7063         if (inode.i_file_acl &&
7064             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
7065                 count = 1;
7066                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
7067                                                    block_buf, -1, &count);
7068                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
7069                         pctx.errcode = 0;
7070                         count = 1;
7071                 }
7072                 if (pctx.errcode) {
7073                         pctx.blk = inode.i_file_acl;
7074                         fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
7075                 }
7076                 /*
7077                  * If the count is zero, then arrange to have the
7078                  * block deleted.  If the block is in the block_dup_map,
7079                  * also call delete_file_block since it will take care
7080                  * of keeping the accounting straight.
7081                  */
7082                 if ((count == 0) ||
7083                     ext2fs_test_block_bitmap(ctx->block_dup_map,
7084                                              inode.i_file_acl))
7085                         delete_file_block(fs, &inode.i_file_acl,
7086                                           BLOCK_COUNT_EXTATTR, 0, 0, &pb);
7087         }
7088         e2fsck_write_inode(ctx, ino, &inode, "delete_file");
7089 }
7090
7091 struct clone_struct {
7092         errcode_t       errcode;
7093         ext2_ino_t      dir;
7094         char    *buf;
7095         e2fsck_t ctx;
7096 };
7097
7098 static int clone_file_block(ext2_filsys fs,
7099                             blk_t       *block_nr,
7100                             e2_blkcnt_t blockcnt,
7101                             blk_t ref_block EXT2FS_ATTR((unused)),
7102                             int ref_offset EXT2FS_ATTR((unused)),
7103                             void *priv_data)
7104 {
7105         struct dup_block *p;
7106         blk_t   new_block;
7107         errcode_t       retval;
7108         struct clone_struct *cs = (struct clone_struct *) priv_data;
7109         dnode_t *n;
7110         e2fsck_t ctx;
7111
7112         ctx = cs->ctx;
7113
7114         if (HOLE_BLKADDR(*block_nr))
7115                 return 0;
7116
7117         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
7118                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
7119                 if (n) {
7120                         p = (struct dup_block *) dnode_get(n);
7121                         retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
7122                                                   &new_block);
7123                         if (retval) {
7124                                 cs->errcode = retval;
7125                                 return BLOCK_ABORT;
7126                         }
7127                         if (cs->dir && (blockcnt >= 0)) {
7128                                 retval = ext2fs_set_dir_block(fs->dblist,
7129                                       cs->dir, new_block, blockcnt);
7130                                 if (retval) {
7131                                         cs->errcode = retval;
7132                                         return BLOCK_ABORT;
7133                                 }
7134                         }
7135 #if 0
7136                         printf("Cloning block %u to %u\n", *block_nr,
7137                                new_block);
7138 #endif
7139                         retval = io_channel_read_blk(fs->io, *block_nr, 1,
7140                                                      cs->buf);
7141                         if (retval) {
7142                                 cs->errcode = retval;
7143                                 return BLOCK_ABORT;
7144                         }
7145                         retval = io_channel_write_blk(fs->io, new_block, 1,
7146                                                       cs->buf);
7147                         if (retval) {
7148                                 cs->errcode = retval;
7149                                 return BLOCK_ABORT;
7150                         }
7151                         decrement_badcount(ctx, *block_nr, p);
7152                         *block_nr = new_block;
7153                         ext2fs_mark_block_bitmap(ctx->block_found_map,
7154                                                  new_block);
7155                         ext2fs_mark_block_bitmap(fs->block_map, new_block);
7156                         return BLOCK_CHANGED;
7157                 } else
7158                         com_err("clone_file_block", 0,
7159                             _("internal error; can't find dup_blk for %d\n"),
7160                                 *block_nr);
7161         }
7162         return 0;
7163 }
7164
7165 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
7166                       struct dup_inode *dp, char* block_buf)
7167 {
7168         ext2_filsys fs = ctx->fs;
7169         errcode_t       retval;
7170         struct clone_struct cs;
7171         struct problem_context  pctx;
7172         blk_t           blk;
7173         dnode_t         *n;
7174         struct inode_el *ino_el;
7175         struct dup_block        *db;
7176         struct dup_inode        *di;
7177
7178         clear_problem_context(&pctx);
7179         cs.errcode = 0;
7180         cs.dir = 0;
7181         cs.ctx = ctx;
7182         retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
7183         if (retval)
7184                 return retval;
7185
7186         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
7187                 cs.dir = ino;
7188
7189         pctx.ino = ino;
7190         pctx.str = "clone_file";
7191         if (ext2fs_inode_has_valid_blocks(&dp->inode))
7192                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7193                                                      clone_file_block, &cs);
7194         ext2fs_mark_bb_dirty(fs);
7195         if (pctx.errcode) {
7196                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
7197                 retval = pctx.errcode;
7198                 goto errout;
7199         }
7200         if (cs.errcode) {
7201                 com_err("clone_file", cs.errcode,
7202                         _("returned from clone_file_block"));
7203                 retval = cs.errcode;
7204                 goto errout;
7205         }
7206         /* The inode may have changed on disk, so we have to re-read it */
7207         e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
7208         blk = dp->inode.i_file_acl;
7209         if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
7210                                      BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
7211                     BLOCK_CHANGED)) {
7212                 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
7213                 /*
7214                  * If we cloned the EA block, find all other inodes
7215                  * which refered to that EA block, and modify
7216                  * them to point to the new EA block.
7217                  */
7218                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
7219                 db = (struct dup_block *) dnode_get(n);
7220                 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
7221                         if (ino_el->inode == ino)
7222                                 continue;
7223                         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
7224                         di = (struct dup_inode *) dnode_get(n);
7225                         if (di->inode.i_file_acl == blk) {
7226                                 di->inode.i_file_acl = dp->inode.i_file_acl;
7227                                 e2fsck_write_inode(ctx, ino_el->inode,
7228                                            &di->inode, "clone file EA");
7229                                 decrement_badcount(ctx, blk, db);
7230                         }
7231                 }
7232         }
7233         retval = 0;
7234 errout:
7235         ext2fs_free_mem(&cs.buf);
7236         return retval;
7237 }
7238
7239 /*
7240  * This routine returns 1 if a block overlaps with one of the superblocks,
7241  * group descriptors, inode bitmaps, or block bitmaps.
7242  */
7243 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
7244 {
7245         ext2_filsys fs = ctx->fs;
7246         blk_t   block;
7247         dgrp_t  i;
7248
7249         block = fs->super->s_first_data_block;
7250         for (i = 0; i < fs->group_desc_count; i++) {
7251
7252                 /* Check superblocks/block group descriptros */
7253                 if (ext2fs_bg_has_super(fs, i)) {
7254                         if (test_block >= block &&
7255                             (test_block <= block + fs->desc_blocks))
7256                                 return 1;
7257                 }
7258
7259                 /* Check the inode table */
7260                 if ((fs->group_desc[i].bg_inode_table) &&
7261                     (test_block >= fs->group_desc[i].bg_inode_table) &&
7262                     (test_block < (fs->group_desc[i].bg_inode_table +
7263                                    fs->inode_blocks_per_group)))
7264                         return 1;
7265
7266                 /* Check the bitmap blocks */
7267                 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
7268                     (test_block == fs->group_desc[i].bg_inode_bitmap))
7269                         return 1;
7270
7271                 block += fs->super->s_blocks_per_group;
7272         }
7273         return 0;
7274 }
7275 /*
7276  * pass2.c --- check directory structure
7277  *
7278  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o
7279  *
7280  * %Begin-Header%
7281  * This file may be redistributed under the terms of the GNU Public
7282  * License.
7283  * %End-Header%
7284  *
7285  * Pass 2 of e2fsck iterates through all active directory inodes, and
7286  * applies to following tests to each directory entry in the directory
7287  * blocks in the inodes:
7288  *
7289  *      - The length of the directory entry (rec_len) should be at
7290  *              least 8 bytes, and no more than the remaining space
7291  *              left in the directory block.
7292  *      - The length of the name in the directory entry (name_len)
7293  *              should be less than (rec_len - 8).
7294  *      - The inode number in the directory entry should be within
7295  *              legal bounds.
7296  *      - The inode number should refer to a in-use inode.
7297  *      - The first entry should be '.', and its inode should be
7298  *              the inode of the directory.
7299  *      - The second entry should be '..'.
7300  *
7301  * To minimize disk seek time, the directory blocks are processed in
7302  * sorted order of block numbers.
7303  *
7304  * Pass 2 also collects the following information:
7305  *      - The inode numbers of the subdirectories for each directory.
7306  *
7307  * Pass 2 relies on the following information from previous passes:
7308  *      - The directory information collected in pass 1.
7309  *      - The inode_used_map bitmap
7310  *      - The inode_bad_map bitmap
7311  *      - The inode_dir_map bitmap
7312  *
7313  * Pass 2 frees the following data structures
7314  *      - The inode_bad_map bitmap
7315  *      - The inode_reg_map bitmap
7316  */
7317
7318 /* #define DX_DEBUG */
7319
7320 /*
7321  * Keeps track of how many times an inode is referenced.
7322  */
7323 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
7324 static int check_dir_block(ext2_filsys fs,
7325                            struct ext2_db_entry *dir_blocks_info,
7326                            void *priv_data);
7327 static int allocate_dir_block(e2fsck_t ctx,
7328                               struct ext2_db_entry *dir_blocks_info,
7329                               char *buf, struct problem_context *pctx);
7330 static int update_dir_block(ext2_filsys fs,
7331                             blk_t       *block_nr,
7332                             e2_blkcnt_t blockcnt,
7333                             blk_t       ref_block,
7334                             int         ref_offset,
7335                             void        *priv_data);
7336 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
7337 static int htree_depth(struct dx_dir_info *dx_dir,
7338                        struct dx_dirblock_info *dx_db);
7339 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
7340
7341 struct check_dir_struct {
7342         char *buf;
7343         struct problem_context  pctx;
7344         int     count, max;
7345         e2fsck_t ctx;
7346 };
7347
7348 void e2fsck_pass2(e2fsck_t ctx)
7349 {
7350         struct ext2_super_block *sb = ctx->fs->super;
7351         struct problem_context  pctx;
7352         ext2_filsys             fs = ctx->fs;
7353         char                    *buf;
7354 #ifdef RESOURCE_TRACK
7355         struct resource_track   rtrack;
7356 #endif
7357         struct dir_info         *dir;
7358         struct check_dir_struct cd;
7359         struct dx_dir_info      *dx_dir;
7360         struct dx_dirblock_info *dx_db, *dx_parent;
7361         int                     b;
7362         int                     i, depth;
7363         problem_t               code;
7364         int                     bad_dir;
7365
7366 #ifdef RESOURCE_TRACK
7367         init_resource_track(&rtrack);
7368 #endif
7369
7370         clear_problem_context(&cd.pctx);
7371
7372 #ifdef MTRACE
7373         mtrace_print("Pass 2");
7374 #endif
7375
7376         if (!(ctx->options & E2F_OPT_PREEN))
7377                 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
7378
7379         cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
7380                                                 0, ctx->inode_link_info,
7381                                                 &ctx->inode_count);
7382         if (cd.pctx.errcode) {
7383                 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
7384                 ctx->flags |= E2F_FLAG_ABORT;
7385                 return;
7386         }
7387         buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
7388                                               "directory scan buffer");
7389
7390         /*
7391          * Set up the parent pointer for the root directory, if
7392          * present.  (If the root directory is not present, we will
7393          * create it in pass 3.)
7394          */
7395         dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
7396         if (dir)
7397                 dir->parent = EXT2_ROOT_INO;
7398
7399         cd.buf = buf;
7400         cd.ctx = ctx;
7401         cd.count = 1;
7402         cd.max = ext2fs_dblist_count(fs->dblist);
7403
7404         if (ctx->progress)
7405                 (void) (ctx->progress)(ctx, 2, 0, cd.max);
7406
7407         if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
7408                 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
7409
7410         cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
7411                                                 &cd);
7412         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7413                 return;
7414         if (cd.pctx.errcode) {
7415                 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
7416                 ctx->flags |= E2F_FLAG_ABORT;
7417                 return;
7418         }
7419
7420 #ifdef ENABLE_HTREE
7421         for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
7422                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7423                         return;
7424                 if (dx_dir->numblocks == 0)
7425                         continue;
7426                 clear_problem_context(&pctx);
7427                 bad_dir = 0;
7428                 pctx.dir = dx_dir->ino;
7429                 dx_db = dx_dir->dx_block;
7430                 if (dx_db->flags & DX_FLAG_REFERENCED)
7431                         dx_db->flags |= DX_FLAG_DUP_REF;
7432                 else
7433                         dx_db->flags |= DX_FLAG_REFERENCED;
7434                 /*
7435                  * Find all of the first and last leaf blocks, and
7436                  * update their parent's min and max hash values
7437                  */
7438                 for (b=0, dx_db = dx_dir->dx_block;
7439                      b < dx_dir->numblocks;
7440                      b++, dx_db++) {
7441                         if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
7442                             !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
7443                                 continue;
7444                         dx_parent = &dx_dir->dx_block[dx_db->parent];
7445                         /*
7446                          * XXX Make sure dx_parent->min_hash > dx_db->min_hash
7447                          */
7448                         if (dx_db->flags & DX_FLAG_FIRST)
7449                                 dx_parent->min_hash = dx_db->min_hash;
7450                         /*
7451                          * XXX Make sure dx_parent->max_hash < dx_db->max_hash
7452                          */
7453                         if (dx_db->flags & DX_FLAG_LAST)
7454                                 dx_parent->max_hash = dx_db->max_hash;
7455                 }
7456
7457                 for (b=0, dx_db = dx_dir->dx_block;
7458                      b < dx_dir->numblocks;
7459                      b++, dx_db++) {
7460                         pctx.blkcount = b;
7461                         pctx.group = dx_db->parent;
7462                         code = 0;
7463                         if (!(dx_db->flags & DX_FLAG_FIRST) &&
7464                             (dx_db->min_hash < dx_db->node_min_hash)) {
7465                                 pctx.blk = dx_db->min_hash;
7466                                 pctx.blk2 = dx_db->node_min_hash;
7467                                 code = PR_2_HTREE_MIN_HASH;
7468                                 fix_problem(ctx, code, &pctx);
7469                                 bad_dir++;
7470                         }
7471                         if (dx_db->type == DX_DIRBLOCK_LEAF) {
7472                                 depth = htree_depth(dx_dir, dx_db);
7473                                 if (depth != dx_dir->depth) {
7474                                         code = PR_2_HTREE_BAD_DEPTH;
7475                                         fix_problem(ctx, code, &pctx);
7476                                         bad_dir++;
7477                                 }
7478                         }
7479                         /*
7480                          * This test doesn't apply for the root block
7481                          * at block #0
7482                          */
7483                         if (b &&
7484                             (dx_db->max_hash > dx_db->node_max_hash)) {
7485                                 pctx.blk = dx_db->max_hash;
7486                                 pctx.blk2 = dx_db->node_max_hash;
7487                                 code = PR_2_HTREE_MAX_HASH;
7488                                 fix_problem(ctx, code, &pctx);
7489                                 bad_dir++;
7490                         }
7491                         if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
7492                                 code = PR_2_HTREE_NOTREF;
7493                                 fix_problem(ctx, code, &pctx);
7494                                 bad_dir++;
7495                         } else if (dx_db->flags & DX_FLAG_DUP_REF) {
7496                                 code = PR_2_HTREE_DUPREF;
7497                                 fix_problem(ctx, code, &pctx);
7498                                 bad_dir++;
7499                         }
7500                         if (code == 0)
7501                                 continue;
7502                 }
7503                 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
7504                         clear_htree(ctx, dx_dir->ino);
7505                         dx_dir->numblocks = 0;
7506                 }
7507         }
7508 #endif
7509         ext2fs_free_mem(&buf);
7510         ext2fs_free_dblist(fs->dblist);
7511
7512         if (ctx->inode_bad_map) {
7513                 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
7514                 ctx->inode_bad_map = 0;
7515         }
7516         if (ctx->inode_reg_map) {
7517                 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
7518                 ctx->inode_reg_map = 0;
7519         }
7520
7521         clear_problem_context(&pctx);
7522         if (ctx->large_files) {
7523                 if (!(sb->s_feature_ro_compat &
7524                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
7525                     fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
7526                         sb->s_feature_ro_compat |=
7527                                 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7528                         ext2fs_mark_super_dirty(fs);
7529                 }
7530                 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
7531                     fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
7532                         ext2fs_update_dynamic_rev(fs);
7533                         ext2fs_mark_super_dirty(fs);
7534                 }
7535         } else if (!ctx->large_files &&
7536             (sb->s_feature_ro_compat &
7537               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
7538                 if (fs->flags & EXT2_FLAG_RW) {
7539                         sb->s_feature_ro_compat &=
7540                                 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7541                         ext2fs_mark_super_dirty(fs);
7542                 }
7543         }
7544
7545 #ifdef RESOURCE_TRACK
7546         if (ctx->options & E2F_OPT_TIME2) {
7547                 e2fsck_clear_progbar(ctx);
7548                 print_resource_track(_("Pass 2"), &rtrack);
7549         }
7550 #endif
7551 }
7552
7553 #define MAX_DEPTH 32000
7554 static int htree_depth(struct dx_dir_info *dx_dir,
7555                        struct dx_dirblock_info *dx_db)
7556 {
7557         int     depth = 0;
7558
7559         while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
7560                 dx_db = &dx_dir->dx_block[dx_db->parent];
7561                 depth++;
7562         }
7563         return depth;
7564 }
7565
7566 static int dict_de_cmp(const void *a, const void *b)
7567 {
7568         const struct ext2_dir_entry *de_a, *de_b;
7569         int     a_len, b_len;
7570
7571         de_a = (const struct ext2_dir_entry *) a;
7572         a_len = de_a->name_len & 0xFF;
7573         de_b = (const struct ext2_dir_entry *) b;
7574         b_len = de_b->name_len & 0xFF;
7575
7576         if (a_len != b_len)
7577                 return (a_len - b_len);
7578
7579         return strncmp(de_a->name, de_b->name, a_len);
7580 }
7581
7582 /*
7583  * This is special sort function that makes sure that directory blocks
7584  * with a dirblock of zero are sorted to the beginning of the list.
7585  * This guarantees that the root node of the htree directories are
7586  * processed first, so we know what hash version to use.
7587  */
7588 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
7589 {
7590         const struct ext2_db_entry *db_a =
7591                 (const struct ext2_db_entry *) a;
7592         const struct ext2_db_entry *db_b =
7593                 (const struct ext2_db_entry *) b;
7594
7595         if (db_a->blockcnt && !db_b->blockcnt)
7596                 return 1;
7597
7598         if (!db_a->blockcnt && db_b->blockcnt)
7599                 return -1;
7600
7601         if (db_a->blk != db_b->blk)
7602                 return (int) (db_a->blk - db_b->blk);
7603
7604         if (db_a->ino != db_b->ino)
7605                 return (int) (db_a->ino - db_b->ino);
7606
7607         return (int) (db_a->blockcnt - db_b->blockcnt);
7608 }
7609
7610
7611 /*
7612  * Make sure the first entry in the directory is '.', and that the
7613  * directory entry is sane.
7614  */
7615 static int check_dot(e2fsck_t ctx,
7616                      struct ext2_dir_entry *dirent,
7617                      ext2_ino_t ino, struct problem_context *pctx)
7618 {
7619         struct ext2_dir_entry *nextdir;
7620         int     status = 0;
7621         int     created = 0;
7622         int     new_len;
7623         int     problem = 0;
7624
7625         if (!dirent->inode)
7626                 problem = PR_2_MISSING_DOT;
7627         else if (((dirent->name_len & 0xFF) != 1) ||
7628                  (dirent->name[0] != '.'))
7629                 problem = PR_2_1ST_NOT_DOT;
7630         else if (dirent->name[1] != '\0')
7631                 problem = PR_2_DOT_NULL_TERM;
7632
7633         if (problem) {
7634                 if (fix_problem(ctx, problem, pctx)) {
7635                         if (dirent->rec_len < 12)
7636                                 dirent->rec_len = 12;
7637                         dirent->inode = ino;
7638                         dirent->name_len = 1;
7639                         dirent->name[0] = '.';
7640                         dirent->name[1] = '\0';
7641                         status = 1;
7642                         created = 1;
7643                 }
7644         }
7645         if (dirent->inode != ino) {
7646                 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
7647                         dirent->inode = ino;
7648                         status = 1;
7649                 }
7650         }
7651         if (dirent->rec_len > 12) {
7652                 new_len = dirent->rec_len - 12;
7653                 if (new_len > 12) {
7654                         if (created ||
7655                             fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
7656                                 nextdir = (struct ext2_dir_entry *)
7657                                         ((char *) dirent + 12);
7658                                 dirent->rec_len = 12;
7659                                 nextdir->rec_len = new_len;
7660                                 nextdir->inode = 0;
7661                                 nextdir->name_len = 0;
7662                                 status = 1;
7663                         }
7664                 }
7665         }
7666         return status;
7667 }
7668
7669 /*
7670  * Make sure the second entry in the directory is '..', and that the
7671  * directory entry is sane.  We do not check the inode number of '..'
7672  * here; this gets done in pass 3.
7673  */
7674 static int check_dotdot(e2fsck_t ctx,
7675                         struct ext2_dir_entry *dirent,
7676                         struct dir_info *dir, struct problem_context *pctx)
7677 {
7678         int             problem = 0;
7679
7680         if (!dirent->inode)
7681                 problem = PR_2_MISSING_DOT_DOT;
7682         else if (((dirent->name_len & 0xFF) != 2) ||
7683                  (dirent->name[0] != '.') ||
7684                  (dirent->name[1] != '.'))
7685                 problem = PR_2_2ND_NOT_DOT_DOT;
7686         else if (dirent->name[2] != '\0')
7687                 problem = PR_2_DOT_DOT_NULL_TERM;
7688
7689         if (problem) {
7690                 if (fix_problem(ctx, problem, pctx)) {
7691                         if (dirent->rec_len < 12)
7692                                 dirent->rec_len = 12;
7693                         /*
7694                          * Note: we don't have the parent inode just
7695                          * yet, so we will fill it in with the root
7696                          * inode.  This will get fixed in pass 3.
7697                          */
7698                         dirent->inode = EXT2_ROOT_INO;
7699                         dirent->name_len = 2;
7700                         dirent->name[0] = '.';
7701                         dirent->name[1] = '.';
7702                         dirent->name[2] = '\0';
7703                         return 1;
7704                 }
7705                 return 0;
7706         }
7707         dir->dotdot = dirent->inode;
7708         return 0;
7709 }
7710
7711 /*
7712  * Check to make sure a directory entry doesn't contain any illegal
7713  * characters.
7714  */
7715 static int check_name(e2fsck_t ctx,
7716                       struct ext2_dir_entry *dirent,
7717                       ext2_ino_t dir_ino EXT2FS_ATTR((unused)),
7718                       struct problem_context *pctx)
7719 {
7720         int     i;
7721         int     fixup = -1;
7722         int     ret = 0;
7723
7724         for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
7725                 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
7726                         if (fixup < 0) {
7727                                 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
7728                         }
7729                         if (fixup) {
7730                                 dirent->name[i] = '.';
7731                                 ret = 1;
7732                         }
7733                 }
7734         }
7735         return ret;
7736 }
7737
7738 /*
7739  * Check the directory filetype (if present)
7740  */
7741 static _INLINE_ int check_filetype(e2fsck_t ctx,
7742                                    struct ext2_dir_entry *dirent,
7743                                    ext2_ino_t dir_ino EXT2FS_ATTR((unused)),
7744                                    struct problem_context *pctx)
7745 {
7746         int     filetype = dirent->name_len >> 8;
7747         int     should_be = EXT2_FT_UNKNOWN;
7748         struct ext2_inode       inode;
7749
7750         if (!(ctx->fs->super->s_feature_incompat &
7751               EXT2_FEATURE_INCOMPAT_FILETYPE)) {
7752                 if (filetype == 0 ||
7753                     !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
7754                         return 0;
7755                 dirent->name_len = dirent->name_len & 0xFF;
7756                 return 1;
7757         }
7758
7759         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
7760                 should_be = EXT2_FT_DIR;
7761         } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
7762                                             dirent->inode)) {
7763                 should_be = EXT2_FT_REG_FILE;
7764         } else if (ctx->inode_bad_map &&
7765                    ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7766                                             dirent->inode))
7767                 should_be = 0;
7768         else {
7769                 e2fsck_read_inode(ctx, dirent->inode, &inode,
7770                                   "check_filetype");
7771                 should_be = ext2_file_type(inode.i_mode);
7772         }
7773         if (filetype == should_be)
7774                 return 0;
7775         pctx->num = should_be;
7776
7777         if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
7778                         pctx) == 0)
7779                 return 0;
7780
7781         dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
7782         return 1;
7783 }
7784
7785 #ifdef ENABLE_HTREE
7786 static void parse_int_node(ext2_filsys fs,
7787                            struct ext2_db_entry *db,
7788                            struct check_dir_struct *cd,
7789                            struct dx_dir_info   *dx_dir,
7790                            char *block_buf)
7791 {
7792         struct          ext2_dx_root_info  *root;
7793         struct          ext2_dx_entry *ent;
7794         struct          ext2_dx_countlimit *limit;
7795         struct dx_dirblock_info *dx_db;
7796         int             i, expect_limit, count;
7797         blk_t           blk;
7798         ext2_dirhash_t  min_hash = 0xffffffff;
7799         ext2_dirhash_t  max_hash = 0;
7800         ext2_dirhash_t  hash = 0, prev_hash;
7801
7802         if (db->blockcnt == 0) {
7803                 root = (struct ext2_dx_root_info *) (block_buf + 24);
7804
7805 #ifdef DX_DEBUG
7806                 printf("Root node dump:\n");
7807                 printf("\t Reserved zero: %d\n", root->reserved_zero);
7808                 printf("\t Hash Version: %d\n", root->hash_version);
7809                 printf("\t Info length: %d\n", root->info_length);
7810                 printf("\t Indirect levels: %d\n", root->indirect_levels);
7811                 printf("\t Flags: %d\n", root->unused_flags);
7812 #endif
7813
7814                 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
7815         } else {
7816                 ent = (struct ext2_dx_entry *) (block_buf+8);
7817         }
7818         limit = (struct ext2_dx_countlimit *) ent;
7819
7820 #ifdef DX_DEBUG
7821         printf("Number of entries (count): %d\n",
7822                ext2fs_le16_to_cpu(limit->count));
7823         printf("Number of entries (limit): %d\n",
7824                ext2fs_le16_to_cpu(limit->limit));
7825 #endif
7826
7827         count = ext2fs_le16_to_cpu(limit->count);
7828         expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
7829                 sizeof(struct ext2_dx_entry);
7830         if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
7831                 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
7832                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
7833                         goto clear_and_exit;
7834         }
7835         if (count > expect_limit) {
7836                 cd->pctx.num = count;
7837                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
7838                         goto clear_and_exit;
7839                 count = expect_limit;
7840         }
7841
7842         for (i=0; i < count; i++) {
7843                 prev_hash = hash;
7844                 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
7845 #ifdef DX_DEBUG
7846                 printf("Entry #%d: Hash 0x%08x, block %d\n", i,
7847                        hash, ext2fs_le32_to_cpu(ent[i].block));
7848 #endif
7849                 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
7850                 /* Check to make sure the block is valid */
7851                 if (blk > (blk_t) dx_dir->numblocks) {
7852                         cd->pctx.blk = blk;
7853                         if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
7854                                         &cd->pctx))
7855                                 goto clear_and_exit;
7856                 }
7857                 if (hash < prev_hash &&
7858                     fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
7859                         goto clear_and_exit;
7860                 dx_db = &dx_dir->dx_block[blk];
7861                 if (dx_db->flags & DX_FLAG_REFERENCED) {
7862                         dx_db->flags |= DX_FLAG_DUP_REF;
7863                 } else {
7864                         dx_db->flags |= DX_FLAG_REFERENCED;
7865                         dx_db->parent = db->blockcnt;
7866                 }
7867                 if (hash < min_hash)
7868                         min_hash = hash;
7869                 if (hash > max_hash)
7870                         max_hash = hash;
7871                 dx_db->node_min_hash = hash;
7872                 if ((i+1) < count)
7873                         dx_db->node_max_hash =
7874                           ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
7875                 else {
7876                         dx_db->node_max_hash = 0xfffffffe;
7877                         dx_db->flags |= DX_FLAG_LAST;
7878                 }
7879                 if (i == 0)
7880                         dx_db->flags |= DX_FLAG_FIRST;
7881         }
7882 #ifdef DX_DEBUG
7883         printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
7884                db->blockcnt, min_hash, max_hash);
7885 #endif
7886         dx_db = &dx_dir->dx_block[db->blockcnt];
7887         dx_db->min_hash = min_hash;
7888         dx_db->max_hash = max_hash;
7889         return;
7890
7891 clear_and_exit:
7892         clear_htree(cd->ctx, cd->pctx.ino);
7893         dx_dir->numblocks = 0;
7894 }
7895 #endif /* ENABLE_HTREE */
7896
7897 /*
7898  * Given a busted directory, try to salvage it somehow.
7899  *
7900  */
7901 static void salvage_directory(ext2_filsys fs,
7902                               struct ext2_dir_entry *dirent,
7903                               struct ext2_dir_entry *prev,
7904                               unsigned int *offset)
7905 {
7906         char    *cp = (char *) dirent;
7907         int left = fs->blocksize - *offset - dirent->rec_len;
7908         int name_len = dirent->name_len & 0xFF;
7909
7910         /*
7911          * Special case of directory entry of size 8: copy what's left
7912          * of the directory block up to cover up the invalid hole.
7913          */
7914         if ((left >= 12) && (dirent->rec_len == 8)) {
7915                 memmove(cp, cp+8, left);
7916                 memset(cp + left, 0, 8);
7917                 return;
7918         }
7919         /*
7920          * If the directory entry overruns the end of the directory
7921          * block, and the name is small enough to fit, then adjust the
7922          * record length.
7923          */
7924         if ((left < 0) &&
7925             (name_len + 8 <= dirent->rec_len + left) &&
7926             dirent->inode <= fs->super->s_inodes_count &&
7927             strnlen(dirent->name, name_len) == name_len) {
7928                 dirent->rec_len += left;
7929                 return;
7930         }
7931         /*
7932          * If the directory entry is a multiple of four, so it is
7933          * valid, let the previous directory entry absorb the invalid
7934          * one.
7935          */
7936         if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
7937                 prev->rec_len += dirent->rec_len;
7938                 *offset += dirent->rec_len;
7939                 return;
7940         }
7941         /*
7942          * Default salvage method --- kill all of the directory
7943          * entries for the rest of the block.  We will either try to
7944          * absorb it into the previous directory entry, or create a
7945          * new empty directory entry the rest of the directory block.
7946          */
7947         if (prev) {
7948                 prev->rec_len += fs->blocksize - *offset;
7949                 *offset = fs->blocksize;
7950         } else {
7951                 dirent->rec_len = fs->blocksize - *offset;
7952                 dirent->name_len = 0;
7953                 dirent->inode = 0;
7954         }
7955 }
7956
7957 static int check_dir_block(ext2_filsys fs,
7958                            struct ext2_db_entry *db,
7959                            void *priv_data)
7960 {
7961         struct dir_info         *subdir, *dir;
7962         struct dx_dir_info      *dx_dir;
7963 #ifdef ENABLE_HTREE
7964         struct dx_dirblock_info *dx_db = 0;
7965 #endif /* ENABLE_HTREE */
7966         struct ext2_dir_entry   *dirent, *prev;
7967         ext2_dirhash_t          hash;
7968         unsigned int            offset = 0;
7969         int                     dir_modified = 0;
7970         int                     dot_state;
7971         blk_t                   block_nr = db->blk;
7972         ext2_ino_t              ino = db->ino;
7973         __u16                   links;
7974         struct check_dir_struct *cd;
7975         char                    *buf;
7976         e2fsck_t                ctx;
7977         int                     problem;
7978         struct ext2_dx_root_info *root;
7979         struct ext2_dx_countlimit *limit;
7980         static dict_t de_dict;
7981         struct problem_context  pctx;
7982         int     dups_found = 0;
7983
7984         cd = (struct check_dir_struct *) priv_data;
7985         buf = cd->buf;
7986         ctx = cd->ctx;
7987
7988         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7989                 return DIRENT_ABORT;
7990
7991         if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
7992                 return DIRENT_ABORT;
7993
7994         /*
7995          * Make sure the inode is still in use (could have been
7996          * deleted in the duplicate/bad blocks pass.
7997          */
7998         if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
7999                 return 0;
8000
8001         cd->pctx.ino = ino;
8002         cd->pctx.blk = block_nr;
8003         cd->pctx.blkcount = db->blockcnt;
8004         cd->pctx.ino2 = 0;
8005         cd->pctx.dirent = 0;
8006         cd->pctx.num = 0;
8007
8008         if (db->blk == 0) {
8009                 if (allocate_dir_block(ctx, db, buf, &cd->pctx))
8010                         return 0;
8011                 block_nr = db->blk;
8012         }
8013
8014         if (db->blockcnt)
8015                 dot_state = 2;
8016         else
8017                 dot_state = 0;
8018
8019         if (ctx->dirs_to_hash &&
8020             ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
8021                 dups_found++;
8022
8023 #if 0
8024         printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr,
8025                db->blockcnt, ino);
8026 #endif
8027
8028         cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
8029         if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
8030                 cd->pctx.errcode = 0; /* We'll handle this ourselves */
8031         if (cd->pctx.errcode) {
8032                 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
8033                         ctx->flags |= E2F_FLAG_ABORT;
8034                         return DIRENT_ABORT;
8035                 }
8036                 memset(buf, 0, fs->blocksize);
8037         }
8038 #ifdef ENABLE_HTREE
8039         dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
8040         if (dx_dir && dx_dir->numblocks) {
8041                 if (db->blockcnt >= dx_dir->numblocks) {
8042                         printf("XXX should never happen!!!\n");
8043                         abort();
8044                 }
8045                 dx_db = &dx_dir->dx_block[db->blockcnt];
8046                 dx_db->type = DX_DIRBLOCK_LEAF;
8047                 dx_db->phys = block_nr;
8048                 dx_db->min_hash = ~0;
8049                 dx_db->max_hash = 0;
8050
8051                 dirent = (struct ext2_dir_entry *) buf;
8052                 limit = (struct ext2_dx_countlimit *) (buf+8);
8053                 if (db->blockcnt == 0) {
8054                         root = (struct ext2_dx_root_info *) (buf + 24);
8055                         dx_db->type = DX_DIRBLOCK_ROOT;
8056                         dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
8057                         if ((root->reserved_zero ||
8058                              root->info_length < 8 ||
8059                              root->indirect_levels > 1) &&
8060                             fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
8061                                 clear_htree(ctx, ino);
8062                                 dx_dir->numblocks = 0;
8063                                 dx_db = 0;
8064                         }
8065                         dx_dir->hashversion = root->hash_version;
8066                         dx_dir->depth = root->indirect_levels + 1;
8067                 } else if ((dirent->inode == 0) &&
8068                            (dirent->rec_len == fs->blocksize) &&
8069                            (dirent->name_len == 0) &&
8070                            (ext2fs_le16_to_cpu(limit->limit) ==
8071                             ((fs->blocksize-8) /
8072                              sizeof(struct ext2_dx_entry))))
8073                         dx_db->type = DX_DIRBLOCK_NODE;
8074         }
8075 #endif /* ENABLE_HTREE */
8076
8077         dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
8078         prev = 0;
8079         do {
8080                 problem = 0;
8081                 dirent = (struct ext2_dir_entry *) (buf + offset);
8082                 cd->pctx.dirent = dirent;
8083                 cd->pctx.num = offset;
8084                 if (((offset + dirent->rec_len) > fs->blocksize) ||
8085                     (dirent->rec_len < 12) ||
8086                     ((dirent->rec_len % 4) != 0) ||
8087                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
8088                         if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
8089                                 salvage_directory(fs, dirent, prev, &offset);
8090                                 dir_modified++;
8091                                 continue;
8092                         } else
8093                                 goto abort_free_dict;
8094                 }
8095                 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
8096                         if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
8097                                 dirent->name_len = EXT2_NAME_LEN;
8098                                 dir_modified++;
8099                         }
8100                 }
8101
8102                 if (dot_state == 0) {
8103                         if (check_dot(ctx, dirent, ino, &cd->pctx))
8104                                 dir_modified++;
8105                 } else if (dot_state == 1) {
8106                         dir = e2fsck_get_dir_info(ctx, ino);
8107                         if (!dir) {
8108                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
8109                                 goto abort_free_dict;
8110                         }
8111                         if (check_dotdot(ctx, dirent, dir, &cd->pctx))
8112                                 dir_modified++;
8113                 } else if (dirent->inode == ino) {
8114                         problem = PR_2_LINK_DOT;
8115                         if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
8116                                 dirent->inode = 0;
8117                                 dir_modified++;
8118                                 goto next;
8119                         }
8120                 }
8121                 if (!dirent->inode)
8122                         goto next;
8123
8124                 /*
8125                  * Make sure the inode listed is a legal one.
8126                  */
8127                 if (((dirent->inode != EXT2_ROOT_INO) &&
8128                      (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
8129                     (dirent->inode > fs->super->s_inodes_count)) {
8130                         problem = PR_2_BAD_INO;
8131                 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
8132                                                dirent->inode))) {
8133                         /*
8134                          * If the inode is unused, offer to clear it.
8135                          */
8136                         problem = PR_2_UNUSED_INODE;
8137                 } else if (ctx->inode_bb_map &&
8138                            (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
8139                                                      dirent->inode))) {
8140                         /*
8141                          * If the inode is in a bad block, offer to
8142                          * clear it.
8143                          */
8144                         problem = PR_2_BB_INODE;
8145                 } else if ((dot_state > 1) &&
8146                            ((dirent->name_len & 0xFF) == 1) &&
8147                            (dirent->name[0] == '.')) {
8148                         /*
8149                          * If there's a '.' entry in anything other
8150                          * than the first directory entry, it's a
8151                          * duplicate entry that should be removed.
8152                          */
8153                         problem = PR_2_DUP_DOT;
8154                 } else if ((dot_state > 1) &&
8155                            ((dirent->name_len & 0xFF) == 2) &&
8156                            (dirent->name[0] == '.') &&
8157                            (dirent->name[1] == '.')) {
8158                         /*
8159                          * If there's a '..' entry in anything other
8160                          * than the second directory entry, it's a
8161                          * duplicate entry that should be removed.
8162                          */
8163                         problem = PR_2_DUP_DOT_DOT;
8164                 } else if ((dot_state > 1) &&
8165                            (dirent->inode == EXT2_ROOT_INO)) {
8166                         /*
8167                          * Don't allow links to the root directory.
8168                          * We check this specially to make sure we
8169                          * catch this error case even if the root
8170                          * directory hasn't been created yet.
8171                          */
8172                         problem = PR_2_LINK_ROOT;
8173                 } else if ((dot_state > 1) &&
8174                            (dirent->name_len & 0xFF) == 0) {
8175                         /*
8176                          * Don't allow zero-length directory names.
8177                          */
8178                         problem = PR_2_NULL_NAME;
8179                 }
8180
8181                 if (problem) {
8182                         if (fix_problem(ctx, problem, &cd->pctx)) {
8183                                 dirent->inode = 0;
8184                                 dir_modified++;
8185                                 goto next;
8186                         } else {
8187                                 ext2fs_unmark_valid(fs);
8188                                 if (problem == PR_2_BAD_INO)
8189                                         goto next;
8190                         }
8191                 }
8192
8193                 /*
8194                  * If the inode was marked as having bad fields in
8195                  * pass1, process it and offer to fix/clear it.
8196                  * (We wait until now so that we can display the
8197                  * pathname to the user.)
8198                  */
8199                 if (ctx->inode_bad_map &&
8200                     ext2fs_test_inode_bitmap(ctx->inode_bad_map,
8201                                              dirent->inode)) {
8202                         if (e2fsck_process_bad_inode(ctx, ino,
8203                                                      dirent->inode,
8204                                                      buf + fs->blocksize)) {
8205                                 dirent->inode = 0;
8206                                 dir_modified++;
8207                                 goto next;
8208                         }
8209                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8210                                 return DIRENT_ABORT;
8211                 }
8212
8213                 if (check_name(ctx, dirent, ino, &cd->pctx))
8214                         dir_modified++;
8215
8216                 if (check_filetype(ctx, dirent, ino, &cd->pctx))
8217                         dir_modified++;
8218
8219 #ifdef ENABLE_HTREE
8220                 if (dx_db) {
8221                         ext2fs_dirhash(dx_dir->hashversion, dirent->name,
8222                                        (dirent->name_len & 0xFF),
8223                                        fs->super->s_hash_seed, &hash, 0);
8224                         if (hash < dx_db->min_hash)
8225                                 dx_db->min_hash = hash;
8226                         if (hash > dx_db->max_hash)
8227                                 dx_db->max_hash = hash;
8228                 }
8229 #endif
8230
8231                 /*
8232                  * If this is a directory, then mark its parent in its
8233                  * dir_info structure.  If the parent field is already
8234                  * filled in, then this directory has more than one
8235                  * hard link.  We assume the first link is correct,
8236                  * and ask the user if he/she wants to clear this one.
8237                  */
8238                 if ((dot_state > 1) &&
8239                     (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8240                                               dirent->inode))) {
8241                         subdir = e2fsck_get_dir_info(ctx, dirent->inode);
8242                         if (!subdir) {
8243                                 cd->pctx.ino = dirent->inode;
8244                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
8245                                 goto abort_free_dict;
8246                         }
8247                         if (subdir->parent) {
8248                                 cd->pctx.ino2 = subdir->parent;
8249                                 if (fix_problem(ctx, PR_2_LINK_DIR,
8250                                                 &cd->pctx)) {
8251                                         dirent->inode = 0;
8252                                         dir_modified++;
8253                                         goto next;
8254                                 }
8255                                 cd->pctx.ino2 = 0;
8256                         } else
8257                                 subdir->parent = ino;
8258                 }
8259
8260                 if (dups_found) {
8261                         ;
8262                 } else if (dict_lookup(&de_dict, dirent)) {
8263                         clear_problem_context(&pctx);
8264                         pctx.ino = ino;
8265                         pctx.dirent = dirent;
8266                         fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
8267                         if (!ctx->dirs_to_hash)
8268                                 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
8269                         if (ctx->dirs_to_hash)
8270                                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8271                         dups_found++;
8272                 } else
8273                         dict_alloc_insert(&de_dict, dirent, dirent);
8274
8275                 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
8276                                         &links);
8277                 if (links > 1)
8278                         ctx->fs_links_count++;
8279                 ctx->fs_total_count++;
8280         next:
8281                 prev = dirent;
8282                 offset += dirent->rec_len;
8283                 dot_state++;
8284         } while (offset < fs->blocksize);
8285 #if 0
8286         printf("\n");
8287 #endif
8288 #ifdef ENABLE_HTREE
8289         if (dx_db) {
8290 #ifdef DX_DEBUG
8291                 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
8292                        db->blockcnt, dx_db->type,
8293                        dx_db->min_hash, dx_db->max_hash);
8294 #endif
8295                 cd->pctx.dir = cd->pctx.ino;
8296                 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
8297                     (dx_db->type == DX_DIRBLOCK_NODE))
8298                         parse_int_node(fs, db, cd, dx_dir, buf);
8299         }
8300 #endif /* ENABLE_HTREE */
8301         if (offset != fs->blocksize) {
8302                 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
8303                 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
8304                         dirent->rec_len = cd->pctx.num;
8305                         dir_modified++;
8306                 }
8307         }
8308         if (dir_modified) {
8309                 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
8310                 if (cd->pctx.errcode) {
8311                         if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
8312                                          &cd->pctx))
8313                                 goto abort_free_dict;
8314                 }
8315                 ext2fs_mark_changed(fs);
8316         }
8317         dict_free_nodes(&de_dict);
8318         return 0;
8319 abort_free_dict:
8320         dict_free_nodes(&de_dict);
8321         ctx->flags |= E2F_FLAG_ABORT;
8322         return DIRENT_ABORT;
8323 }
8324
8325 /*
8326  * This function is called to deallocate a block, and is an interator
8327  * functioned called by deallocate inode via ext2fs_iterate_block().
8328  */
8329 static int deallocate_inode_block(ext2_filsys fs,
8330                                   blk_t *block_nr,
8331                                   e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
8332                                   blk_t ref_block EXT2FS_ATTR((unused)),
8333                                   int ref_offset EXT2FS_ATTR((unused)),
8334                                   void *priv_data)
8335 {
8336         e2fsck_t        ctx = (e2fsck_t) priv_data;
8337
8338         if (HOLE_BLKADDR(*block_nr))
8339                 return 0;
8340         if ((*block_nr < fs->super->s_first_data_block) ||
8341             (*block_nr >= fs->super->s_blocks_count))
8342                 return 0;
8343         ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
8344         ext2fs_block_alloc_stats(fs, *block_nr, -1);
8345         return 0;
8346 }
8347
8348 /*
8349  * This fuction deallocates an inode
8350  */
8351 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
8352 {
8353         ext2_filsys fs = ctx->fs;
8354         struct ext2_inode       inode;
8355         struct problem_context  pctx;
8356         __u32                   count;
8357
8358         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
8359         e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
8360         inode.i_links_count = 0;
8361         inode.i_dtime = time(0);
8362         e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
8363         clear_problem_context(&pctx);
8364         pctx.ino = ino;
8365
8366         /*
8367          * Fix up the bitmaps...
8368          */
8369         e2fsck_read_bitmaps(ctx);
8370         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
8371         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
8372         if (ctx->inode_bad_map)
8373                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8374         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
8375
8376         if (inode.i_file_acl &&
8377             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
8378                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
8379                                                    block_buf, -1, &count);
8380                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
8381                         pctx.errcode = 0;
8382                         count = 1;
8383                 }
8384                 if (pctx.errcode) {
8385                         pctx.blk = inode.i_file_acl;
8386                         fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
8387                         ctx->flags |= E2F_FLAG_ABORT;
8388                         return;
8389                 }
8390                 if (count == 0) {
8391                         ext2fs_unmark_block_bitmap(ctx->block_found_map,
8392                                                    inode.i_file_acl);
8393                         ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
8394                 }
8395                 inode.i_file_acl = 0;
8396         }
8397
8398         if (!ext2fs_inode_has_valid_blocks(&inode))
8399                 return;
8400
8401         if (LINUX_S_ISREG(inode.i_mode) &&
8402             (inode.i_size_high || inode.i_size & 0x80000000UL))
8403                 ctx->large_files--;
8404
8405         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
8406                                             deallocate_inode_block, ctx);
8407         if (pctx.errcode) {
8408                 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
8409                 ctx->flags |= E2F_FLAG_ABORT;
8410                 return;
8411         }
8412 }
8413
8414 /*
8415  * This fuction clears the htree flag on an inode
8416  */
8417 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
8418 {
8419         struct ext2_inode       inode;
8420
8421         e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
8422         inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
8423         e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
8424         if (ctx->dirs_to_hash)
8425                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8426 }
8427
8428
8429 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
8430                                     ext2_ino_t ino, char *buf)
8431 {
8432         ext2_filsys fs = ctx->fs;
8433         struct ext2_inode       inode;
8434         int                     inode_modified = 0;
8435         int                     not_fixed = 0;
8436         unsigned char           *frag, *fsize;
8437         struct problem_context  pctx;
8438         int     problem = 0;
8439
8440         e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
8441
8442         clear_problem_context(&pctx);
8443         pctx.ino = ino;
8444         pctx.dir = dir;
8445         pctx.inode = &inode;
8446
8447         if (inode.i_file_acl &&
8448             !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
8449             fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
8450                 inode.i_file_acl = 0;
8451 #ifdef EXT2FS_ENABLE_SWAPFS
8452                 /*
8453                  * This is a special kludge to deal with long symlinks
8454                  * on big endian systems.  i_blocks had already been
8455                  * decremented earlier in pass 1, but since i_file_acl
8456                  * hadn't yet been cleared, ext2fs_read_inode()
8457                  * assumed that the file was short symlink and would
8458                  * not have byte swapped i_block[0].  Hence, we have
8459                  * to byte-swap it here.
8460                  */
8461                 if (LINUX_S_ISLNK(inode.i_mode) &&
8462                     (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
8463                     (inode.i_blocks == fs->blocksize >> 9))
8464                         inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
8465 #endif
8466                 inode_modified++;
8467         } else
8468                 not_fixed++;
8469
8470         if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
8471             !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
8472             !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
8473             !(LINUX_S_ISSOCK(inode.i_mode)))
8474                 problem = PR_2_BAD_MODE;
8475         else if (LINUX_S_ISCHR(inode.i_mode)
8476                  && !e2fsck_pass1_check_device_inode(fs, &inode))
8477                 problem = PR_2_BAD_CHAR_DEV;
8478         else if (LINUX_S_ISBLK(inode.i_mode)
8479                  && !e2fsck_pass1_check_device_inode(fs, &inode))
8480                 problem = PR_2_BAD_BLOCK_DEV;
8481         else if (LINUX_S_ISFIFO(inode.i_mode)
8482                  && !e2fsck_pass1_check_device_inode(fs, &inode))
8483                 problem = PR_2_BAD_FIFO;
8484         else if (LINUX_S_ISSOCK(inode.i_mode)
8485                  && !e2fsck_pass1_check_device_inode(fs, &inode))
8486                 problem = PR_2_BAD_SOCKET;
8487         else if (LINUX_S_ISLNK(inode.i_mode)
8488                  && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
8489                 problem = PR_2_INVALID_SYMLINK;
8490         }
8491
8492         if (problem) {
8493                 if (fix_problem(ctx, problem, &pctx)) {
8494                         deallocate_inode(ctx, ino, 0);
8495                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8496                                 return 0;
8497                         return 1;
8498                 } else
8499                         not_fixed++;
8500                 problem = 0;
8501         }
8502
8503         if (inode.i_faddr) {
8504                 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
8505                         inode.i_faddr = 0;
8506                         inode_modified++;
8507                 } else
8508                         not_fixed++;
8509         }
8510
8511         switch (fs->super->s_creator_os) {
8512             case EXT2_OS_LINUX:
8513                 frag = &inode.osd2.linux2.l_i_frag;
8514                 fsize = &inode.osd2.linux2.l_i_fsize;
8515                 break;
8516             case EXT2_OS_HURD:
8517                 frag = &inode.osd2.hurd2.h_i_frag;
8518                 fsize = &inode.osd2.hurd2.h_i_fsize;
8519                 break;
8520             case EXT2_OS_MASIX:
8521                 frag = &inode.osd2.masix2.m_i_frag;
8522                 fsize = &inode.osd2.masix2.m_i_fsize;
8523                 break;
8524             default:
8525                 frag = fsize = 0;
8526         }
8527         if (frag && *frag) {
8528                 pctx.num = *frag;
8529                 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
8530                         *frag = 0;
8531                         inode_modified++;
8532                 } else
8533                         not_fixed++;
8534                 pctx.num = 0;
8535         }
8536         if (fsize && *fsize) {
8537                 pctx.num = *fsize;
8538                 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
8539                         *fsize = 0;
8540                         inode_modified++;
8541                 } else
8542                         not_fixed++;
8543                 pctx.num = 0;
8544         }
8545
8546         if (inode.i_file_acl &&
8547             ((inode.i_file_acl < fs->super->s_first_data_block) ||
8548              (inode.i_file_acl >= fs->super->s_blocks_count))) {
8549                 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
8550                         inode.i_file_acl = 0;
8551                         inode_modified++;
8552                 } else
8553                         not_fixed++;
8554         }
8555         if (inode.i_dir_acl &&
8556             LINUX_S_ISDIR(inode.i_mode)) {
8557                 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
8558                         inode.i_dir_acl = 0;
8559                         inode_modified++;
8560                 } else
8561                         not_fixed++;
8562         }
8563
8564         if (inode_modified)
8565                 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
8566         if (!not_fixed)
8567                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8568         return 0;
8569 }
8570
8571
8572 /*
8573  * allocate_dir_block --- this function allocates a new directory
8574  *      block for a particular inode; this is done if a directory has
8575  *      a "hole" in it, or if a directory has a illegal block number
8576  *      that was zeroed out and now needs to be replaced.
8577  */
8578 static int allocate_dir_block(e2fsck_t ctx,
8579                               struct ext2_db_entry *db,
8580                               char *buf EXT2FS_ATTR((unused)),
8581                               struct problem_context *pctx)
8582 {
8583         ext2_filsys fs = ctx->fs;
8584         blk_t                   blk;
8585         char                    *block;
8586         struct ext2_inode       inode;
8587
8588         if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
8589                 return 1;
8590
8591         /*
8592          * Read the inode and block bitmaps in; we'll be messing with
8593          * them.
8594          */
8595         e2fsck_read_bitmaps(ctx);
8596
8597         /*
8598          * First, find a free block
8599          */
8600         pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8601         if (pctx->errcode) {
8602                 pctx->str = "ext2fs_new_block";
8603                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8604                 return 1;
8605         }
8606         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8607         ext2fs_mark_block_bitmap(fs->block_map, blk);
8608         ext2fs_mark_bb_dirty(fs);
8609
8610         /*
8611          * Now let's create the actual data block for the inode
8612          */
8613         if (db->blockcnt)
8614                 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
8615         else
8616                 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
8617                                                      EXT2_ROOT_INO, &block);
8618
8619         if (pctx->errcode) {
8620                 pctx->str = "ext2fs_new_dir_block";
8621                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8622                 return 1;
8623         }
8624
8625         pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
8626         ext2fs_free_mem(&block);
8627         if (pctx->errcode) {
8628                 pctx->str = "ext2fs_write_dir_block";
8629                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8630                 return 1;
8631         }
8632
8633         /*
8634          * Update the inode block count
8635          */
8636         e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
8637         inode.i_blocks += fs->blocksize / 512;
8638         if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
8639                 inode.i_size = (db->blockcnt+1) * fs->blocksize;
8640         e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
8641
8642         /*
8643          * Finally, update the block pointers for the inode
8644          */
8645         db->blk = blk;
8646         pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
8647                                       0, update_dir_block, db);
8648         if (pctx->errcode) {
8649                 pctx->str = "ext2fs_block_iterate";
8650                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8651                 return 1;
8652         }
8653
8654         return 0;
8655 }
8656
8657 /*
8658  * This is a helper function for allocate_dir_block().
8659  */
8660 static int update_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
8661                             blk_t       *block_nr,
8662                             e2_blkcnt_t blockcnt,
8663                             blk_t ref_block EXT2FS_ATTR((unused)),
8664                             int ref_offset EXT2FS_ATTR((unused)),
8665                             void *priv_data)
8666 {
8667         struct ext2_db_entry *db;
8668
8669         db = (struct ext2_db_entry *) priv_data;
8670         if (db->blockcnt == (int) blockcnt) {
8671                 *block_nr = db->blk;
8672                 return BLOCK_CHANGED;
8673         }
8674         return 0;
8675 }
8676 /*
8677  * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
8678  *
8679  * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
8680  *
8681  * %Begin-Header%
8682  * This file may be redistributed under the terms of the GNU Public
8683  * License.
8684  * %End-Header%
8685  *
8686  * Pass #3 assures that all directories are connected to the
8687  * filesystem tree, using the following algorithm:
8688  *
8689  * First, the root directory is checked to make sure it exists; if
8690  * not, e2fsck will offer to create a new one.  It is then marked as
8691  * "done".
8692  *
8693  * Then, pass3 interates over all directory inodes; for each directory
8694  * it attempts to trace up the filesystem tree, using dirinfo.parent
8695  * until it reaches a directory which has been marked "done".  If it
8696  * can not do so, then the directory must be disconnected, and e2fsck
8697  * will offer to reconnect it to /lost+found.  While it is chasing
8698  * parent pointers up the filesystem tree, if pass3 sees a directory
8699  * twice, then it has detected a filesystem loop, and it will again
8700  * offer to reconnect the directory to /lost+found in to break the
8701  * filesystem loop.
8702  *
8703  * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
8704  * reconnect inodes to /lost+found; this subroutine is also used by
8705  * pass 4.  e2fsck_reconnect_file() calls get_lost_and_found(), which
8706  * is responsible for creating /lost+found if it does not exist.
8707  *
8708  * Pass 3 frees the following data structures:
8709  *      - The dirinfo directory information cache.
8710  */
8711
8712 static void check_root(e2fsck_t ctx);
8713 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8714                            struct problem_context *pctx);
8715 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
8716
8717 static ext2fs_inode_bitmap inode_loop_detect = 0;
8718 static ext2fs_inode_bitmap inode_done_map = 0;
8719
8720 void e2fsck_pass3(e2fsck_t ctx)
8721 {
8722         ext2_filsys fs = ctx->fs;
8723         int             i;
8724 #ifdef RESOURCE_TRACK
8725         struct resource_track   rtrack;
8726 #endif
8727         struct problem_context  pctx;
8728         struct dir_info *dir;
8729         unsigned long maxdirs, count;
8730
8731 #ifdef RESOURCE_TRACK
8732         init_resource_track(&rtrack);
8733 #endif
8734
8735         clear_problem_context(&pctx);
8736
8737 #ifdef MTRACE
8738         mtrace_print("Pass 3");
8739 #endif
8740
8741         if (!(ctx->options & E2F_OPT_PREEN))
8742                 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
8743
8744         /*
8745          * Allocate some bitmaps to do loop detection.
8746          */
8747         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
8748                                                     &inode_done_map);
8749         if (pctx.errcode) {
8750                 pctx.num = 2;
8751                 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
8752                 ctx->flags |= E2F_FLAG_ABORT;
8753                 goto abort_exit;
8754         }
8755 #ifdef RESOURCE_TRACK
8756         if (ctx->options & E2F_OPT_TIME) {
8757                 e2fsck_clear_progbar(ctx);
8758                 print_resource_track(_("Peak memory"), &ctx->global_rtrack);
8759         }
8760 #endif
8761
8762         check_root(ctx);
8763         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8764                 goto abort_exit;
8765
8766         ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
8767
8768         maxdirs = e2fsck_get_num_dirinfo(ctx);
8769         count = 1;
8770
8771         if (ctx->progress)
8772                 if ((ctx->progress)(ctx, 3, 0, maxdirs))
8773                         goto abort_exit;
8774
8775         for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
8776                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8777                         goto abort_exit;
8778                 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
8779                         goto abort_exit;
8780                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
8781                         if (check_directory(ctx, dir, &pctx))
8782                                 goto abort_exit;
8783         }
8784
8785         /*
8786          * Force the creation of /lost+found if not present
8787          */
8788         if ((ctx->flags & E2F_OPT_READONLY) == 0)
8789                 e2fsck_get_lost_and_found(ctx, 1);
8790
8791         /*
8792          * If there are any directories that need to be indexed or
8793          * optimized, do it here.
8794          */
8795         e2fsck_rehash_directories(ctx);
8796
8797 abort_exit:
8798         e2fsck_free_dir_info(ctx);
8799         if (inode_loop_detect) {
8800                 ext2fs_free_inode_bitmap(inode_loop_detect);
8801                 inode_loop_detect = 0;
8802         }
8803         if (inode_done_map) {
8804                 ext2fs_free_inode_bitmap(inode_done_map);
8805                 inode_done_map = 0;
8806         }
8807
8808 #ifdef RESOURCE_TRACK
8809         if (ctx->options & E2F_OPT_TIME2) {
8810                 e2fsck_clear_progbar(ctx);
8811                 print_resource_track(_("Pass 3"), &rtrack);
8812         }
8813 #endif
8814 }
8815
8816 /*
8817  * This makes sure the root inode is present; if not, we ask if the
8818  * user wants us to create it.  Not creating it is a fatal error.
8819  */
8820 static void check_root(e2fsck_t ctx)
8821 {
8822         ext2_filsys fs = ctx->fs;
8823         blk_t                   blk;
8824         struct ext2_inode       inode;
8825         char *                  block;
8826         struct problem_context  pctx;
8827
8828         clear_problem_context(&pctx);
8829
8830         if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
8831                 /*
8832                  * If the root inode is not a directory, die here.  The
8833                  * user must have answered 'no' in pass1 when we
8834                  * offered to clear it.
8835                  */
8836                 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8837                                                EXT2_ROOT_INO))) {
8838                         fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
8839                         ctx->flags |= E2F_FLAG_ABORT;
8840                 }
8841                 return;
8842         }
8843
8844         if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
8845                 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
8846                 ctx->flags |= E2F_FLAG_ABORT;
8847                 return;
8848         }
8849
8850         e2fsck_read_bitmaps(ctx);
8851
8852         /*
8853          * First, find a free block
8854          */
8855         pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8856         if (pctx.errcode) {
8857                 pctx.str = "ext2fs_new_block";
8858                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8859                 ctx->flags |= E2F_FLAG_ABORT;
8860                 return;
8861         }
8862         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8863         ext2fs_mark_block_bitmap(fs->block_map, blk);
8864         ext2fs_mark_bb_dirty(fs);
8865
8866         /*
8867          * Now let's create the actual data block for the inode
8868          */
8869         pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
8870                                             &block);
8871         if (pctx.errcode) {
8872                 pctx.str = "ext2fs_new_dir_block";
8873                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8874                 ctx->flags |= E2F_FLAG_ABORT;
8875                 return;
8876         }
8877
8878         pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
8879         if (pctx.errcode) {
8880                 pctx.str = "ext2fs_write_dir_block";
8881                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8882                 ctx->flags |= E2F_FLAG_ABORT;
8883                 return;
8884         }
8885         ext2fs_free_mem(&block);
8886
8887         /*
8888          * Set up the inode structure
8889          */
8890         memset(&inode, 0, sizeof(inode));
8891         inode.i_mode = 040755;
8892         inode.i_size = fs->blocksize;
8893         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8894         inode.i_links_count = 2;
8895         inode.i_blocks = fs->blocksize / 512;
8896         inode.i_block[0] = blk;
8897
8898         /*
8899          * Write out the inode.
8900          */
8901         pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
8902         if (pctx.errcode) {
8903                 pctx.str = "ext2fs_write_inode";
8904                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8905                 ctx->flags |= E2F_FLAG_ABORT;
8906                 return;
8907         }
8908
8909         /*
8910          * Miscellaneous bookkeeping...
8911          */
8912         e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
8913         ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
8914         ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
8915
8916         ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
8917         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
8918         ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
8919         ext2fs_mark_ib_dirty(fs);
8920 }
8921
8922 /*
8923  * This subroutine is responsible for making sure that a particular
8924  * directory is connected to the root; if it isn't we trace it up as
8925  * far as we can go, and then offer to connect the resulting parent to
8926  * the lost+found.  We have to do loop detection; if we ever discover
8927  * a loop, we treat that as a disconnected directory and offer to
8928  * reparent it to lost+found.
8929  *
8930  * However, loop detection is expensive, because for very large
8931  * filesystems, the inode_loop_detect bitmap is huge, and clearing it
8932  * is non-trivial.  Loops in filesystems are also a rare error case,
8933  * and we shouldn't optimize for error cases.  So we try two passes of
8934  * the algorithm.  The first time, we ignore loop detection and merely
8935  * increment a counter; if the counter exceeds some extreme threshold,
8936  * then we try again with the loop detection bitmap enabled.
8937  */
8938 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8939                            struct problem_context *pctx)
8940 {
8941         ext2_filsys     fs = ctx->fs;
8942         struct dir_info *p = dir;
8943         int             loop_pass = 0, parent_count = 0;
8944
8945         if (!p)
8946                 return 0;
8947
8948         while (1) {
8949                 /*
8950                  * Mark this inode as being "done"; by the time we
8951                  * return from this function, the inode we either be
8952                  * verified as being connected to the directory tree,
8953                  * or we will have offered to reconnect this to
8954                  * lost+found.
8955                  *
8956                  * If it was marked done already, then we've reached a
8957                  * parent we've already checked.
8958                  */
8959                 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
8960                         break;
8961
8962                 /*
8963                  * If this directory doesn't have a parent, or we've
8964                  * seen the parent once already, then offer to
8965                  * reparent it to lost+found
8966                  */
8967                 if (!p->parent ||
8968                     (loop_pass &&
8969                      (ext2fs_test_inode_bitmap(inode_loop_detect,
8970                                               p->parent)))) {
8971                         pctx->ino = p->ino;
8972                         if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
8973                                 if (e2fsck_reconnect_file(ctx, pctx->ino))
8974                                         ext2fs_unmark_valid(fs);
8975                                 else {
8976                                         p = e2fsck_get_dir_info(ctx, pctx->ino);
8977                                         p->parent = ctx->lost_and_found;
8978                                         fix_dotdot(ctx, p, ctx->lost_and_found);
8979                                 }
8980                         }
8981                         break;
8982                 }
8983                 p = e2fsck_get_dir_info(ctx, p->parent);
8984                 if (!p) {
8985                         fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
8986                         return 0;
8987                 }
8988                 if (loop_pass) {
8989                         ext2fs_mark_inode_bitmap(inode_loop_detect,
8990                                                  p->ino);
8991                 } else if (parent_count++ > 2048) {
8992                         /*
8993                          * If we've run into a path depth that's
8994                          * greater than 2048, try again with the inode
8995                          * loop bitmap turned on and start from the
8996                          * top.
8997                          */
8998                         loop_pass = 1;
8999                         if (inode_loop_detect)
9000                                 ext2fs_clear_inode_bitmap(inode_loop_detect);
9001                         else {
9002                                 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
9003                                 if (pctx->errcode) {
9004                                         pctx->num = 1;
9005                                         fix_problem(ctx,
9006                                     PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
9007                                         ctx->flags |= E2F_FLAG_ABORT;
9008                                         return -1;
9009                                 }
9010                         }
9011                         p = dir;
9012                 }
9013         }
9014
9015         /*
9016          * Make sure that .. and the parent directory are the same;
9017          * offer to fix it if not.
9018          */
9019         if (dir->parent != dir->dotdot) {
9020                 pctx->ino = dir->ino;
9021                 pctx->ino2 = dir->dotdot;
9022                 pctx->dir = dir->parent;
9023                 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
9024                         fix_dotdot(ctx, dir, dir->parent);
9025         }
9026         return 0;
9027 }
9028
9029 /*
9030  * This routine gets the lost_and_found inode, making it a directory
9031  * if necessary
9032  */
9033 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
9034 {
9035         ext2_filsys fs = ctx->fs;
9036         ext2_ino_t                      ino;
9037         blk_t                   blk;
9038         errcode_t               retval;
9039         struct ext2_inode       inode;
9040         char *                  block;
9041         static const char       name[] = "lost+found";
9042         struct  problem_context pctx;
9043         struct dir_info         *dirinfo;
9044
9045         if (ctx->lost_and_found)
9046                 return ctx->lost_and_found;
9047
9048         clear_problem_context(&pctx);
9049
9050         retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
9051                                sizeof(name)-1, 0, &ino);
9052         if (retval && !fix)
9053                 return 0;
9054         if (!retval) {
9055                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
9056                         ctx->lost_and_found = ino;
9057                         return ino;
9058                 }
9059
9060                 /* Lost+found isn't a directory! */
9061                 if (!fix)
9062                         return 0;
9063                 pctx.ino = ino;
9064                 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
9065                         return 0;
9066
9067                 /* OK, unlink the old /lost+found file. */
9068                 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
9069                 if (pctx.errcode) {
9070                         pctx.str = "ext2fs_unlink";
9071                         fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9072                         return 0;
9073                 }
9074                 dirinfo = e2fsck_get_dir_info(ctx, ino);
9075                 if (dirinfo)
9076                         dirinfo->parent = 0;
9077                 e2fsck_adjust_inode_count(ctx, ino, -1);
9078         } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
9079                 pctx.errcode = retval;
9080                 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
9081         }
9082         if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
9083                 return 0;
9084
9085         /*
9086          * Read the inode and block bitmaps in; we'll be messing with
9087          * them.
9088          */
9089         e2fsck_read_bitmaps(ctx);
9090
9091         /*
9092          * First, find a free block
9093          */
9094         retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
9095         if (retval) {
9096                 pctx.errcode = retval;
9097                 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
9098                 return 0;
9099         }
9100         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
9101         ext2fs_block_alloc_stats(fs, blk, +1);
9102
9103         /*
9104          * Next find a free inode.
9105          */
9106         retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
9107                                   ctx->inode_used_map, &ino);
9108         if (retval) {
9109                 pctx.errcode = retval;
9110                 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
9111                 return 0;
9112         }
9113         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
9114         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
9115         ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
9116
9117         /*
9118          * Now let's create the actual data block for the inode
9119          */
9120         retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
9121         if (retval) {
9122                 pctx.errcode = retval;
9123                 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
9124                 return 0;
9125         }
9126
9127         retval = ext2fs_write_dir_block(fs, blk, block);
9128         ext2fs_free_mem(&block);
9129         if (retval) {
9130                 pctx.errcode = retval;
9131                 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
9132                 return 0;
9133         }
9134
9135         /*
9136          * Set up the inode structure
9137          */
9138         memset(&inode, 0, sizeof(inode));
9139         inode.i_mode = 040700;
9140         inode.i_size = fs->blocksize;
9141         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
9142         inode.i_links_count = 2;
9143         inode.i_blocks = fs->blocksize / 512;
9144         inode.i_block[0] = blk;
9145
9146         /*
9147          * Next, write out the inode.
9148          */
9149         pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
9150         if (pctx.errcode) {
9151                 pctx.str = "ext2fs_write_inode";
9152                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9153                 return 0;
9154         }
9155         /*
9156          * Finally, create the directory link
9157          */
9158         pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
9159         if (pctx.errcode) {
9160                 pctx.str = "ext2fs_link";
9161                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9162                 return 0;
9163         }
9164
9165         /*
9166          * Miscellaneous bookkeeping that needs to be kept straight.
9167          */
9168         e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
9169         e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
9170         ext2fs_icount_store(ctx->inode_count, ino, 2);
9171         ext2fs_icount_store(ctx->inode_link_info, ino, 2);
9172         ctx->lost_and_found = ino;
9173 #if 0
9174         printf("/lost+found created; inode #%lu\n", ino);
9175 #endif
9176         return ino;
9177 }
9178
9179 /*
9180  * This routine will connect a file to lost+found
9181  */
9182 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
9183 {
9184         ext2_filsys fs = ctx->fs;
9185         errcode_t       retval;
9186         char            name[80];
9187         struct problem_context  pctx;
9188         struct ext2_inode       inode;
9189         int             file_type = 0;
9190
9191         clear_problem_context(&pctx);
9192         pctx.ino = ino;
9193
9194         if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
9195                 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
9196                         ctx->bad_lost_and_found++;
9197         }
9198         if (ctx->bad_lost_and_found) {
9199                 fix_problem(ctx, PR_3_NO_LPF, &pctx);
9200                 return 1;
9201         }
9202
9203         sprintf(name, "#%u", ino);
9204         if (ext2fs_read_inode(fs, ino, &inode) == 0)
9205                 file_type = ext2_file_type(inode.i_mode);
9206         retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
9207         if (retval == EXT2_ET_DIR_NO_SPACE) {
9208                 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
9209                         return 1;
9210                 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
9211                                                  1, 0);
9212                 if (retval) {
9213                         pctx.errcode = retval;
9214                         fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
9215                         return 1;
9216                 }
9217                 retval = ext2fs_link(fs, ctx->lost_and_found, name,
9218                                      ino, file_type);
9219         }
9220         if (retval) {
9221                 pctx.errcode = retval;
9222                 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
9223                 return 1;
9224         }
9225         e2fsck_adjust_inode_count(ctx, ino, 1);
9226
9227         return 0;
9228 }
9229
9230 /*
9231  * Utility routine to adjust the inode counts on an inode.
9232  */
9233 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
9234 {
9235         ext2_filsys fs = ctx->fs;
9236         errcode_t               retval;
9237         struct ext2_inode       inode;
9238
9239         if (!ino)
9240                 return 0;
9241
9242         retval = ext2fs_read_inode(fs, ino, &inode);
9243         if (retval)
9244                 return retval;
9245
9246 #if 0
9247         printf("Adjusting link count for inode %lu by %d (from %d)\n", ino, adj,
9248                inode.i_links_count);
9249 #endif
9250
9251         if (adj == 1) {
9252                 ext2fs_icount_increment(ctx->inode_count, ino, 0);
9253                 if (inode.i_links_count == (__u16) ~0)
9254                         return 0;
9255                 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
9256                 inode.i_links_count++;
9257         } else if (adj == -1) {
9258                 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
9259                 if (inode.i_links_count == 0)
9260                         return 0;
9261                 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
9262                 inode.i_links_count--;
9263         }
9264
9265         retval = ext2fs_write_inode(fs, ino, &inode);
9266         if (retval)
9267                 return retval;
9268
9269         return 0;
9270 }
9271
9272 /*
9273  * Fix parent --- this routine fixes up the parent of a directory.
9274  */
9275 struct fix_dotdot_struct {
9276         ext2_filsys     fs;
9277         ext2_ino_t      parent;
9278         int             done;
9279         e2fsck_t        ctx;
9280 };
9281
9282 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
9283                            int  offset EXT2FS_ATTR((unused)),
9284                            int  blocksize EXT2FS_ATTR((unused)),
9285                            char *buf EXT2FS_ATTR((unused)),
9286                            void *priv_data)
9287 {
9288         struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
9289         errcode_t       retval;
9290         struct problem_context pctx;
9291
9292         if ((dirent->name_len & 0xFF) != 2)
9293                 return 0;
9294         if (strncmp(dirent->name, "..", 2))
9295                 return 0;
9296
9297         clear_problem_context(&pctx);
9298
9299         retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
9300         if (retval) {
9301                 pctx.errcode = retval;
9302                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9303         }
9304         retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
9305         if (retval) {
9306                 pctx.errcode = retval;
9307                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9308         }
9309         dirent->inode = fp->parent;
9310
9311         fp->done++;
9312         return DIRENT_ABORT | DIRENT_CHANGED;
9313 }
9314
9315 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
9316 {
9317         ext2_filsys fs = ctx->fs;
9318         errcode_t       retval;
9319         struct fix_dotdot_struct fp;
9320         struct problem_context pctx;
9321
9322         fp.fs = fs;
9323         fp.parent = parent;
9324         fp.done = 0;
9325         fp.ctx = ctx;
9326
9327 #if 0
9328         printf("Fixing '..' of inode %lu to be %lu...\n", dir->ino, parent);
9329 #endif
9330
9331         retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
9332                                     0, fix_dotdot_proc, &fp);
9333         if (retval || !fp.done) {
9334                 clear_problem_context(&pctx);
9335                 pctx.ino = dir->ino;
9336                 pctx.errcode = retval;
9337                 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
9338                             PR_3_FIX_PARENT_NOFIND, &pctx);
9339                 ext2fs_unmark_valid(fs);
9340         }
9341         dir->dotdot = parent;
9342
9343         return;
9344 }
9345
9346 /*
9347  * These routines are responsible for expanding a /lost+found if it is
9348  * too small.
9349  */
9350
9351 struct expand_dir_struct {
9352         int                     num;
9353         int                     guaranteed_size;
9354         int                     newblocks;
9355         int                     last_block;
9356         errcode_t               err;
9357         e2fsck_t                ctx;
9358 };
9359
9360 static int expand_dir_proc(ext2_filsys fs,
9361                            blk_t        *blocknr,
9362                            e2_blkcnt_t  blockcnt,
9363                            blk_t ref_block EXT2FS_ATTR((unused)),
9364                            int ref_offset EXT2FS_ATTR((unused)),
9365                            void *priv_data)
9366 {
9367         struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
9368         blk_t   new_blk;
9369         static blk_t    last_blk = 0;
9370         char            *block;
9371         errcode_t       retval;
9372         e2fsck_t        ctx;
9373
9374         ctx = es->ctx;
9375
9376         if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
9377                 return BLOCK_ABORT;
9378
9379         if (blockcnt > 0)
9380                 es->last_block = blockcnt;
9381         if (*blocknr) {
9382                 last_blk = *blocknr;
9383                 return 0;
9384         }
9385         retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
9386                                   &new_blk);
9387         if (retval) {
9388                 es->err = retval;
9389                 return BLOCK_ABORT;
9390         }
9391         if (blockcnt > 0) {
9392                 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
9393                 if (retval) {
9394                         es->err = retval;
9395                         return BLOCK_ABORT;
9396                 }
9397                 es->num--;
9398                 retval = ext2fs_write_dir_block(fs, new_blk, block);
9399         } else {
9400                 retval = ext2fs_get_mem(fs->blocksize, &block);
9401                 if (retval) {
9402                         es->err = retval;
9403                         return BLOCK_ABORT;
9404                 }
9405                 memset(block, 0, fs->blocksize);
9406                 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
9407         }
9408         if (retval) {
9409                 es->err = retval;
9410                 return BLOCK_ABORT;
9411         }
9412         ext2fs_free_mem(&block);
9413         *blocknr = new_blk;
9414         ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
9415         ext2fs_block_alloc_stats(fs, new_blk, +1);
9416         es->newblocks++;
9417
9418         if (es->num == 0)
9419                 return (BLOCK_CHANGED | BLOCK_ABORT);
9420         else
9421                 return BLOCK_CHANGED;
9422 }
9423
9424 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
9425                                   int num, int guaranteed_size)
9426 {
9427         ext2_filsys fs = ctx->fs;
9428         errcode_t       retval;
9429         struct expand_dir_struct es;
9430         struct ext2_inode       inode;
9431
9432         if (!(fs->flags & EXT2_FLAG_RW))
9433                 return EXT2_ET_RO_FILSYS;
9434
9435         /*
9436          * Read the inode and block bitmaps in; we'll be messing with
9437          * them.
9438          */
9439         e2fsck_read_bitmaps(ctx);
9440
9441         retval = ext2fs_check_directory(fs, dir);
9442         if (retval)
9443                 return retval;
9444
9445         es.num = num;
9446         es.guaranteed_size = guaranteed_size;
9447         es.last_block = 0;
9448         es.err = 0;
9449         es.newblocks = 0;
9450         es.ctx = ctx;
9451
9452         retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
9453                                        0, expand_dir_proc, &es);
9454
9455         if (es.err)
9456                 return es.err;
9457
9458         /*
9459          * Update the size and block count fields in the inode.
9460          */
9461         retval = ext2fs_read_inode(fs, dir, &inode);
9462         if (retval)
9463                 return retval;
9464
9465         inode.i_size = (es.last_block + 1) * fs->blocksize;
9466         inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
9467
9468         e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
9469
9470         return 0;
9471 }
9472
9473 /*
9474  * pass4.c -- pass #4 of e2fsck: Check reference counts
9475  *
9476  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
9477  *
9478  * %Begin-Header%
9479  * This file may be redistributed under the terms of the GNU Public
9480  * License.
9481  * %End-Header%
9482  *
9483  * Pass 4 frees the following data structures:
9484  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
9485  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
9486  */
9487
9488 /*
9489  * This routine is called when an inode is not connected to the
9490  * directory tree.
9491  *
9492  * This subroutine returns 1 then the caller shouldn't bother with the
9493  * rest of the pass 4 tests.
9494  */
9495 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
9496 {
9497         ext2_filsys fs = ctx->fs;
9498         struct ext2_inode       inode;
9499         struct problem_context  pctx;
9500
9501         e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
9502         clear_problem_context(&pctx);
9503         pctx.ino = i;
9504         pctx.inode = &inode;
9505
9506         /*
9507          * Offer to delete any zero-length files that does not have
9508          * blocks.  If there is an EA block, it might have useful
9509          * information, so we won't prompt to delete it, but let it be
9510          * reconnected to lost+found.
9511          */
9512         if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
9513                                 LINUX_S_ISDIR(inode.i_mode))) {
9514                 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
9515                         ext2fs_icount_store(ctx->inode_link_info, i, 0);
9516                         inode.i_links_count = 0;
9517                         inode.i_dtime = time(0);
9518                         e2fsck_write_inode(ctx, i, &inode,
9519                                            "disconnect_inode");
9520                         /*
9521                          * Fix up the bitmaps...
9522                          */
9523                         e2fsck_read_bitmaps(ctx);
9524                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
9525                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
9526                         ext2fs_inode_alloc_stats2(fs, i, -1,
9527                                                   LINUX_S_ISDIR(inode.i_mode));
9528                         return 0;
9529                 }
9530         }
9531
9532         /*
9533          * Prompt to reconnect.
9534          */
9535         if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
9536                 if (e2fsck_reconnect_file(ctx, i))
9537                         ext2fs_unmark_valid(fs);
9538         } else {
9539                 /*
9540                  * If we don't attach the inode, then skip the
9541                  * i_links_test since there's no point in trying to
9542                  * force i_links_count to zero.
9543                  */
9544                 ext2fs_unmark_valid(fs);
9545                 return 1;
9546         }
9547         return 0;
9548 }
9549
9550
9551 void e2fsck_pass4(e2fsck_t ctx)
9552 {
9553         ext2_filsys fs = ctx->fs;
9554         ext2_ino_t      i;
9555         struct ext2_inode       inode;
9556 #ifdef RESOURCE_TRACK
9557         struct resource_track   rtrack;
9558 #endif
9559         struct problem_context  pctx;
9560         __u16   link_count, link_counted;
9561         char    *buf = 0;
9562         int     group, maxgroup;
9563
9564 #ifdef RESOURCE_TRACK
9565         init_resource_track(&rtrack);
9566 #endif
9567
9568 #ifdef MTRACE
9569         mtrace_print("Pass 4");
9570 #endif
9571
9572         clear_problem_context(&pctx);
9573
9574         if (!(ctx->options & E2F_OPT_PREEN))
9575                 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
9576
9577         group = 0;
9578         maxgroup = fs->group_desc_count;
9579         if (ctx->progress)
9580                 if ((ctx->progress)(ctx, 4, 0, maxgroup))
9581                         return;
9582
9583         for (i=1; i <= fs->super->s_inodes_count; i++) {
9584                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9585                         return;
9586                 if ((i % fs->super->s_inodes_per_group) == 0) {
9587                         group++;
9588                         if (ctx->progress)
9589                                 if ((ctx->progress)(ctx, 4, group, maxgroup))
9590                                         return;
9591                 }
9592                 if (i == EXT2_BAD_INO ||
9593                     (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
9594                         continue;
9595                 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
9596                     (ctx->inode_imagic_map &&
9597                      ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
9598                     (ctx->inode_bb_map &&
9599                      ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
9600                         continue;
9601                 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
9602                 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
9603                 if (link_counted == 0) {
9604                         if (!buf)
9605                                 buf = e2fsck_allocate_memory(ctx,
9606                                      fs->blocksize, "bad_inode buffer");
9607                         if (e2fsck_process_bad_inode(ctx, 0, i, buf))
9608                                 continue;
9609                         if (disconnect_inode(ctx, i))
9610                                 continue;
9611                         ext2fs_icount_fetch(ctx->inode_link_info, i,
9612                                             &link_count);
9613                         ext2fs_icount_fetch(ctx->inode_count, i,
9614                                             &link_counted);
9615                 }
9616                 if (link_counted != link_count) {
9617                         e2fsck_read_inode(ctx, i, &inode, "pass4");
9618                         pctx.ino = i;
9619                         pctx.inode = &inode;
9620                         if (link_count != inode.i_links_count) {
9621                                 pctx.num = link_count;
9622                                 fix_problem(ctx,
9623                                             PR_4_INCONSISTENT_COUNT, &pctx);
9624                         }
9625                         pctx.num = link_counted;
9626                         if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
9627                                 inode.i_links_count = link_counted;
9628                                 e2fsck_write_inode(ctx, i, &inode, "pass4");
9629                         }
9630                 }
9631         }
9632         ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
9633         ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
9634         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
9635         ctx->inode_bb_map = 0;
9636         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
9637         ctx->inode_imagic_map = 0;
9638         if (buf)
9639                 ext2fs_free_mem(&buf);
9640 #ifdef RESOURCE_TRACK
9641         if (ctx->options & E2F_OPT_TIME2) {
9642                 e2fsck_clear_progbar(ctx);
9643                 print_resource_track(_("Pass 4"), &rtrack);
9644         }
9645 #endif
9646 }
9647
9648 /*
9649  * pass5.c --- check block and inode bitmaps against on-disk bitmaps
9650  *
9651  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
9652  *
9653  * %Begin-Header%
9654  * This file may be redistributed under the terms of the GNU Public
9655  * License.
9656  * %End-Header%
9657  *
9658  */
9659
9660 static void check_block_bitmaps(e2fsck_t ctx);
9661 static void check_inode_bitmaps(e2fsck_t ctx);
9662 static void check_inode_end(e2fsck_t ctx);
9663 static void check_block_end(e2fsck_t ctx);
9664
9665 void e2fsck_pass5(e2fsck_t ctx)
9666 {
9667 #ifdef RESOURCE_TRACK
9668         struct resource_track   rtrack;
9669 #endif
9670         struct problem_context  pctx;
9671
9672 #ifdef MTRACE
9673         mtrace_print("Pass 5");
9674 #endif
9675
9676 #ifdef RESOURCE_TRACK
9677         init_resource_track(&rtrack);
9678 #endif
9679
9680         clear_problem_context(&pctx);
9681
9682         if (!(ctx->options & E2F_OPT_PREEN))
9683                 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
9684
9685         if (ctx->progress)
9686                 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
9687                         return;
9688
9689         e2fsck_read_bitmaps(ctx);
9690
9691         check_block_bitmaps(ctx);
9692         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9693                 return;
9694         check_inode_bitmaps(ctx);
9695         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9696                 return;
9697         check_inode_end(ctx);
9698         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9699                 return;
9700         check_block_end(ctx);
9701         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9702                 return;
9703
9704         ext2fs_free_inode_bitmap(ctx->inode_used_map);
9705         ctx->inode_used_map = 0;
9706         ext2fs_free_inode_bitmap(ctx->inode_dir_map);
9707         ctx->inode_dir_map = 0;
9708         ext2fs_free_block_bitmap(ctx->block_found_map);
9709         ctx->block_found_map = 0;
9710
9711 #ifdef RESOURCE_TRACK
9712         if (ctx->options & E2F_OPT_TIME2) {
9713                 e2fsck_clear_progbar(ctx);
9714                 print_resource_track(_("Pass 5"), &rtrack);
9715         }
9716 #endif
9717 }
9718
9719 #define NO_BLK ((blk_t) -1)
9720
9721 static void print_bitmap_problem(e2fsck_t ctx, int problem,
9722                             struct problem_context *pctx)
9723 {
9724         switch (problem) {
9725         case PR_5_BLOCK_UNUSED:
9726                 if (pctx->blk == pctx->blk2)
9727                         pctx->blk2 = 0;
9728                 else
9729                         problem = PR_5_BLOCK_RANGE_UNUSED;
9730                 break;
9731         case PR_5_BLOCK_USED:
9732                 if (pctx->blk == pctx->blk2)
9733                         pctx->blk2 = 0;
9734                 else
9735                         problem = PR_5_BLOCK_RANGE_USED;
9736                 break;
9737         case PR_5_INODE_UNUSED:
9738                 if (pctx->ino == pctx->ino2)
9739                         pctx->ino2 = 0;
9740                 else
9741                         problem = PR_5_INODE_RANGE_UNUSED;
9742                 break;
9743         case PR_5_INODE_USED:
9744                 if (pctx->ino == pctx->ino2)
9745                         pctx->ino2 = 0;
9746                 else
9747                         problem = PR_5_INODE_RANGE_USED;
9748                 break;
9749         }
9750         fix_problem(ctx, problem, pctx);
9751         pctx->blk = pctx->blk2 = NO_BLK;
9752         pctx->ino = pctx->ino2 = 0;
9753 }
9754
9755 static void check_block_bitmaps(e2fsck_t ctx)
9756 {
9757         ext2_filsys fs = ctx->fs;
9758         blk_t   i;
9759         int     *free_array;
9760         int     group = 0;
9761         unsigned int    blocks = 0;
9762         unsigned int    free_blocks = 0;
9763         int     group_free = 0;
9764         int     actual, bitmap;
9765         struct problem_context  pctx;
9766         int     problem, save_problem, fixit, had_problem;
9767         errcode_t       retval;
9768
9769         clear_problem_context(&pctx);
9770         free_array = (int *) e2fsck_allocate_memory(ctx,
9771             fs->group_desc_count * sizeof(int), "free block count array");
9772
9773         if ((fs->super->s_first_data_block <
9774              ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
9775             (fs->super->s_blocks_count-1 >
9776              ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
9777                 pctx.num = 1;
9778                 pctx.blk = fs->super->s_first_data_block;
9779                 pctx.blk2 = fs->super->s_blocks_count -1;
9780                 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
9781                 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
9782                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9783
9784                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9785                 return;
9786         }
9787
9788         if ((fs->super->s_first_data_block <
9789              ext2fs_get_block_bitmap_start(fs->block_map)) ||
9790             (fs->super->s_blocks_count-1 >
9791              ext2fs_get_block_bitmap_end(fs->block_map))) {
9792                 pctx.num = 2;
9793                 pctx.blk = fs->super->s_first_data_block;
9794                 pctx.blk2 = fs->super->s_blocks_count -1;
9795                 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
9796                 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
9797                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9798
9799                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9800                 return;
9801         }
9802
9803 redo_counts:
9804         had_problem = 0;
9805         save_problem = 0;
9806         pctx.blk = pctx.blk2 = NO_BLK;
9807         for (i = fs->super->s_first_data_block;
9808              i < fs->super->s_blocks_count;
9809              i++) {
9810                 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
9811                 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
9812
9813                 if (actual == bitmap)
9814                         goto do_counts;
9815
9816                 if (!actual && bitmap) {
9817                         /*
9818                          * Block not used, but marked in use in the bitmap.
9819                          */
9820                         problem = PR_5_BLOCK_UNUSED;
9821                 } else {
9822                         /*
9823                          * Block used, but not marked in use in the bitmap.
9824                          */
9825                         problem = PR_5_BLOCK_USED;
9826                 }
9827                 if (pctx.blk == NO_BLK) {
9828                         pctx.blk = pctx.blk2 = i;
9829                         save_problem = problem;
9830                 } else {
9831                         if ((problem == save_problem) &&
9832                             (pctx.blk2 == i-1))
9833                                 pctx.blk2++;
9834                         else {
9835                                 print_bitmap_problem(ctx, save_problem, &pctx);
9836                                 pctx.blk = pctx.blk2 = i;
9837                                 save_problem = problem;
9838                         }
9839                 }
9840                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9841                 had_problem++;
9842
9843         do_counts:
9844                 if (!bitmap) {
9845                         group_free++;
9846                         free_blocks++;
9847                 }
9848                 blocks ++;
9849                 if ((blocks == fs->super->s_blocks_per_group) ||
9850                     (i == fs->super->s_blocks_count-1)) {
9851                         free_array[group] = group_free;
9852                         group ++;
9853                         blocks = 0;
9854                         group_free = 0;
9855                         if (ctx->progress)
9856                                 if ((ctx->progress)(ctx, 5, group,
9857                                                     fs->group_desc_count*2))
9858                                         return;
9859                 }
9860         }
9861         if (pctx.blk != NO_BLK)
9862                 print_bitmap_problem(ctx, save_problem, &pctx);
9863         if (had_problem)
9864                 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
9865         else
9866                 fixit = -1;
9867         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9868
9869         if (fixit == 1) {
9870                 ext2fs_free_block_bitmap(fs->block_map);
9871                 retval = ext2fs_copy_bitmap(ctx->block_found_map,
9872                                                   &fs->block_map);
9873                 if (retval) {
9874                         clear_problem_context(&pctx);
9875                         fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
9876                         ctx->flags |= E2F_FLAG_ABORT;
9877                         return;
9878                 }
9879                 ext2fs_set_bitmap_padding(fs->block_map);
9880                 ext2fs_mark_bb_dirty(fs);
9881
9882                 /* Redo the counts */
9883                 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
9884                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9885                 goto redo_counts;
9886         } else if (fixit == 0)
9887                 ext2fs_unmark_valid(fs);
9888
9889         for (i = 0; i < fs->group_desc_count; i++) {
9890                 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
9891                         pctx.group = i;
9892                         pctx.blk = fs->group_desc[i].bg_free_blocks_count;
9893                         pctx.blk2 = free_array[i];
9894
9895                         if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
9896                                         &pctx)) {
9897                                 fs->group_desc[i].bg_free_blocks_count =
9898                                         free_array[i];
9899                                 ext2fs_mark_super_dirty(fs);
9900                         } else
9901                                 ext2fs_unmark_valid(fs);
9902                 }
9903         }
9904         if (free_blocks != fs->super->s_free_blocks_count) {
9905                 pctx.group = 0;
9906                 pctx.blk = fs->super->s_free_blocks_count;
9907                 pctx.blk2 = free_blocks;
9908
9909                 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
9910                         fs->super->s_free_blocks_count = free_blocks;
9911                         ext2fs_mark_super_dirty(fs);
9912                 } else
9913                         ext2fs_unmark_valid(fs);
9914         }
9915         ext2fs_free_mem(&free_array);
9916 }
9917
9918 static void check_inode_bitmaps(e2fsck_t ctx)
9919 {
9920         ext2_filsys fs = ctx->fs;
9921         ext2_ino_t      i;
9922         unsigned int    free_inodes = 0;
9923         int             group_free = 0;
9924         int             dirs_count = 0;
9925         int             group = 0;
9926         unsigned int    inodes = 0;
9927         int             *free_array;
9928         int             *dir_array;
9929         int             actual, bitmap;
9930         errcode_t       retval;
9931         struct problem_context  pctx;
9932         int             problem, save_problem, fixit, had_problem;
9933
9934         clear_problem_context(&pctx);
9935         free_array = (int *) e2fsck_allocate_memory(ctx,
9936             fs->group_desc_count * sizeof(int), "free inode count array");
9937
9938         dir_array = (int *) e2fsck_allocate_memory(ctx,
9939            fs->group_desc_count * sizeof(int), "directory count array");
9940
9941         if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
9942             (fs->super->s_inodes_count >
9943              ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
9944                 pctx.num = 3;
9945                 pctx.blk = 1;
9946                 pctx.blk2 = fs->super->s_inodes_count;
9947                 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
9948                 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
9949                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9950
9951                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9952                 return;
9953         }
9954         if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
9955             (fs->super->s_inodes_count >
9956              ext2fs_get_inode_bitmap_end(fs->inode_map))) {
9957                 pctx.num = 4;
9958                 pctx.blk = 1;
9959                 pctx.blk2 = fs->super->s_inodes_count;
9960                 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
9961                 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
9962                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9963
9964                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9965                 return;
9966         }
9967
9968 redo_counts:
9969         had_problem = 0;
9970         save_problem = 0;
9971         pctx.ino = pctx.ino2 = 0;
9972         for (i = 1; i <= fs->super->s_inodes_count; i++) {
9973                 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
9974                 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
9975
9976                 if (actual == bitmap)
9977                         goto do_counts;
9978
9979                 if (!actual && bitmap) {
9980                         /*
9981                          * Inode wasn't used, but marked in bitmap
9982                          */
9983                         problem = PR_5_INODE_UNUSED;
9984                 } else /* if (actual && !bitmap) */ {
9985                         /*
9986                          * Inode used, but not in bitmap
9987                          */
9988                         problem = PR_5_INODE_USED;
9989                 }
9990                 if (pctx.ino == 0) {
9991                         pctx.ino = pctx.ino2 = i;
9992                         save_problem = problem;
9993                 } else {
9994                         if ((problem == save_problem) &&
9995                             (pctx.ino2 == i-1))
9996                                 pctx.ino2++;
9997                         else {
9998                                 print_bitmap_problem(ctx, save_problem, &pctx);
9999                                 pctx.ino = pctx.ino2 = i;
10000                                 save_problem = problem;
10001                         }
10002                 }
10003                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
10004                 had_problem++;
10005
10006 do_counts:
10007                 if (!bitmap) {
10008                         group_free++;
10009                         free_inodes++;
10010                 } else {
10011                         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
10012                                 dirs_count++;
10013                 }
10014                 inodes++;
10015                 if ((inodes == fs->super->s_inodes_per_group) ||
10016                     (i == fs->super->s_inodes_count)) {
10017                         free_array[group] = group_free;
10018                         dir_array[group] = dirs_count;
10019                         group ++;
10020                         inodes = 0;
10021                         group_free = 0;
10022                         dirs_count = 0;
10023                         if (ctx->progress)
10024                                 if ((ctx->progress)(ctx, 5,
10025                                             group + fs->group_desc_count,
10026                                             fs->group_desc_count*2))
10027                                         return;
10028                 }
10029         }
10030         if (pctx.ino)
10031                 print_bitmap_problem(ctx, save_problem, &pctx);
10032
10033         if (had_problem)
10034                 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
10035         else
10036                 fixit = -1;
10037         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
10038
10039         if (fixit == 1) {
10040                 ext2fs_free_inode_bitmap(fs->inode_map);
10041                 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
10042                                                   &fs->inode_map);
10043                 if (retval) {
10044                         clear_problem_context(&pctx);
10045                         fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
10046                         ctx->flags |= E2F_FLAG_ABORT;
10047                         return;
10048                 }
10049                 ext2fs_set_bitmap_padding(fs->inode_map);
10050                 ext2fs_mark_ib_dirty(fs);
10051
10052                 /* redo counts */
10053                 inodes = 0; free_inodes = 0; group_free = 0;
10054                 dirs_count = 0; group = 0;
10055                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
10056                 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
10057                 goto redo_counts;
10058         } else if (fixit == 0)
10059                 ext2fs_unmark_valid(fs);
10060
10061         for (i = 0; i < fs->group_desc_count; i++) {
10062                 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
10063                         pctx.group = i;
10064                         pctx.ino = fs->group_desc[i].bg_free_inodes_count;
10065                         pctx.ino2 = free_array[i];
10066                         if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
10067                                         &pctx)) {
10068                                 fs->group_desc[i].bg_free_inodes_count =
10069                                         free_array[i];
10070                                 ext2fs_mark_super_dirty(fs);
10071                         } else
10072                                 ext2fs_unmark_valid(fs);
10073                 }
10074                 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
10075                         pctx.group = i;
10076                         pctx.ino = fs->group_desc[i].bg_used_dirs_count;
10077                         pctx.ino2 = dir_array[i];
10078
10079                         if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
10080                                         &pctx)) {
10081                                 fs->group_desc[i].bg_used_dirs_count =
10082                                         dir_array[i];
10083                                 ext2fs_mark_super_dirty(fs);
10084                         } else
10085                                 ext2fs_unmark_valid(fs);
10086                 }
10087         }
10088         if (free_inodes != fs->super->s_free_inodes_count) {
10089                 pctx.group = -1;
10090                 pctx.ino = fs->super->s_free_inodes_count;
10091                 pctx.ino2 = free_inodes;
10092
10093                 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
10094                         fs->super->s_free_inodes_count = free_inodes;
10095                         ext2fs_mark_super_dirty(fs);
10096                 } else
10097                         ext2fs_unmark_valid(fs);
10098         }
10099         ext2fs_free_mem(&free_array);
10100         ext2fs_free_mem(&dir_array);
10101 }
10102
10103 static void check_inode_end(e2fsck_t ctx)
10104 {
10105         ext2_filsys fs = ctx->fs;
10106         ext2_ino_t      end, save_inodes_count, i;
10107         struct problem_context  pctx;
10108
10109         clear_problem_context(&pctx);
10110
10111         end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
10112         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
10113                                                      &save_inodes_count);
10114         if (pctx.errcode) {
10115                 pctx.num = 1;
10116                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10117                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10118                 return;
10119         }
10120         if (save_inodes_count == end)
10121                 return;
10122
10123         for (i = save_inodes_count + 1; i <= end; i++) {
10124                 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
10125                         if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
10126                                 for (i = save_inodes_count + 1; i <= end; i++)
10127                                         ext2fs_mark_inode_bitmap(fs->inode_map,
10128                                                                  i);
10129                                 ext2fs_mark_ib_dirty(fs);
10130                         } else
10131                                 ext2fs_unmark_valid(fs);
10132                         break;
10133                 }
10134         }
10135
10136         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
10137                                                      save_inodes_count, 0);
10138         if (pctx.errcode) {
10139                 pctx.num = 2;
10140                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10141                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10142                 return;
10143         }
10144 }
10145
10146 static void check_block_end(e2fsck_t ctx)
10147 {
10148         ext2_filsys fs = ctx->fs;
10149         blk_t   end, save_blocks_count, i;
10150         struct problem_context  pctx;
10151
10152         clear_problem_context(&pctx);
10153
10154         end = fs->block_map->start +
10155                 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
10156         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
10157                                                      &save_blocks_count);
10158         if (pctx.errcode) {
10159                 pctx.num = 3;
10160                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10161                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10162                 return;
10163         }
10164         if (save_blocks_count == end)
10165                 return;
10166
10167         for (i = save_blocks_count + 1; i <= end; i++) {
10168                 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
10169                         if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
10170                                 for (i = save_blocks_count + 1; i <= end; i++)
10171                                         ext2fs_mark_block_bitmap(fs->block_map,
10172                                                                  i);
10173                                 ext2fs_mark_bb_dirty(fs);
10174                         } else
10175                                 ext2fs_unmark_valid(fs);
10176                         break;
10177                 }
10178         }
10179
10180         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
10181                                                      save_blocks_count, 0);
10182         if (pctx.errcode) {
10183                 pctx.num = 4;
10184                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10185                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10186                 return;
10187         }
10188 }
10189
10190
10191
10192 /*
10193  * problem.c --- report filesystem problems to the user
10194  *
10195  * Copyright 1996, 1997 by Theodore Ts'o
10196  *
10197  * %Begin-Header%
10198  * This file may be redistributed under the terms of the GNU Public
10199  * License.
10200  * %End-Header%
10201  */
10202
10203 #define PR_PREEN_OK     0x000001 /* Don't need to do preenhalt */
10204 #define PR_NO_OK        0x000002 /* If user answers no, don't make fs invalid */
10205 #define PR_NO_DEFAULT   0x000004 /* Default to no */
10206 #define PR_MSG_ONLY     0x000008 /* Print message only */
10207
10208 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
10209
10210 #define PR_FATAL        0x001000 /* Fatal error */
10211 #define PR_AFTER_CODE   0x002000 /* After asking the first question, */
10212                                  /* ask another */
10213 #define PR_PREEN_NOMSG  0x004000 /* Don't print a message if we're preening */
10214 #define PR_NOCOLLATE    0x008000 /* Don't collate answers for this latch */
10215 #define PR_NO_NOMSG     0x010000 /* Don't print a message if e2fsck -n */
10216 #define PR_PREEN_NO     0x020000 /* Use No as an answer if preening */
10217 #define PR_PREEN_NOHDR  0x040000 /* Don't print the preen header */
10218
10219
10220 #define PROMPT_NONE     0
10221 #define PROMPT_FIX      1
10222 #define PROMPT_CLEAR    2
10223 #define PROMPT_RELOCATE 3
10224 #define PROMPT_ALLOCATE 4
10225 #define PROMPT_EXPAND   5
10226 #define PROMPT_CONNECT  6
10227 #define PROMPT_CREATE   7
10228 #define PROMPT_SALVAGE  8
10229 #define PROMPT_TRUNCATE 9
10230 #define PROMPT_CLEAR_INODE 10
10231 #define PROMPT_ABORT    11
10232 #define PROMPT_SPLIT    12
10233 #define PROMPT_CONTINUE 13
10234 #define PROMPT_CLONE    14
10235 #define PROMPT_DELETE   15
10236 #define PROMPT_SUPPRESS 16
10237 #define PROMPT_UNLINK   17
10238 #define PROMPT_CLEAR_HTREE 18
10239 #define PROMPT_RECREATE 19
10240 #define PROMPT_NULL     20
10241
10242 struct e2fsck_problem {
10243         problem_t       e2p_code;
10244         const char *    e2p_description;
10245         char            prompt;
10246         int             flags;
10247         problem_t       second_code;
10248 };
10249
10250 struct latch_descr {
10251         int             latch_code;
10252         problem_t       question;
10253         problem_t       end_message;
10254         int             flags;
10255 };
10256
10257 /*
10258  * These are the prompts which are used to ask the user if they want
10259  * to fix a problem.
10260  */
10261 static const char *prompt[] = {
10262         N_("(no prompt)"),      /* 0 */
10263         N_("Fix"),              /* 1 */
10264         N_("Clear"),            /* 2 */
10265         N_("Relocate"),         /* 3 */
10266         N_("Allocate"),         /* 4 */
10267         N_("Expand"),           /* 5 */
10268         N_("Connect to /lost+found"), /* 6 */
10269         N_("Create"),           /* 7 */
10270         N_("Salvage"),          /* 8 */
10271         N_("Truncate"),         /* 9 */
10272         N_("Clear inode"),      /* 10 */
10273         N_("Abort"),            /* 11 */
10274         N_("Split"),            /* 12 */
10275         N_("Continue"),         /* 13 */
10276         N_("Clone duplicate/bad blocks"), /* 14 */
10277         N_("Delete file"),      /* 15 */
10278         N_("Suppress messages"),/* 16 */
10279         N_("Unlink"),           /* 17 */
10280         N_("Clear HTree index"),/* 18 */
10281         N_("Recreate"),         /* 19 */
10282         "",                     /* 20 */
10283 };
10284
10285 /*
10286  * These messages are printed when we are preen mode and we will be
10287  * automatically fixing the problem.
10288  */
10289 static const char *preen_msg[] = {
10290         N_("(NONE)"),           /* 0 */
10291         N_("FIXED"),            /* 1 */
10292         N_("CLEARED"),          /* 2 */
10293         N_("RELOCATED"),        /* 3 */
10294         N_("ALLOCATED"),        /* 4 */
10295         N_("EXPANDED"),         /* 5 */
10296         N_("RECONNECTED"),      /* 6 */
10297         N_("CREATED"),          /* 7 */
10298         N_("SALVAGED"),         /* 8 */
10299         N_("TRUNCATED"),        /* 9 */
10300         N_("INODE CLEARED"),    /* 10 */
10301         N_("ABORTED"),          /* 11 */
10302         N_("SPLIT"),            /* 12 */
10303         N_("CONTINUING"),       /* 13 */
10304         N_("DUPLICATE/BAD BLOCKS CLONED"), /* 14 */
10305         N_("FILE DELETED"),     /* 15 */
10306         N_("SUPPRESSED"),       /* 16 */
10307         N_("UNLINKED"),         /* 17 */
10308         N_("HTREE INDEX CLEARED"),/* 18 */
10309         N_("WILL RECREATE"),    /* 19 */
10310         "",                     /* 20 */
10311 };
10312
10313 static const struct e2fsck_problem problem_table[] = {
10314
10315         /* Pre-Pass 1 errors */
10316
10317         /* Block bitmap not in group */
10318         { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g.  (@b %b)\n"),
10319           PROMPT_RELOCATE, PR_LATCH_RELOC },
10320
10321         /* Inode bitmap not in group */
10322         { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g.  (@b %b)\n"),
10323           PROMPT_RELOCATE, PR_LATCH_RELOC },
10324
10325         /* Inode table not in group */
10326         { PR_0_ITABLE_NOT_GROUP,
10327           N_("@i table for @g %g is not in @g.  (@b %b)\n"
10328           "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
10329           PROMPT_RELOCATE, PR_LATCH_RELOC },
10330
10331         /* Superblock corrupt */
10332         { PR_0_SB_CORRUPT,
10333           N_("\nThe @S could not be read or does not describe a correct ext2\n"
10334           "@f.  If the @v is valid and it really contains an ext2\n"
10335           "@f (and not swap or ufs or something else), then the @S\n"
10336           "is corrupt, and you might try running e2fsck with an alternate @S:\n"
10337           "    e2fsck -b %S <@v>\n\n"),
10338           PROMPT_NONE, PR_FATAL },
10339
10340         /* Filesystem size is wrong */
10341         { PR_0_FS_SIZE_WRONG,
10342           N_("The @f size (according to the @S) is %b @bs\n"
10343           "The physical size of the @v is %c @bs\n"
10344           "Either the @S or the partition table is likely to be corrupt!\n"),
10345           PROMPT_ABORT, 0 },
10346
10347         /* Fragments not supported */
10348         { PR_0_NO_FRAGMENTS,
10349           N_("@S @b_size = %b, fragsize = %c.\n"
10350           "This version of e2fsck does not support fragment sizes different\n"
10351           "from the @b size.\n"),
10352           PROMPT_NONE, PR_FATAL },
10353
10354           /* Bad blocks_per_group */
10355         { PR_0_BLOCKS_PER_GROUP,
10356           N_("@S @bs_per_group = %b, should have been %c\n"),
10357           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10358
10359         /* Bad first_data_block */
10360         { PR_0_FIRST_DATA_BLOCK,
10361           N_("@S first_data_@b = %b, should have been %c\n"),
10362           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10363
10364         /* Adding UUID to filesystem */
10365         { PR_0_ADD_UUID,
10366           N_("@f did not have a UUID; generating one.\n\n"),
10367           PROMPT_NONE, 0 },
10368
10369         /* Relocate hint */
10370         { PR_0_RELOCATE_HINT,
10371           N_("Note: if there is several inode or block bitmap blocks\n"
10372           "which require relocation, or one part of the inode table\n"
10373           "which must be moved, you may wish to try running e2fsck\n"
10374           "with the '-b %S' option first.  The problem may lie only\n"
10375           "with the primary block group descriptor, and the backup\n"
10376           "block group descriptor may be OK.\n\n"),
10377           PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
10378
10379         /* Miscellaneous superblock corruption */
10380         { PR_0_MISC_CORRUPT_SUPER,
10381           N_("Corruption found in @S.  (%s = %N).\n"),
10382           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10383
10384         /* Error determing physical device size of filesystem */
10385         { PR_0_GETSIZE_ERROR,
10386           N_("Error determining size of the physical @v: %m\n"),
10387           PROMPT_NONE, PR_FATAL },
10388
10389         /* Inode count in superblock is incorrect */
10390         { PR_0_INODE_COUNT_WRONG,
10391           N_("@i count in @S is %i, should be %j.\n"),
10392           PROMPT_FIX, 0 },
10393
10394         { PR_0_HURD_CLEAR_FILETYPE,
10395           N_("The Hurd does not support the filetype feature.\n"),
10396           PROMPT_CLEAR, 0 },
10397
10398         /* Journal inode is invalid */
10399         { PR_0_JOURNAL_BAD_INODE,
10400           N_("@S has a bad ext3 @j (@i %i).\n"),
10401           PROMPT_CLEAR, PR_PREEN_OK },
10402
10403         /* The external journal has (unsupported) multiple filesystems */
10404         { PR_0_JOURNAL_UNSUPP_MULTIFS,
10405           N_("External @j has multiple @f users (unsupported).\n"),
10406           PROMPT_NONE, PR_FATAL },
10407
10408         /* Can't find external journal */
10409         { PR_0_CANT_FIND_JOURNAL,
10410           N_("Can't find external @j\n"),
10411           PROMPT_NONE, PR_FATAL },
10412
10413         /* External journal has bad superblock */
10414         { PR_0_EXT_JOURNAL_BAD_SUPER,
10415           N_("External @j has bad @S\n"),
10416           PROMPT_NONE, PR_FATAL },
10417
10418         /* Superblock has a bad journal UUID */
10419         { PR_0_JOURNAL_BAD_UUID,
10420           N_("External @j does not support this @f\n"),
10421           PROMPT_NONE, PR_FATAL },
10422
10423         /* Journal has an unknown superblock type */
10424         { PR_0_JOURNAL_UNSUPP_SUPER,
10425           N_("Ext3 @j @S is unknown type %N (unsupported).\n"
10426              "It is likely that your copy of e2fsck is old and/or doesn't "
10427              "support this @j format.\n"
10428              "It is also possible the @j @S is corrupt.\n"),
10429           PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
10430
10431         /* Journal superblock is corrupt */
10432         { PR_0_JOURNAL_BAD_SUPER,
10433           N_("Ext3 @j @S is corrupt.\n"),
10434           PROMPT_FIX, PR_PREEN_OK },
10435
10436         /* Superblock flag should be cleared */
10437         { PR_0_JOURNAL_HAS_JOURNAL,
10438           N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
10439           PROMPT_CLEAR, PR_PREEN_OK },
10440
10441         /* Superblock flag is incorrect */
10442         { PR_0_JOURNAL_RECOVER_SET,
10443           N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
10444           PROMPT_CLEAR, PR_PREEN_OK },
10445
10446         /* Journal has data, but recovery flag is clear */
10447         { PR_0_JOURNAL_RECOVERY_CLEAR,
10448           N_("ext3 recovery flag clear, but @j has data.\n"),
10449           PROMPT_NONE, 0 },
10450
10451         /* Ask if we should clear the journal */
10452         { PR_0_JOURNAL_RESET_JOURNAL,
10453           N_("Clear @j"),
10454           PROMPT_NULL, PR_PREEN_NOMSG },
10455
10456         /* Ask if we should run the journal anyway */
10457         { PR_0_JOURNAL_RUN,
10458           N_("Run @j anyway"),
10459           PROMPT_NULL, 0 },
10460
10461         /* Run the journal by default */
10462         { PR_0_JOURNAL_RUN_DEFAULT,
10463           N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
10464           PROMPT_NONE, 0 },
10465
10466         /* Clearing orphan inode */
10467         { PR_0_ORPHAN_CLEAR_INODE,
10468           N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
10469           PROMPT_NONE, 0 },
10470
10471         /* Illegal block found in orphaned inode */
10472         { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
10473            N_("@I @b #%B (%b) found in @o @i %i.\n"),
10474           PROMPT_NONE, 0 },
10475
10476         /* Already cleared block found in orphaned inode */
10477         { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
10478            N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
10479           PROMPT_NONE, 0 },
10480
10481         /* Illegal orphan inode in superblock */
10482         { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
10483           N_("@I @o @i %i in @S.\n"),
10484           PROMPT_NONE, 0 },
10485
10486         /* Illegal inode in orphaned inode list */
10487         { PR_0_ORPHAN_ILLEGAL_INODE,
10488           N_("@I @i %i in @o @i list.\n"),
10489           PROMPT_NONE, 0 },
10490
10491         /* Filesystem revision is 0, but feature flags are set */
10492         { PR_0_FS_REV_LEVEL,
10493           "@f has feature flag(s) set, but is a revision 0 @f.  ",
10494           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10495
10496         /* Journal superblock has an unknown read-only feature flag set */
10497         { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
10498           N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
10499           PROMPT_ABORT, 0 },
10500
10501         /* Journal superblock has an unknown incompatible feature flag set */
10502         { PR_0_JOURNAL_UNSUPP_INCOMPAT,
10503           N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
10504           PROMPT_ABORT, 0 },
10505
10506         /* Journal has unsupported version number */
10507         { PR_0_JOURNAL_UNSUPP_VERSION,
10508           N_("@j version not supported by this e2fsck.\n"),
10509           PROMPT_ABORT, 0 },
10510
10511         /* Moving journal to hidden file */
10512         { PR_0_MOVE_JOURNAL,
10513           N_("Moving @j from /%s to hidden inode.\n\n"),
10514           PROMPT_NONE, 0 },
10515
10516         /* Error moving journal to hidden file */
10517         { PR_0_ERR_MOVE_JOURNAL,
10518           N_("Error moving @j: %m\n\n"),
10519           PROMPT_NONE, 0 },
10520
10521         /* Clearing V2 journal superblock */
10522         { PR_0_CLEAR_V2_JOURNAL,
10523           N_("Found invalid V2 @j @S fields (from V1 journal).\n"
10524              "Clearing fields beyond the V1 @j @S...\n\n"),
10525           PROMPT_NONE, 0 },
10526
10527         /* Backup journal inode blocks */
10528         { PR_0_BACKUP_JNL,
10529           N_("Backing up @j @i @b information.\n\n"),
10530           PROMPT_NONE, 0 },
10531
10532         /* Reserved blocks w/o resize_inode */
10533         { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
10534           N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
10535              "is %N; @s zero.  "),
10536           PROMPT_FIX, 0 },
10537
10538         /* Resize_inode not enabled, but resize inode is non-zero */
10539         { PR_0_CLEAR_RESIZE_INODE,
10540           N_("Resize_@i not enabled, but the resize inode is non-zero.  "),
10541           PROMPT_CLEAR, 0 },
10542
10543         /* Resize inode invalid */
10544         { PR_0_RESIZE_INODE_INVALID,
10545           N_("Resize @i not valid.  "),
10546           PROMPT_RECREATE, 0 },
10547
10548         /* Pass 1 errors */
10549
10550         /* Pass 1: Checking inodes, blocks, and sizes */
10551         { PR_1_PASS_HEADER,
10552           N_("Pass 1: Checking @is, @bs, and sizes\n"),
10553           PROMPT_NONE, 0 },
10554
10555         /* Root directory is not an inode */
10556         { PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
10557           PROMPT_CLEAR, 0 },
10558
10559         /* Root directory has dtime set */
10560         { PR_1_ROOT_DTIME,
10561           N_("@r has dtime set (probably due to old mke2fs).  "),
10562           PROMPT_FIX, PR_PREEN_OK },
10563
10564         /* Reserved inode has bad mode */
10565         { PR_1_RESERVED_BAD_MODE,
10566           N_("Reserved @i %i %Q has bad mode.  "),
10567           PROMPT_CLEAR, PR_PREEN_OK },
10568
10569         /* Deleted inode has zero dtime */
10570         { PR_1_ZERO_DTIME,
10571           N_("@D @i %i has zero dtime.  "),
10572           PROMPT_FIX, PR_PREEN_OK },
10573
10574         /* Inode in use, but dtime set */
10575         { PR_1_SET_DTIME,
10576           N_("@i %i is in use, but has dtime set.  "),
10577           PROMPT_FIX, PR_PREEN_OK },
10578
10579         /* Zero-length directory */
10580         { PR_1_ZERO_LENGTH_DIR,
10581           N_("@i %i is a @z @d.  "),
10582           PROMPT_CLEAR, PR_PREEN_OK },
10583
10584         /* Block bitmap conflicts with some other fs block */
10585         { PR_1_BB_CONFLICT,
10586           N_("@g %g's @b @B at %b @C.\n"),
10587           PROMPT_RELOCATE, 0 },
10588
10589         /* Inode bitmap conflicts with some other fs block */
10590         { PR_1_IB_CONFLICT,
10591           N_("@g %g's @i @B at %b @C.\n"),
10592           PROMPT_RELOCATE, 0 },
10593
10594         /* Inode table conflicts with some other fs block */
10595         { PR_1_ITABLE_CONFLICT,
10596           N_("@g %g's @i table at %b @C.\n"),
10597           PROMPT_RELOCATE, 0 },
10598
10599         /* Block bitmap is on a bad block */
10600         { PR_1_BB_BAD_BLOCK,
10601           N_("@g %g's @b @B (%b) is bad.  "),
10602           PROMPT_RELOCATE, 0 },
10603
10604         /* Inode bitmap is on a bad block */
10605         { PR_1_IB_BAD_BLOCK,
10606           N_("@g %g's @i @B (%b) is bad.  "),
10607           PROMPT_RELOCATE, 0 },
10608
10609         /* Inode has incorrect i_size */
10610         { PR_1_BAD_I_SIZE,
10611           N_("@i %i, i_size is %Is, @s %N.  "),
10612           PROMPT_FIX, PR_PREEN_OK },
10613
10614         /* Inode has incorrect i_blocks */
10615         { PR_1_BAD_I_BLOCKS,
10616           N_("@i %i, i_@bs is %Ib, @s %N.  "),
10617           PROMPT_FIX, PR_PREEN_OK },
10618
10619         /* Illegal blocknumber in inode */
10620         { PR_1_ILLEGAL_BLOCK_NUM,
10621           N_("@I @b #%B (%b) in @i %i.  "),
10622           PROMPT_CLEAR, PR_LATCH_BLOCK },
10623
10624         /* Block number overlaps fs metadata */
10625         { PR_1_BLOCK_OVERLAPS_METADATA,
10626           N_("@b #%B (%b) overlaps @f metadata in @i %i.  "),
10627           PROMPT_CLEAR, PR_LATCH_BLOCK },
10628
10629         /* Inode has illegal blocks (latch question) */
10630         { PR_1_INODE_BLOCK_LATCH,
10631           N_("@i %i has illegal @b(s).  "),
10632           PROMPT_CLEAR, 0 },
10633
10634         /* Too many bad blocks in inode */
10635         { PR_1_TOO_MANY_BAD_BLOCKS,
10636           N_("Too many illegal @bs in @i %i.\n"),
10637           PROMPT_CLEAR_INODE, PR_NO_OK },
10638
10639         /* Illegal block number in bad block inode */
10640         { PR_1_BB_ILLEGAL_BLOCK_NUM,
10641           N_("@I @b #%B (%b) in bad @b @i.  "),
10642           PROMPT_CLEAR, PR_LATCH_BBLOCK },
10643
10644         /* Bad block inode has illegal blocks (latch question) */
10645         { PR_1_INODE_BBLOCK_LATCH,
10646           N_("Bad @b @i has illegal @b(s).  "),
10647           PROMPT_CLEAR, 0 },
10648
10649         /* Duplicate or bad blocks in use! */
10650         { PR_1_DUP_BLOCKS_PREENSTOP,
10651           N_("Duplicate or bad @b in use!\n"),
10652           PROMPT_NONE, 0 },
10653
10654         /* Bad block used as bad block indirect block */
10655         { PR_1_BBINODE_BAD_METABLOCK,
10656           N_("Bad @b %b used as bad @b @i indirect @b.  "),
10657           PROMPT_CLEAR, PR_LATCH_BBLOCK },
10658
10659         /* Inconsistency can't be fixed prompt */
10660         { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
10661           N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
10662              "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
10663              "in the @f.\n"),
10664           PROMPT_CONTINUE, PR_PREEN_NOMSG },
10665
10666         /* Bad primary block */
10667         { PR_1_BAD_PRIMARY_BLOCK,
10668           N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
10669           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
10670
10671         /* Bad primary block prompt */
10672         { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
10673           N_("You can clear the this @b (and hope for the best) from the\n"
10674           "bad @b list and hope that @b is really OK, but there are no\n"
10675           "guarantees.\n\n"),
10676           PROMPT_CLEAR, PR_PREEN_NOMSG },
10677
10678         /* Bad primary superblock */
10679         { PR_1_BAD_PRIMARY_SUPERBLOCK,
10680           N_("The primary @S (%b) is on the bad @b list.\n"),
10681           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10682
10683         /* Bad primary block group descriptors */
10684         { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
10685           N_("Block %b in the primary @g descriptors "
10686           "is on the bad @b list\n"),
10687           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10688
10689         /* Bad superblock in group */
10690         { PR_1_BAD_SUPERBLOCK,
10691           N_("Warning: Group %g's @S (%b) is bad.\n"),
10692           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10693
10694         /* Bad block group descriptors in group */
10695         { PR_1_BAD_GROUP_DESCRIPTORS,
10696           N_("Warning: Group %g's copy of the @g descriptors has a bad "
10697           "@b (%b).\n"),
10698           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10699
10700         /* Block claimed for no reason */
10701         { PR_1_PROGERR_CLAIMED_BLOCK,
10702           N_("Programming error?  @b #%b claimed for no reason in "
10703           "process_bad_@b.\n"),
10704           PROMPT_NONE, PR_PREEN_OK },
10705
10706         /* Error allocating blocks for relocating metadata */
10707         { PR_1_RELOC_BLOCK_ALLOCATE,
10708           N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
10709           PROMPT_NONE, PR_PREEN_OK },
10710
10711         /* Error allocating block buffer during relocation process */
10712         { PR_1_RELOC_MEMORY_ALLOCATE,
10713           N_("@A @b buffer for relocating %s\n"),
10714           PROMPT_NONE, PR_PREEN_OK },
10715
10716         /* Relocating metadata group information from X to Y */
10717         { PR_1_RELOC_FROM_TO,
10718           N_("Relocating @g %g's %s from %b to %c...\n"),
10719           PROMPT_NONE, PR_PREEN_OK },
10720
10721         /* Relocating metatdata group information to X */
10722         { PR_1_RELOC_TO,
10723           N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
10724           PROMPT_NONE, PR_PREEN_OK },
10725
10726         /* Block read error during relocation process */
10727         { PR_1_RELOC_READ_ERR,
10728           N_("Warning: could not read @b %b of %s: %m\n"),
10729           PROMPT_NONE, PR_PREEN_OK },
10730
10731         /* Block write error during relocation process */
10732         { PR_1_RELOC_WRITE_ERR,
10733           N_("Warning: could not write @b %b for %s: %m\n"),
10734           PROMPT_NONE, PR_PREEN_OK },
10735
10736         /* Error allocating inode bitmap */
10737         { PR_1_ALLOCATE_IBITMAP_ERROR,
10738           "@A @i @B (%N): %m\n",
10739           PROMPT_NONE, PR_FATAL },
10740
10741         /* Error allocating block bitmap */
10742         { PR_1_ALLOCATE_BBITMAP_ERROR,
10743           "@A @b @B (%N): %m\n",
10744           PROMPT_NONE, PR_FATAL },
10745
10746         /* Error allocating icount structure */
10747         { PR_1_ALLOCATE_ICOUNT,
10748           N_("@A icount link information: %m\n"),
10749           PROMPT_NONE, PR_FATAL },
10750
10751         /* Error allocating dbcount */
10752         { PR_1_ALLOCATE_DBCOUNT,
10753           N_("@A @d @b array: %m\n"),
10754           PROMPT_NONE, PR_FATAL },
10755
10756         /* Error while scanning inodes */
10757         { PR_1_ISCAN_ERROR,
10758           N_("Error while scanning @is (%i): %m\n"),
10759           PROMPT_NONE, PR_FATAL },
10760
10761         /* Error while iterating over blocks */
10762         { PR_1_BLOCK_ITERATE,
10763           N_("Error while iterating over @bs in @i %i: %m\n"),
10764           PROMPT_NONE, PR_FATAL },
10765
10766         /* Error while storing inode count information */
10767         { PR_1_ICOUNT_STORE,
10768           N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
10769           PROMPT_NONE, PR_FATAL },
10770
10771         /* Error while storing directory block information */
10772         { PR_1_ADD_DBLOCK,
10773           N_("Error storing @d @b information "
10774           "(@i=%i, @b=%b, num=%N): %m\n"),
10775           PROMPT_NONE, PR_FATAL },
10776
10777         /* Error while reading inode (for clearing) */
10778         { PR_1_READ_INODE,
10779           N_("Error reading @i %i: %m\n"),
10780           PROMPT_NONE, PR_FATAL },
10781
10782         /* Suppress messages prompt */
10783         { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
10784
10785         /* Imagic flag set on an inode when filesystem doesn't support it */
10786         { PR_1_SET_IMAGIC,
10787           N_("@i %i has imagic flag set.  "),
10788           PROMPT_CLEAR, 0 },
10789
10790         /* Immutable flag set on a device or socket inode */
10791         { PR_1_SET_IMMUTABLE,
10792           N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
10793              "or append-only flag set.  "),
10794           PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
10795
10796         /* Compression flag set on an inode when filesystem doesn't support it */
10797         { PR_1_COMPR_SET,
10798           N_("@i %i has @cion flag set on @f without @cion support.  "),
10799           PROMPT_CLEAR, 0 },
10800
10801         /* Non-zero size for device, fifo or socket inode */
10802         { PR_1_SET_NONZSIZE,
10803           "Special (@v/socket/fifo) @i %i has non-zero size.  ",
10804           PROMPT_FIX, PR_PREEN_OK },
10805
10806         /* Filesystem revision is 0, but feature flags are set */
10807         { PR_1_FS_REV_LEVEL,
10808           "@f has feature flag(s) set, but is a revision 0 @f.  ",
10809           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10810
10811         /* Journal inode is not in use, but contains data */
10812         { PR_1_JOURNAL_INODE_NOT_CLEAR,
10813           "@j @i is not in use, but contains data.  ",
10814           PROMPT_CLEAR, PR_PREEN_OK },
10815
10816         /* Journal has bad mode */
10817         { PR_1_JOURNAL_BAD_MODE,
10818           N_("@j is not regular file.  "),
10819           PROMPT_FIX, PR_PREEN_OK },
10820
10821         /* Deal with inodes that were part of orphan linked list */
10822         { PR_1_LOW_DTIME,
10823           N_("@i %i was part of the orphaned @i list.  "),
10824           PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
10825
10826         /* Deal with inodes that were part of corrupted orphan linked
10827            list (latch question) */
10828         { PR_1_ORPHAN_LIST_REFUGEES,
10829           N_("@is that were part of a corrupted orphan linked list found.  "),
10830           PROMPT_FIX, 0 },
10831
10832         /* Error allocating refcount structure */
10833         { PR_1_ALLOCATE_REFCOUNT,
10834           "@A refcount structure (%N): %m\n",
10835           PROMPT_NONE, PR_FATAL },
10836
10837         /* Error reading extended attribute block */
10838         { PR_1_READ_EA_BLOCK,
10839           N_("Error reading @a @b %b for @i %i.  "),
10840           PROMPT_CLEAR, 0 },
10841
10842         /* Invalid extended attribute block */
10843         { PR_1_BAD_EA_BLOCK,
10844           N_("@i %i has a bad @a @b %b.  "),
10845           PROMPT_CLEAR, 0 },
10846
10847         /* Error reading Extended Attribute block while fixing refcount */
10848         { PR_1_EXTATTR_READ_ABORT,
10849           N_("Error reading @a @b %b (%m).  "),
10850           PROMPT_ABORT, 0 },
10851
10852         /* Extended attribute reference count incorrect */
10853         { PR_1_EXTATTR_REFCOUNT,
10854           N_("@a @b %b has reference count %B, should be %N.  "),
10855           PROMPT_FIX, 0 },
10856
10857         /* Error writing Extended Attribute block while fixing refcount */
10858         { PR_1_EXTATTR_WRITE,
10859           N_("Error writing @a @b %b (%m).  "),
10860           PROMPT_ABORT, 0 },
10861
10862         /* Multiple EA blocks not supported */
10863         { PR_1_EA_MULTI_BLOCK,
10864           N_("@a @b %b has h_blocks > 1.  "),
10865           PROMPT_CLEAR, 0},
10866
10867         /* Error allocating EA region allocation structure */
10868         { PR_1_EA_ALLOC_REGION,
10869           N_("Error allocating @a @b %b.  "),
10870           PROMPT_ABORT, 0},
10871
10872         /* Error EA allocation collision */
10873         { PR_1_EA_ALLOC_COLLISION,
10874           N_("@a @b %b is corrupt (allocation collision).  "),
10875           PROMPT_CLEAR, 0},
10876
10877         /* Bad extended attribute name */
10878         { PR_1_EA_BAD_NAME,
10879           N_("@a @b %b is corrupt (invalid name).  "),
10880           PROMPT_CLEAR, 0},
10881
10882         /* Bad extended attribute value */
10883         { PR_1_EA_BAD_VALUE,
10884           N_("@a @b %b is corrupt (invalid value).  "),
10885           PROMPT_CLEAR, 0},
10886
10887         /* Inode too big (latch question) */
10888         { PR_1_INODE_TOOBIG,
10889           N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
10890
10891         /* Directory too big */
10892         { PR_1_TOOBIG_DIR,
10893           N_("@b #%B (%b) causes @d to be too big.  "),
10894           PROMPT_CLEAR, PR_LATCH_TOOBIG },
10895
10896         /* Regular file too big */
10897         { PR_1_TOOBIG_REG,
10898           N_("@b #%B (%b) causes file to be too big.  "),
10899           PROMPT_CLEAR, PR_LATCH_TOOBIG },
10900
10901         /* Symlink too big */
10902         { PR_1_TOOBIG_SYMLINK,
10903           N_("@b #%B (%b) causes symlink to be too big.  "),
10904           PROMPT_CLEAR, PR_LATCH_TOOBIG },
10905
10906         /* INDEX_FL flag set on a non-HTREE filesystem */
10907         { PR_1_HTREE_SET,
10908           N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
10909           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10910
10911         /* INDEX_FL flag set on a non-directory */
10912         { PR_1_HTREE_NODIR,
10913           N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
10914           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10915
10916         /* Invalid root node in HTREE directory */
10917         { PR_1_HTREE_BADROOT,
10918           N_("@h %i has an invalid root node.\n"),
10919           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10920
10921         /* Unsupported hash version in HTREE directory */
10922         { PR_1_HTREE_HASHV,
10923           N_("@h %i has an unsupported hash version (%N)\n"),
10924           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10925
10926         /* Incompatible flag in HTREE root node */
10927         { PR_1_HTREE_INCOMPAT,
10928           N_("@h %i uses an incompatible htree root node flag.\n"),
10929           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10930
10931         /* HTREE too deep */
10932         { PR_1_HTREE_DEPTH,
10933           N_("@h %i has a tree depth (%N) which is too big\n"),
10934           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10935
10936         /* Bad block has indirect block that conflicts with filesystem block */
10937         { PR_1_BB_FS_BLOCK,
10938           N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
10939              "@f metadata.  "),
10940           PROMPT_CLEAR, PR_LATCH_BBLOCK },
10941
10942         /* Resize inode failed */
10943         { PR_1_RESIZE_INODE_CREATE,
10944           N_("Resize @i (re)creation failed: %m."),
10945           PROMPT_ABORT, 0 },
10946
10947         /* invalid inode->i_extra_isize */
10948         { PR_1_EXTRA_ISIZE,
10949           N_("@i %i has a extra size (%IS) which is invalid\n"),
10950           PROMPT_FIX, PR_PREEN_OK },
10951
10952         /* invalid ea entry->e_name_len */
10953         { PR_1_ATTR_NAME_LEN,
10954           N_("@a in @i %i has a namelen (%N) which is invalid\n"),
10955           PROMPT_CLEAR, PR_PREEN_OK },
10956
10957         /* invalid ea entry->e_value_size */
10958         { PR_1_ATTR_VALUE_SIZE,
10959           N_("@a in @i %i has a value size (%N) which is invalid\n"),
10960           PROMPT_CLEAR, PR_PREEN_OK },
10961
10962         /* invalid ea entry->e_value_offs */
10963         { PR_1_ATTR_VALUE_OFFSET,
10964           N_("@a in @i %i has a value offset (%N) which is invalid\n"),
10965           PROMPT_CLEAR, PR_PREEN_OK },
10966
10967         /* invalid ea entry->e_value_block */
10968         { PR_1_ATTR_VALUE_BLOCK,
10969           N_("@a in @i %i has a value block (%N) which is invalid (must be 0)\n"),
10970           PROMPT_CLEAR, PR_PREEN_OK },
10971
10972         /* invalid ea entry->e_hash */
10973         { PR_1_ATTR_HASH,
10974           N_("@a in @i %i has a hash (%N) which is invalid (must be 0)\n"),
10975           PROMPT_CLEAR, PR_PREEN_OK },
10976
10977         /* Pass 1b errors */
10978
10979         /* Pass 1B: Rescan for duplicate/bad blocks */
10980         { PR_1B_PASS_HEADER,
10981           N_("Duplicate @bs found... invoking duplicate @b passes.\n"
10982           "Pass 1B: Rescan for duplicate/bad @bs\n"),
10983           PROMPT_NONE, 0 },
10984
10985         /* Duplicate/bad block(s) header */
10986         { PR_1B_DUP_BLOCK_HEADER,
10987           N_("Duplicate/bad @b(s) in @i %i:"),
10988           PROMPT_NONE, 0 },
10989
10990         /* Duplicate/bad block(s) in inode */
10991         { PR_1B_DUP_BLOCK,
10992           " %b",
10993           PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
10994
10995         /* Duplicate/bad block(s) end */
10996         { PR_1B_DUP_BLOCK_END,
10997           "\n",
10998           PROMPT_NONE, PR_PREEN_NOHDR },
10999
11000         /* Error while scanning inodes */
11001         { PR_1B_ISCAN_ERROR,
11002           N_("Error while scanning inodes (%i): %m\n"),
11003           PROMPT_NONE, PR_FATAL },
11004
11005         /* Error allocating inode bitmap */
11006         { PR_1B_ALLOCATE_IBITMAP_ERROR,
11007           N_("@A @i @B (inode_dup_map): %m\n"),
11008           PROMPT_NONE, PR_FATAL },
11009
11010         /* Error while iterating over blocks */
11011         { PR_1B_BLOCK_ITERATE,
11012           N_("Error while iterating over @bs in @i %i (%s): %m\n"),
11013           PROMPT_NONE, 0 },
11014
11015         /* Error adjusting EA refcount */
11016         { PR_1B_ADJ_EA_REFCOUNT,
11017           N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
11018           PROMPT_NONE, 0 },
11019
11020
11021         /* Pass 1C: Scan directories for inodes with dup blocks. */
11022         { PR_1C_PASS_HEADER,
11023           N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
11024           PROMPT_NONE, 0 },
11025
11026
11027         /* Pass 1D: Reconciling duplicate blocks */
11028         { PR_1D_PASS_HEADER,
11029           N_("Pass 1D: Reconciling duplicate @bs\n"),
11030           PROMPT_NONE, 0 },
11031
11032         /* File has duplicate blocks */
11033         { PR_1D_DUP_FILE,
11034           N_("File %Q (@i #%i, mod time %IM) \n"
11035           "  has %B duplicate @b(s), shared with %N file(s):\n"),
11036           PROMPT_NONE, 0 },
11037
11038         /* List of files sharing duplicate blocks */
11039         { PR_1D_DUP_FILE_LIST,
11040           N_("\t%Q (@i #%i, mod time %IM)\n"),
11041           PROMPT_NONE, 0 },
11042
11043         /* File sharing blocks with filesystem metadata  */
11044         { PR_1D_SHARE_METADATA,
11045           N_("\t<@f metadata>\n"),
11046           PROMPT_NONE, 0 },
11047
11048         /* Report of how many duplicate/bad inodes */
11049         { PR_1D_NUM_DUP_INODES,
11050           N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
11051           PROMPT_NONE, 0 },
11052
11053         /* Duplicated blocks already reassigned or cloned. */
11054         { PR_1D_DUP_BLOCKS_DEALT,
11055           N_("Duplicated @bs already reassigned or cloned.\n\n"),
11056           PROMPT_NONE, 0 },
11057
11058         /* Clone duplicate/bad blocks? */
11059         { PR_1D_CLONE_QUESTION,
11060           "", PROMPT_CLONE, PR_NO_OK },
11061
11062         /* Delete file? */
11063         { PR_1D_DELETE_QUESTION,
11064           "", PROMPT_DELETE, 0 },
11065
11066         /* Couldn't clone file (error) */
11067         { PR_1D_CLONE_ERROR,
11068           N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
11069
11070         /* Pass 2 errors */
11071
11072         /* Pass 2: Checking directory structure */
11073         { PR_2_PASS_HEADER,
11074           N_("Pass 2: Checking @d structure\n"),
11075           PROMPT_NONE, 0 },
11076
11077         /* Bad inode number for '.' */
11078         { PR_2_BAD_INODE_DOT,
11079           N_("Bad @i number for '.' in @d @i %i.\n"),
11080           PROMPT_FIX, 0 },
11081
11082         /* Directory entry has bad inode number */
11083         { PR_2_BAD_INO,
11084           N_("@E has bad @i #: %Di.\n"),
11085           PROMPT_CLEAR, 0 },
11086
11087         /* Directory entry has deleted or unused inode */
11088         { PR_2_UNUSED_INODE,
11089           N_("@E has @D/unused @i %Di.  "),
11090           PROMPT_CLEAR, PR_PREEN_OK },
11091
11092         /* Directry entry is link to '.' */
11093         { PR_2_LINK_DOT,
11094           N_("@E @L to '.'  "),
11095           PROMPT_CLEAR, 0 },
11096
11097         /* Directory entry points to inode now located in a bad block */
11098         { PR_2_BB_INODE,
11099           N_("@E points to @i (%Di) located in a bad @b.\n"),
11100           PROMPT_CLEAR, 0 },
11101
11102         /* Directory entry contains a link to a directory */
11103         { PR_2_LINK_DIR,
11104           N_("@E @L to @d %P (%Di).\n"),
11105           PROMPT_CLEAR, 0 },
11106
11107         /* Directory entry contains a link to the root directry */
11108         { PR_2_LINK_ROOT,
11109           N_("@E @L to the @r.\n"),
11110           PROMPT_CLEAR, 0 },
11111
11112         /* Directory entry has illegal characters in its name */
11113         { PR_2_BAD_NAME,
11114           N_("@E has illegal characters in its name.\n"),
11115           PROMPT_FIX, 0 },
11116
11117         /* Missing '.' in directory inode */
11118         { PR_2_MISSING_DOT,
11119           N_("Missing '.' in @d @i %i.\n"),
11120           PROMPT_FIX, 0 },
11121
11122         /* Missing '..' in directory inode */
11123         { PR_2_MISSING_DOT_DOT,
11124           N_("Missing '..' in @d @i %i.\n"),
11125           PROMPT_FIX, 0 },
11126
11127         /* First entry in directory inode doesn't contain '.' */
11128         { PR_2_1ST_NOT_DOT,
11129           N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
11130           PROMPT_FIX, 0 },
11131
11132         /* Second entry in directory inode doesn't contain '..' */
11133         { PR_2_2ND_NOT_DOT_DOT,
11134           N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
11135           PROMPT_FIX, 0 },
11136
11137         /* i_faddr should be zero */
11138         { PR_2_FADDR_ZERO,
11139           N_("i_faddr @F %IF, @s zero.\n"),
11140           PROMPT_CLEAR, 0 },
11141
11142         /* i_file_acl should be zero */
11143         { PR_2_FILE_ACL_ZERO,
11144           N_("i_file_acl @F %If, @s zero.\n"),
11145           PROMPT_CLEAR, 0 },
11146
11147         /* i_dir_acl should be zero */
11148         { PR_2_DIR_ACL_ZERO,
11149           N_("i_dir_acl @F %Id, @s zero.\n"),
11150           PROMPT_CLEAR, 0 },
11151
11152         /* i_frag should be zero */
11153         { PR_2_FRAG_ZERO,
11154           N_("i_frag @F %N, @s zero.\n"),
11155           PROMPT_CLEAR, 0 },
11156
11157         /* i_fsize should be zero */
11158         { PR_2_FSIZE_ZERO,
11159           N_("i_fsize @F %N, @s zero.\n"),
11160           PROMPT_CLEAR, 0 },
11161
11162         /* inode has bad mode */
11163         { PR_2_BAD_MODE,
11164           N_("@i %i (%Q) has a bad mode (%Im).\n"),
11165           PROMPT_CLEAR, 0 },
11166
11167         /* directory corrupted */
11168         { PR_2_DIR_CORRUPTED,
11169           N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
11170           PROMPT_SALVAGE, 0 },
11171
11172         /* filename too long */
11173         { PR_2_FILENAME_LONG,
11174           N_("@d @i %i, @b %B, offset %N: filename too long\n"),
11175           PROMPT_TRUNCATE, 0 },
11176
11177         /* Directory inode has a missing block (hole) */
11178         { PR_2_DIRECTORY_HOLE,
11179           N_("@d @i %i has an unallocated @b #%B.  "),
11180           PROMPT_ALLOCATE, 0 },
11181
11182         /* '.' is not NULL terminated */
11183         { PR_2_DOT_NULL_TERM,
11184           N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
11185           PROMPT_FIX, 0 },
11186
11187         /* '..' is not NULL terminated */
11188         { PR_2_DOT_DOT_NULL_TERM,
11189           N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
11190           PROMPT_FIX, 0 },
11191
11192         /* Illegal character device inode */
11193         { PR_2_BAD_CHAR_DEV,
11194           N_("@i %i (%Q) is an @I character @v.\n"),
11195           PROMPT_CLEAR, 0 },
11196
11197         /* Illegal block device inode */
11198         { PR_2_BAD_BLOCK_DEV,
11199           N_("@i %i (%Q) is an @I @b @v.\n"),
11200           PROMPT_CLEAR, 0 },
11201
11202         /* Duplicate '.' entry */
11203         { PR_2_DUP_DOT,
11204           N_("@E is duplicate '.' @e.\n"),
11205           PROMPT_FIX, 0 },
11206
11207         /* Duplicate '..' entry */
11208         { PR_2_DUP_DOT_DOT,
11209           N_("@E is duplicate '..' @e.\n"),
11210           PROMPT_FIX, 0 },
11211
11212         /* Internal error: couldn't find dir_info */
11213         { PR_2_NO_DIRINFO,
11214           N_("Internal error: couldn't find dir_info for %i.\n"),
11215           PROMPT_NONE, PR_FATAL },
11216
11217         /* Final rec_len is wrong */
11218         { PR_2_FINAL_RECLEN,
11219           N_("@E has rec_len of %Dr, should be %N.\n"),
11220           PROMPT_FIX, 0 },
11221
11222         /* Error allocating icount structure */
11223         { PR_2_ALLOCATE_ICOUNT,
11224           N_("@A icount structure: %m\n"),
11225           PROMPT_NONE, PR_FATAL },
11226
11227         /* Error iterating over directory blocks */
11228         { PR_2_DBLIST_ITERATE,
11229           N_("Error iterating over @d @bs: %m\n"),
11230           PROMPT_NONE, PR_FATAL },
11231
11232         /* Error reading directory block */
11233         { PR_2_READ_DIRBLOCK,
11234           N_("Error reading @d @b %b (@i %i): %m\n"),
11235           PROMPT_CONTINUE, 0 },
11236
11237         /* Error writing directory block */
11238         { PR_2_WRITE_DIRBLOCK,
11239           N_("Error writing @d @b %b (@i %i): %m\n"),
11240           PROMPT_CONTINUE, 0 },
11241
11242         /* Error allocating new directory block */
11243         { PR_2_ALLOC_DIRBOCK,
11244           N_("@A new @d @b for @i %i (%s): %m\n"),
11245           PROMPT_NONE, 0 },
11246
11247         /* Error deallocating inode */
11248         { PR_2_DEALLOC_INODE,
11249           N_("Error deallocating @i %i: %m\n"),
11250           PROMPT_NONE, PR_FATAL },
11251
11252         /* Directory entry for '.' is big.  Split? */
11253         { PR_2_SPLIT_DOT,
11254           N_("@d @e for '.' is big.  "),
11255           PROMPT_SPLIT, PR_NO_OK },
11256
11257         /* Illegal FIFO inode */
11258         { PR_2_BAD_FIFO,
11259           N_("@i %i (%Q) is an @I FIFO.\n"),
11260           PROMPT_CLEAR, 0 },
11261
11262         /* Illegal socket inode */
11263         { PR_2_BAD_SOCKET,
11264           N_("@i %i (%Q) is an @I socket.\n"),
11265           PROMPT_CLEAR, 0 },
11266
11267         /* Directory filetype not set */
11268         { PR_2_SET_FILETYPE,
11269           N_("Setting filetype for @E to %N.\n"),
11270           PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
11271
11272         /* Directory filetype incorrect */
11273         { PR_2_BAD_FILETYPE,
11274           N_("@E has an incorrect filetype (was %Dt, should be %N).\n"),
11275           PROMPT_FIX, 0 },
11276
11277         /* Directory filetype set on filesystem */
11278         { PR_2_CLEAR_FILETYPE,
11279           N_("@E has filetype set.\n"),
11280           PROMPT_CLEAR, PR_PREEN_OK },
11281
11282         /* Directory filename is null */
11283         { PR_2_NULL_NAME,
11284           N_("@E has a zero-length name.\n"),
11285           PROMPT_CLEAR, 0 },
11286
11287         /* Invalid symlink */
11288         { PR_2_INVALID_SYMLINK,
11289           N_("Symlink %Q (@i #%i) is invalid.\n"),
11290           PROMPT_CLEAR, 0 },
11291
11292         /* i_file_acl (extended attribute block) is bad */
11293         { PR_2_FILE_ACL_BAD,
11294           N_("@a @b @F invalid (%If).\n"),
11295           PROMPT_CLEAR, 0 },
11296
11297         /* Filesystem contains large files, but has no such flag in sb */
11298         { PR_2_FEATURE_LARGE_FILES,
11299           N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
11300           PROMPT_FIX, 0 },
11301
11302         /* Node in HTREE directory not referenced */
11303         { PR_2_HTREE_NOTREF,
11304           N_("@p @h %d: node (%B) not referenced\n"),
11305           PROMPT_NONE, 0 },
11306
11307         /* Node in HTREE directory referenced twice */
11308         { PR_2_HTREE_DUPREF,
11309           N_("@p @h %d: node (%B) referenced twice\n"),
11310           PROMPT_NONE, 0 },
11311
11312         /* Node in HTREE directory has bad min hash */
11313         { PR_2_HTREE_MIN_HASH,
11314           N_("@p @h %d: node (%B) has bad min hash\n"),
11315           PROMPT_NONE, 0 },
11316
11317         /* Node in HTREE directory has bad max hash */
11318         { PR_2_HTREE_MAX_HASH,
11319           N_("@p @h %d: node (%B) has bad max hash\n"),
11320           PROMPT_NONE, 0 },
11321
11322         /* Clear invalid HTREE directory */
11323         { PR_2_HTREE_CLEAR,
11324           N_("Invalid @h %d (%q).  "), PROMPT_CLEAR, 0 },
11325
11326         /* Bad block in htree interior node */
11327         { PR_2_HTREE_BADBLK,
11328           N_("@p @h %d (%q): bad @b number %b.\n"),
11329           PROMPT_CLEAR_HTREE, 0 },
11330
11331         /* Error adjusting EA refcount */
11332         { PR_2_ADJ_EA_REFCOUNT,
11333           N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
11334           PROMPT_NONE, PR_FATAL },
11335
11336         /* Invalid HTREE root node */
11337         { PR_2_HTREE_BAD_ROOT,
11338           N_("@p @h %d: root node is invalid\n"),
11339           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11340
11341         /* Invalid HTREE limit */
11342         { PR_2_HTREE_BAD_LIMIT,
11343           N_("@p @h %d: node (%B) has bad limit (%N)\n"),
11344           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11345
11346         /* Invalid HTREE count */
11347         { PR_2_HTREE_BAD_COUNT,
11348           N_("@p @h %d: node (%B) has bad count (%N)\n"),
11349           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11350
11351         /* HTREE interior node has out-of-order hashes in table */
11352         { PR_2_HTREE_HASH_ORDER,
11353           N_("@p @h %d: node (%B) has an unordered hash table\n"),
11354           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11355
11356         /* Node in HTREE directory has bad depth */
11357         { PR_2_HTREE_BAD_DEPTH,
11358           N_("@p @h %d: node (%B) has bad depth\n"),
11359           PROMPT_NONE, 0 },
11360
11361         /* Duplicate directory entry found */
11362         { PR_2_DUPLICATE_DIRENT,
11363           N_("Duplicate @E found.  "),
11364           PROMPT_CLEAR, 0 },
11365
11366         /* Non-unique filename found */
11367         { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
11368           N_("@E has a non-unique filename.\nRename to %s"),
11369           PROMPT_NULL, 0 },
11370
11371         /* Duplicate directory entry found */
11372         { PR_2_REPORT_DUP_DIRENT,
11373           N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
11374           PROMPT_NONE, 0 },
11375
11376         /* Pass 3 errors */
11377
11378         /* Pass 3: Checking directory connectivity */
11379         { PR_3_PASS_HEADER,
11380           N_("Pass 3: Checking @d connectivity\n"),
11381           PROMPT_NONE, 0 },
11382
11383         /* Root inode not allocated */
11384         { PR_3_NO_ROOT_INODE,
11385           N_("@r not allocated.  "),
11386           PROMPT_ALLOCATE, 0 },
11387
11388         /* No room in lost+found */
11389         { PR_3_EXPAND_LF_DIR,
11390           N_("No room in @l @d.  "),
11391           PROMPT_EXPAND, 0 },
11392
11393         /* Unconnected directory inode */
11394         { PR_3_UNCONNECTED_DIR,
11395           N_("Unconnected @d @i %i (%p)\n"),
11396           PROMPT_CONNECT, 0 },
11397
11398         /* /lost+found not found */
11399         { PR_3_NO_LF_DIR,
11400           N_("/@l not found.  "),
11401           PROMPT_CREATE, PR_PREEN_OK },
11402
11403         /* .. entry is incorrect */
11404         { PR_3_BAD_DOT_DOT,
11405           N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
11406           PROMPT_FIX, 0 },
11407
11408         /* Bad or non-existent /lost+found.  Cannot reconnect */
11409         { PR_3_NO_LPF,
11410           N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
11411           PROMPT_NONE, 0 },
11412
11413         /* Could not expand /lost+found */
11414         { PR_3_CANT_EXPAND_LPF,
11415           N_("Could not expand /@l: %m\n"),
11416           PROMPT_NONE, 0 },
11417
11418         /* Could not reconnect inode */
11419         { PR_3_CANT_RECONNECT,
11420           N_("Could not reconnect %i: %m\n"),
11421           PROMPT_NONE, 0 },
11422
11423         /* Error while trying to find /lost+found */
11424         { PR_3_ERR_FIND_LPF,
11425           N_("Error while trying to find /@l: %m\n"),
11426           PROMPT_NONE, 0 },
11427
11428         /* Error in ext2fs_new_block while creating /lost+found */
11429         { PR_3_ERR_LPF_NEW_BLOCK,
11430           N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
11431           PROMPT_NONE, 0 },
11432
11433         /* Error in ext2fs_new_inode while creating /lost+found */
11434         { PR_3_ERR_LPF_NEW_INODE,
11435           N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
11436           PROMPT_NONE, 0 },
11437
11438         /* Error in ext2fs_new_dir_block while creating /lost+found */
11439         { PR_3_ERR_LPF_NEW_DIR_BLOCK,
11440           N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
11441           PROMPT_NONE, 0 },
11442
11443         /* Error while writing directory block for /lost+found */
11444         { PR_3_ERR_LPF_WRITE_BLOCK,
11445           N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
11446           PROMPT_NONE, 0 },
11447
11448         /* Error while adjusting inode count */
11449         { PR_3_ADJUST_INODE,
11450           N_("Error while adjusting @i count on @i %i\n"),
11451           PROMPT_NONE, 0 },
11452
11453         /* Couldn't fix parent directory -- error */
11454         { PR_3_FIX_PARENT_ERR,
11455           N_("Couldn't fix parent of @i %i: %m\n\n"),
11456           PROMPT_NONE, 0 },
11457
11458         /* Couldn't fix parent directory -- couldn't find it */
11459         { PR_3_FIX_PARENT_NOFIND,
11460           N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
11461           PROMPT_NONE, 0 },
11462
11463         /* Error allocating inode bitmap */
11464         { PR_3_ALLOCATE_IBITMAP_ERROR,
11465           N_("@A @i @B (%N): %m\n"),
11466           PROMPT_NONE, PR_FATAL },
11467
11468         /* Error creating root directory */
11469         { PR_3_CREATE_ROOT_ERROR,
11470           N_("Error creating root @d (%s): %m\n"),
11471           PROMPT_NONE, PR_FATAL },
11472
11473         /* Error creating lost and found directory */
11474         { PR_3_CREATE_LPF_ERROR,
11475           N_("Error creating /@l @d (%s): %m\n"),
11476           PROMPT_NONE, PR_FATAL },
11477
11478         /* Root inode is not directory; aborting */
11479         { PR_3_ROOT_NOT_DIR_ABORT,
11480           N_("@r is not a @d; aborting.\n"),
11481           PROMPT_NONE, PR_FATAL },
11482
11483         /* Cannot proceed without a root inode. */
11484         { PR_3_NO_ROOT_INODE_ABORT,
11485           N_("Cannot proceed without a @r.\n"),
11486           PROMPT_NONE, PR_FATAL },
11487
11488         /* Internal error: couldn't find dir_info */
11489         { PR_3_NO_DIRINFO,
11490           N_("Internal error: couldn't find dir_info for %i.\n"),
11491           PROMPT_NONE, PR_FATAL },
11492
11493         /* Lost+found not a directory */
11494         { PR_3_LPF_NOTDIR,
11495           N_("/@l is not a @d (ino=%i)\n"),
11496           PROMPT_UNLINK, 0 },
11497
11498         /* Pass 3A Directory Optimization       */
11499
11500         /* Pass 3A: Optimizing directories */
11501         { PR_3A_PASS_HEADER,
11502           N_("Pass 3A: Optimizing directories\n"),
11503           PROMPT_NONE, PR_PREEN_NOMSG },
11504
11505         /* Error iterating over directories */
11506         { PR_3A_OPTIMIZE_ITER,
11507           N_("Failed to create dirs_to_hash iterator: %m"),
11508           PROMPT_NONE, 0 },
11509
11510         /* Error rehash directory */
11511         { PR_3A_OPTIMIZE_DIR_ERR,
11512           N_("Failed to optimize directory %q (%d): %m"),
11513           PROMPT_NONE, 0 },
11514
11515         /* Rehashing dir header */
11516         { PR_3A_OPTIMIZE_DIR_HEADER,
11517           N_("Optimizing directories: "),
11518           PROMPT_NONE, PR_MSG_ONLY },
11519
11520         /* Rehashing directory %d */
11521         { PR_3A_OPTIMIZE_DIR,
11522           " %d",
11523           PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
11524
11525         /* Rehashing dir end */
11526         { PR_3A_OPTIMIZE_DIR_END,
11527           "\n",
11528           PROMPT_NONE, PR_PREEN_NOHDR },
11529
11530         /* Pass 4 errors */
11531
11532         /* Pass 4: Checking reference counts */
11533         { PR_4_PASS_HEADER,
11534           N_("Pass 4: Checking reference counts\n"),
11535           PROMPT_NONE, 0 },
11536
11537         /* Unattached zero-length inode */
11538         { PR_4_ZERO_LEN_INODE,
11539           "@u @z @i %i.  ",
11540           PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
11541
11542         /* Unattached inode */
11543         { PR_4_UNATTACHED_INODE,
11544           "@u @i %i\n",
11545           PROMPT_CONNECT, 0 },
11546
11547         /* Inode ref count wrong */
11548         { PR_4_BAD_REF_COUNT,
11549           N_("@i %i ref count is %Il, @s %N.  "),
11550           PROMPT_FIX, PR_PREEN_OK },
11551
11552         { PR_4_INCONSISTENT_COUNT,
11553           N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
11554           "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
11555           "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
11556           "They should be the same!\n"),
11557           PROMPT_NONE, 0 },
11558
11559         /* Pass 5 errors */
11560
11561         /* Pass 5: Checking group summary information */
11562         { PR_5_PASS_HEADER,
11563           N_("Pass 5: Checking @g summary information\n"),
11564           PROMPT_NONE, 0 },
11565
11566         /* Padding at end of inode bitmap is not set. */
11567         { PR_5_INODE_BMAP_PADDING,
11568           N_("Padding at end of @i @B is not set. "),
11569           PROMPT_FIX, PR_PREEN_OK },
11570
11571         /* Padding at end of block bitmap is not set. */
11572         { PR_5_BLOCK_BMAP_PADDING,
11573           N_("Padding at end of @b @B is not set. "),
11574           PROMPT_FIX, PR_PREEN_OK },
11575
11576         /* Block bitmap differences header */
11577         { PR_5_BLOCK_BITMAP_HEADER,
11578           N_("@b @B differences: "),
11579           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
11580
11581         /* Block not used, but marked in bitmap */
11582         { PR_5_BLOCK_UNUSED,
11583           " -%b",
11584           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11585
11586         /* Block used, but not marked used in bitmap */
11587         { PR_5_BLOCK_USED,
11588           " +%b",
11589           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11590
11591         /* Block bitmap differences end */
11592         { PR_5_BLOCK_BITMAP_END,
11593           "\n",
11594           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11595
11596         /* Inode bitmap differences header */
11597         { PR_5_INODE_BITMAP_HEADER,
11598           N_("@i @B differences: "),
11599           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
11600
11601         /* Inode not used, but marked in bitmap */
11602         { PR_5_INODE_UNUSED,
11603           " -%i",
11604           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11605
11606         /* Inode used, but not marked used in bitmap */
11607         { PR_5_INODE_USED,
11608           " +%i",
11609           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11610
11611         /* Inode bitmap differences end */
11612         { PR_5_INODE_BITMAP_END,
11613           "\n",
11614           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11615
11616         /* Free inodes count for group wrong */
11617         { PR_5_FREE_INODE_COUNT_GROUP,
11618           N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
11619           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11620
11621         /* Directories count for group wrong */
11622         { PR_5_FREE_DIR_COUNT_GROUP,
11623           N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
11624           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11625
11626         /* Free inodes count wrong */
11627         { PR_5_FREE_INODE_COUNT,
11628           N_("Free @is count wrong (%i, counted=%j).\n"),
11629           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11630
11631         /* Free blocks count for group wrong */
11632         { PR_5_FREE_BLOCK_COUNT_GROUP,
11633           N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
11634           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11635
11636         /* Free blocks count wrong */
11637         { PR_5_FREE_BLOCK_COUNT,
11638           N_("Free @bs count wrong (%b, counted=%c).\n"),
11639           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11640
11641         /* Programming error: bitmap endpoints don't match */
11642         { PR_5_BMAP_ENDPOINTS,
11643           N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
11644           "match calculated @B endpoints (%i, %j)\n"),
11645           PROMPT_NONE, PR_FATAL },
11646
11647         /* Internal error: fudging end of bitmap */
11648         { PR_5_FUDGE_BITMAP_ERROR,
11649           N_("Internal error: fudging end of bitmap (%N)\n"),
11650           PROMPT_NONE, PR_FATAL },
11651
11652         /* Error copying in replacement inode bitmap */
11653         { PR_5_COPY_IBITMAP_ERROR,
11654           "Error copying in replacement @i @B: %m\n",
11655           PROMPT_NONE, PR_FATAL },
11656
11657         /* Error copying in replacement block bitmap */
11658         { PR_5_COPY_BBITMAP_ERROR,
11659           "Error copying in replacement @b @B: %m\n",
11660           PROMPT_NONE, PR_FATAL },
11661
11662         /* Block range not used, but marked in bitmap */
11663         { PR_5_BLOCK_RANGE_UNUSED,
11664           " -(%b--%c)",
11665           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11666
11667         /* Block range used, but not marked used in bitmap */
11668         { PR_5_BLOCK_RANGE_USED,
11669           " +(%b--%c)",
11670           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11671
11672         /* Inode range not used, but marked in bitmap */
11673         { PR_5_INODE_RANGE_UNUSED,
11674           " -(%i--%j)",
11675           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11676
11677         /* Inode range used, but not marked used in bitmap */
11678         { PR_5_INODE_RANGE_USED,
11679           " +(%i--%j)",
11680           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11681
11682         { 0 }
11683 };
11684
11685 /*
11686  * This is the latch flags register.  It allows several problems to be
11687  * "latched" together.  This means that the user has to answer but one
11688  * question for the set of problems, and all of the associated
11689  * problems will be either fixed or not fixed.
11690  */
11691 static struct latch_descr pr_latch_info[] = {
11692         { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
11693         { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
11694         { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
11695         { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
11696         { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
11697         { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
11698         { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
11699         { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
11700         { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
11701         { -1, 0, 0 },
11702 };
11703
11704 static const struct e2fsck_problem *find_problem(problem_t code)
11705 {
11706         int     i;
11707
11708         for (i=0; problem_table[i].e2p_code; i++) {
11709                 if (problem_table[i].e2p_code == code)
11710                         return &problem_table[i];
11711         }
11712         return 0;
11713 }
11714
11715 static struct latch_descr *find_latch(int code)
11716 {
11717         int     i;
11718
11719         for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
11720                 if (pr_latch_info[i].latch_code == code)
11721                         return &pr_latch_info[i];
11722         }
11723         return 0;
11724 }
11725
11726 int end_problem_latch(e2fsck_t ctx, int mask)
11727 {
11728         struct latch_descr *ldesc;
11729         struct problem_context pctx;
11730         int answer = -1;
11731
11732         ldesc = find_latch(mask);
11733         if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
11734                 clear_problem_context(&pctx);
11735                 answer = fix_problem(ctx, ldesc->end_message, &pctx);
11736         }
11737         ldesc->flags &= ~(PRL_VARIABLE);
11738         return answer;
11739 }
11740
11741 int set_latch_flags(int mask, int setflags, int clearflags)
11742 {
11743         struct latch_descr *ldesc;
11744
11745         ldesc = find_latch(mask);
11746         if (!ldesc)
11747                 return -1;
11748         ldesc->flags |= setflags;
11749         ldesc->flags &= ~clearflags;
11750         return 0;
11751 }
11752
11753 void clear_problem_context(struct problem_context *ctx)
11754 {
11755         memset(ctx, 0, sizeof(struct problem_context));
11756         ctx->blkcount = -1;
11757         ctx->group = -1;
11758 }
11759
11760 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
11761 {
11762         ext2_filsys fs = ctx->fs;
11763         const struct e2fsck_problem *ptr;
11764         struct latch_descr *ldesc = 0;
11765         const char *message;
11766         int             def_yn, answer, ans;
11767         int             print_answer = 0;
11768         int             suppress = 0;
11769
11770         ptr = find_problem(code);
11771         if (!ptr) {
11772                 printf(_("Unhandled error code (0x%x)!\n"), code);
11773                 return 0;
11774         }
11775         def_yn = 1;
11776         if ((ptr->flags & PR_NO_DEFAULT) ||
11777             ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
11778             (ctx->options & E2F_OPT_NO))
11779                 def_yn= 0;
11780
11781         /*
11782          * Do special latch processing.  This is where we ask the
11783          * latch question, if it exists
11784          */
11785         if (ptr->flags & PR_LATCH_MASK) {
11786                 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
11787                 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
11788                         ans = fix_problem(ctx, ldesc->question, pctx);
11789                         if (ans == 1)
11790                                 ldesc->flags |= PRL_YES;
11791                         if (ans == 0)
11792                                 ldesc->flags |= PRL_NO;
11793                         ldesc->flags |= PRL_LATCHED;
11794                 }
11795                 if (ldesc->flags & PRL_SUPPRESS)
11796                         suppress++;
11797         }
11798         if ((ptr->flags & PR_PREEN_NOMSG) &&
11799             (ctx->options & E2F_OPT_PREEN))
11800                 suppress++;
11801         if ((ptr->flags & PR_NO_NOMSG) &&
11802             (ctx->options & E2F_OPT_NO))
11803                 suppress++;
11804         if (!suppress) {
11805                 message = ptr->e2p_description;
11806                 if ((ctx->options & E2F_OPT_PREEN) &&
11807                     !(ptr->flags & PR_PREEN_NOHDR)) {
11808                         printf("%s: ", ctx->device_name ?
11809                                ctx->device_name : ctx->filesystem_name);
11810                 }
11811                 if (*message)
11812                         print_e2fsck_message(ctx, _(message), pctx, 1);
11813         }
11814         if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
11815                 preenhalt(ctx);
11816
11817         if (ptr->flags & PR_FATAL)
11818                 fatal_error(ctx, 0);
11819
11820         if (ptr->prompt == PROMPT_NONE) {
11821                 if (ptr->flags & PR_NOCOLLATE)
11822                         answer = -1;
11823                 else
11824                         answer = def_yn;
11825         } else {
11826                 if (ctx->options & E2F_OPT_PREEN) {
11827                         answer = def_yn;
11828                         if (!(ptr->flags & PR_PREEN_NOMSG))
11829                                 print_answer = 1;
11830                 } else if ((ptr->flags & PR_LATCH_MASK) &&
11831                            (ldesc->flags & (PRL_YES | PRL_NO))) {
11832                         if (!suppress)
11833                                 print_answer = 1;
11834                         if (ldesc->flags & PRL_YES)
11835                                 answer = 1;
11836                         else
11837                                 answer = 0;
11838                 } else
11839                         answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
11840                 if (!answer && !(ptr->flags & PR_NO_OK))
11841                         ext2fs_unmark_valid(fs);
11842
11843                 if (print_answer)
11844                         printf("%s.\n", answer ?
11845                                _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
11846
11847         }
11848
11849         if ((ptr->prompt == PROMPT_ABORT) && answer)
11850                 fatal_error(ctx, 0);
11851
11852         if (ptr->flags & PR_AFTER_CODE)
11853                 answer = fix_problem(ctx, ptr->second_code, pctx);
11854
11855         return answer;
11856 }
11857 /*
11858  * linux/fs/recovery.c
11859  *
11860  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
11861  *
11862  * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
11863  *
11864  * This file is part of the Linux kernel and is made available under
11865  * the terms of the GNU General Public License, version 2, or at your
11866  * option, any later version, incorporated herein by reference.
11867  *
11868  * Journal recovery routines for the generic filesystem journaling code;
11869  * part of the ext2fs journaling system.
11870  */
11871
11872 /*
11873  * Maintain information about the progress of the recovery job, so that
11874  * the different passes can carry information between them.
11875  */
11876 struct recovery_info
11877 {
11878         tid_t           start_transaction;
11879         tid_t           end_transaction;
11880
11881         int             nr_replays;
11882         int             nr_revokes;
11883         int             nr_revoke_hits;
11884 };
11885
11886 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
11887 static int do_one_pass(journal_t *journal,
11888                                 struct recovery_info *info, enum passtype pass);
11889 static int scan_revoke_records(journal_t *, struct buffer_head *,
11890                                 tid_t, struct recovery_info *);
11891
11892 #ifdef __KERNEL__
11893
11894 /* Release readahead buffers after use */
11895 void journal_brelse_array(struct buffer_head *b[], int n)
11896 {
11897         while (--n >= 0)
11898                 brelse (b[n]);
11899 }
11900
11901
11902 /*
11903  * When reading from the journal, we are going through the block device
11904  * layer directly and so there is no readahead being done for us.  We
11905  * need to implement any readahead ourselves if we want it to happen at
11906  * all.  Recovery is basically one long sequential read, so make sure we
11907  * do the IO in reasonably large chunks.
11908  *
11909  * This is not so critical that we need to be enormously clever about
11910  * the readahead size, though.  128K is a purely arbitrary, good-enough
11911  * fixed value.
11912  */
11913
11914 #define MAXBUF 8
11915 static int do_readahead(journal_t *journal, unsigned int start)
11916 {
11917         int err;
11918         unsigned int max, nbufs, next;
11919         unsigned long blocknr;
11920         struct buffer_head *bh;
11921
11922         struct buffer_head * bufs[MAXBUF];
11923
11924         /* Do up to 128K of readahead */
11925         max = start + (128 * 1024 / journal->j_blocksize);
11926         if (max > journal->j_maxlen)
11927                 max = journal->j_maxlen;
11928
11929         /* Do the readahead itself.  We'll submit MAXBUF buffer_heads at
11930          * a time to the block device IO layer. */
11931
11932         nbufs = 0;
11933
11934         for (next = start; next < max; next++) {
11935                 err = journal_bmap(journal, next, &blocknr);
11936
11937                 if (err) {
11938                         printk (KERN_ERR "JBD: bad block at offset %u\n",
11939                                 next);
11940                         goto failed;
11941                 }
11942
11943                 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
11944                 if (!bh) {
11945                         err = -ENOMEM;
11946                         goto failed;
11947                 }
11948
11949                 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
11950                         bufs[nbufs++] = bh;
11951                         if (nbufs == MAXBUF) {
11952                                 ll_rw_block(READ, nbufs, bufs);
11953                                 journal_brelse_array(bufs, nbufs);
11954                                 nbufs = 0;
11955                         }
11956                 } else
11957                         brelse(bh);
11958         }
11959
11960         if (nbufs)
11961                 ll_rw_block(READ, nbufs, bufs);
11962         err = 0;
11963
11964 failed:
11965         if (nbufs)
11966                 journal_brelse_array(bufs, nbufs);
11967         return err;
11968 }
11969
11970 #endif /* __KERNEL__ */
11971
11972
11973 /*
11974  * Read a block from the journal
11975  */
11976
11977 static int jread(struct buffer_head **bhp, journal_t *journal,
11978                  unsigned int offset)
11979 {
11980         int err;
11981         unsigned long blocknr;
11982         struct buffer_head *bh;
11983
11984         *bhp = NULL;
11985
11986         J_ASSERT (offset < journal->j_maxlen);
11987
11988         err = journal_bmap(journal, offset, &blocknr);
11989
11990         if (err) {
11991                 printk (KERN_ERR "JBD: bad block at offset %u\n",
11992                         offset);
11993                 return err;
11994         }
11995
11996         bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
11997         if (!bh)
11998                 return -ENOMEM;
11999
12000         if (!buffer_uptodate(bh)) {
12001                 /* If this is a brand new buffer, start readahead.
12002                    Otherwise, we assume we are already reading it.  */
12003                 if (!buffer_req(bh))
12004                         do_readahead(journal, offset);
12005                 wait_on_buffer(bh);
12006         }
12007
12008         if (!buffer_uptodate(bh)) {
12009                 printk (KERN_ERR "JBD: Failed to read block at offset %u\n",
12010                         offset);
12011                 brelse(bh);
12012                 return -EIO;
12013         }
12014
12015         *bhp = bh;
12016         return 0;
12017 }
12018
12019
12020 /*
12021  * Count the number of in-use tags in a journal descriptor block.
12022  */
12023
12024 static int count_tags(struct buffer_head *bh, int size)
12025 {
12026         char *                  tagp;
12027         journal_block_tag_t *   tag;
12028         int                     nr = 0;
12029
12030         tagp = &bh->b_data[sizeof(journal_header_t)];
12031
12032         while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
12033                 tag = (journal_block_tag_t *) tagp;
12034
12035                 nr++;
12036                 tagp += sizeof(journal_block_tag_t);
12037                 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
12038                         tagp += 16;
12039
12040                 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
12041                         break;
12042         }
12043
12044         return nr;
12045 }
12046
12047
12048 /* Make sure we wrap around the log correctly! */
12049 #define wrap(journal, var)                                              \
12050 do {                                                                    \
12051         if (var >= (journal)->j_last)                                   \
12052                 var -= ((journal)->j_last - (journal)->j_first);        \
12053 } while (0)
12054
12055 /**
12056  * int journal_recover(journal_t *journal) - recovers a on-disk journal
12057  * @journal: the journal to recover
12058  *
12059  * The primary function for recovering the log contents when mounting a
12060  * journaled device.
12061  *
12062  * Recovery is done in three passes.  In the first pass, we look for the
12063  * end of the log.  In the second, we assemble the list of revoke
12064  * blocks.  In the third and final pass, we replay any un-revoked blocks
12065  * in the log.
12066  */
12067 int journal_recover(journal_t *journal)
12068 {
12069         int                     err;
12070         journal_superblock_t *  sb;
12071
12072         struct recovery_info    info;
12073
12074         memset(&info, 0, sizeof(info));
12075         sb = journal->j_superblock;
12076
12077         /*
12078          * The journal superblock's s_start field (the current log head)
12079          * is always zero if, and only if, the journal was cleanly
12080          * unmounted.
12081          */
12082
12083         if (!sb->s_start) {
12084                 jbd_debug(1, "No recovery required, last transaction %d\n",
12085                           ntohl(sb->s_sequence));
12086                 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
12087                 return 0;
12088         }
12089
12090         err = do_one_pass(journal, &info, PASS_SCAN);
12091         if (!err)
12092                 err = do_one_pass(journal, &info, PASS_REVOKE);
12093         if (!err)
12094                 err = do_one_pass(journal, &info, PASS_REPLAY);
12095
12096         jbd_debug(0, "JBD: recovery, exit status %d, "
12097                   "recovered transactions %u to %u\n",
12098                   err, info.start_transaction, info.end_transaction);
12099         jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
12100                   info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
12101
12102         /* Restart the log at the next transaction ID, thus invalidating
12103          * any existing commit records in the log. */
12104         journal->j_transaction_sequence = ++info.end_transaction;
12105
12106         journal_clear_revoke(journal);
12107         sync_blockdev(journal->j_fs_dev);
12108         return err;
12109 }
12110
12111 static int do_one_pass(journal_t *journal,
12112                         struct recovery_info *info, enum passtype pass)
12113 {
12114         unsigned int            first_commit_ID, next_commit_ID;
12115         unsigned long           next_log_block;
12116         int                     err, success = 0;
12117         journal_superblock_t *  sb;
12118         journal_header_t *      tmp;
12119         struct buffer_head *    bh;
12120         unsigned int            sequence;
12121         int                     blocktype;
12122
12123         /* Precompute the maximum metadata descriptors in a descriptor block */
12124         int                     MAX_BLOCKS_PER_DESC;
12125         MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
12126                                / sizeof(journal_block_tag_t));
12127
12128         /*
12129          * First thing is to establish what we expect to find in the log
12130          * (in terms of transaction IDs), and where (in terms of log
12131          * block offsets): query the superblock.
12132          */
12133
12134         sb = journal->j_superblock;
12135         next_commit_ID = ntohl(sb->s_sequence);
12136         next_log_block = ntohl(sb->s_start);
12137
12138         first_commit_ID = next_commit_ID;
12139         if (pass == PASS_SCAN)
12140                 info->start_transaction = first_commit_ID;
12141
12142         jbd_debug(1, "Starting recovery pass %d\n", pass);
12143
12144         /*
12145          * Now we walk through the log, transaction by transaction,
12146          * making sure that each transaction has a commit block in the
12147          * expected place.  Each complete transaction gets replayed back
12148          * into the main filesystem.
12149          */
12150
12151         while (1) {
12152                 int                     flags;
12153                 char *                  tagp;
12154                 journal_block_tag_t *   tag;
12155                 struct buffer_head *    obh;
12156                 struct buffer_head *    nbh;
12157
12158                 /* If we already know where to stop the log traversal,
12159                  * check right now that we haven't gone past the end of
12160                  * the log. */
12161
12162                 if (pass != PASS_SCAN)
12163                         if (tid_geq(next_commit_ID, info->end_transaction))
12164                                 break;
12165
12166                 jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
12167                           next_commit_ID, next_log_block, journal->j_last);
12168
12169                 /* Skip over each chunk of the transaction looking
12170                  * either the next descriptor block or the final commit
12171                  * record. */
12172
12173                 jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
12174                 err = jread(&bh, journal, next_log_block);
12175                 if (err)
12176                         goto failed;
12177
12178                 next_log_block++;
12179                 wrap(journal, next_log_block);
12180
12181                 /* What kind of buffer is it?
12182                  *
12183                  * If it is a descriptor block, check that it has the
12184                  * expected sequence number.  Otherwise, we're all done
12185                  * here. */
12186
12187                 tmp = (journal_header_t *)bh->b_data;
12188
12189                 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
12190                         brelse(bh);
12191                         break;
12192                 }
12193
12194                 blocktype = ntohl(tmp->h_blocktype);
12195                 sequence = ntohl(tmp->h_sequence);
12196                 jbd_debug(3, "Found magic %d, sequence %d\n",
12197                           blocktype, sequence);
12198
12199                 if (sequence != next_commit_ID) {
12200                         brelse(bh);
12201                         break;
12202                 }
12203
12204                 /* OK, we have a valid descriptor block which matches
12205                  * all of the sequence number checks.  What are we going
12206                  * to do with it?  That depends on the pass... */
12207
12208                 switch(blocktype) {
12209                 case JFS_DESCRIPTOR_BLOCK:
12210                         /* If it is a valid descriptor block, replay it
12211                          * in pass REPLAY; otherwise, just skip over the
12212                          * blocks it describes. */
12213                         if (pass != PASS_REPLAY) {
12214                                 next_log_block +=
12215                                         count_tags(bh, journal->j_blocksize);
12216                                 wrap(journal, next_log_block);
12217                                 brelse(bh);
12218                                 continue;
12219                         }
12220
12221                         /* A descriptor block: we can now write all of
12222                          * the data blocks.  Yay, useful work is finally
12223                          * getting done here! */
12224
12225                         tagp = &bh->b_data[sizeof(journal_header_t)];
12226                         while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
12227                                <= journal->j_blocksize) {
12228                                 unsigned long io_block;
12229
12230                                 tag = (journal_block_tag_t *) tagp;
12231                                 flags = ntohl(tag->t_flags);
12232
12233                                 io_block = next_log_block++;
12234                                 wrap(journal, next_log_block);
12235                                 err = jread(&obh, journal, io_block);
12236                                 if (err) {
12237                                         /* Recover what we can, but
12238                                          * report failure at the end. */
12239                                         success = err;
12240                                         printk (KERN_ERR
12241                                                 "JBD: IO error %d recovering "
12242                                                 "block %ld in log\n",
12243                                                 err, io_block);
12244                                 } else {
12245                                         unsigned long blocknr;
12246
12247                                         J_ASSERT(obh != NULL);
12248                                         blocknr = ntohl(tag->t_blocknr);
12249
12250                                         /* If the block has been
12251                                          * revoked, then we're all done
12252                                          * here. */
12253                                         if (journal_test_revoke
12254                                             (journal, blocknr,
12255                                              next_commit_ID)) {
12256                                                 brelse(obh);
12257                                                 ++info->nr_revoke_hits;
12258                                                 goto skip_write;
12259                                         }
12260
12261                                         /* Find a buffer for the new
12262                                          * data being restored */
12263                                         nbh = __getblk(journal->j_fs_dev,
12264                                                        blocknr,
12265                                                      journal->j_blocksize);
12266                                         if (nbh == NULL) {
12267                                                 printk(KERN_ERR
12268                                                        "JBD: Out of memory "
12269                                                        "during recovery.\n");
12270                                                 err = -ENOMEM;
12271                                                 brelse(bh);
12272                                                 brelse(obh);
12273                                                 goto failed;
12274                                         }
12275
12276                                         lock_buffer(nbh);
12277                                         memcpy(nbh->b_data, obh->b_data,
12278                                                         journal->j_blocksize);
12279                                         if (flags & JFS_FLAG_ESCAPE) {
12280                                                 *((unsigned int *)bh->b_data) =
12281                                                         htonl(JFS_MAGIC_NUMBER);
12282                                         }
12283
12284                                         BUFFER_TRACE(nbh, "marking dirty");
12285                                         set_buffer_uptodate(nbh);
12286                                         mark_buffer_dirty(nbh);
12287                                         BUFFER_TRACE(nbh, "marking uptodate");
12288                                         ++info->nr_replays;
12289                                         /* ll_rw_block(WRITE, 1, &nbh); */
12290                                         unlock_buffer(nbh);
12291                                         brelse(obh);
12292                                         brelse(nbh);
12293                                 }
12294
12295                         skip_write:
12296                                 tagp += sizeof(journal_block_tag_t);
12297                                 if (!(flags & JFS_FLAG_SAME_UUID))
12298                                         tagp += 16;
12299
12300                                 if (flags & JFS_FLAG_LAST_TAG)
12301                                         break;
12302                         }
12303
12304                         brelse(bh);
12305                         continue;
12306
12307                 case JFS_COMMIT_BLOCK:
12308                         /* Found an expected commit block: not much to
12309                          * do other than move on to the next sequence
12310                          * number. */
12311                         brelse(bh);
12312                         next_commit_ID++;
12313                         continue;
12314
12315                 case JFS_REVOKE_BLOCK:
12316                         /* If we aren't in the REVOKE pass, then we can
12317                          * just skip over this block. */
12318                         if (pass != PASS_REVOKE) {
12319                                 brelse(bh);
12320                                 continue;
12321                         }
12322
12323                         err = scan_revoke_records(journal, bh,
12324                                                   next_commit_ID, info);
12325                         brelse(bh);
12326                         if (err)
12327                                 goto failed;
12328                         continue;
12329
12330                 default:
12331                         jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
12332                                   blocktype);
12333                         goto done;
12334                 }
12335         }
12336
12337  done:
12338         /*
12339          * We broke out of the log scan loop: either we came to the
12340          * known end of the log or we found an unexpected block in the
12341          * log.  If the latter happened, then we know that the "current"
12342          * transaction marks the end of the valid log.
12343          */
12344
12345         if (pass == PASS_SCAN)
12346                 info->end_transaction = next_commit_ID;
12347         else {
12348                 /* It's really bad news if different passes end up at
12349                  * different places (but possible due to IO errors). */
12350                 if (info->end_transaction != next_commit_ID) {
12351                         printk (KERN_ERR "JBD: recovery pass %d ended at "
12352                                 "transaction %u, expected %u\n",
12353                                 pass, next_commit_ID, info->end_transaction);
12354                         if (!success)
12355                                 success = -EIO;
12356                 }
12357         }
12358
12359         return success;
12360
12361  failed:
12362         return err;
12363 }
12364
12365
12366 /* Scan a revoke record, marking all blocks mentioned as revoked. */
12367
12368 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
12369                                tid_t sequence, struct recovery_info *info)
12370 {
12371         journal_revoke_header_t *header;
12372         int offset, max;
12373
12374         header = (journal_revoke_header_t *) bh->b_data;
12375         offset = sizeof(journal_revoke_header_t);
12376         max = ntohl(header->r_count);
12377
12378         while (offset < max) {
12379                 unsigned long blocknr;
12380                 int err;
12381
12382                 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
12383                 offset += 4;
12384                 err = journal_set_revoke(journal, blocknr, sequence);
12385                 if (err)
12386                         return err;
12387                 ++info->nr_revokes;
12388         }
12389         return 0;
12390 }
12391 /*
12392  * region.c --- code which manages allocations within a region.
12393  *
12394  * Copyright (C) 2001 Theodore Ts'o.
12395  *
12396  * %Begin-Header%
12397  * This file may be redistributed under the terms of the GNU Public
12398  * License.
12399  * %End-Header%
12400  */
12401
12402 struct region_el {
12403         region_addr_t   start;
12404         region_addr_t   end;
12405         struct region_el *next;
12406 };
12407
12408 struct region_struct {
12409         region_addr_t   min;
12410         region_addr_t   max;
12411         struct region_el *allocated;
12412 };
12413
12414 region_t region_create(region_addr_t min, region_addr_t max)
12415 {
12416         region_t        region;
12417
12418         region = malloc(sizeof(struct region_struct));
12419         if (!region)
12420                 return NULL;
12421         memset(region, 0, sizeof(struct region_struct));
12422         region->min = min;
12423         region->max = max;
12424         return region;
12425 }
12426
12427 void region_free(region_t region)
12428 {
12429         struct region_el        *r, *next;
12430
12431         for (r = region->allocated; r; r = next) {
12432                 next = r->next;
12433                 free(r);
12434         }
12435         memset(region, 0, sizeof(struct region_struct));
12436         free(region);
12437 }
12438
12439 int region_allocate(region_t region, region_addr_t start, int n)
12440 {
12441         struct region_el        *r, *new_region, *prev, *next;
12442         region_addr_t end;
12443
12444         end = start+n;
12445         if ((start < region->min) || (end > region->max))
12446                 return -1;
12447         if (n == 0)
12448                 return 1;
12449
12450         /*
12451          * Search through the linked list.  If we find that it
12452          * conflicts witih something that's already allocated, return
12453          * 1; if we can find an existing region which we can grow, do
12454          * so.  Otherwise, stop when we find the appropriate place
12455          * insert a new region element into the linked list.
12456          */
12457         for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
12458                 if (((start >= r->start) && (start < r->end)) ||
12459                     ((end > r->start) && (end <= r->end)) ||
12460                     ((start <= r->start) && (end >= r->end)))
12461                         return 1;
12462                 if (end == r->start) {
12463                         r->start = start;
12464                         return 0;
12465                 }
12466                 if (start == r->end) {
12467                         if ((next = r->next)) {
12468                                 if (end > next->start)
12469                                         return 1;
12470                                 if (end == next->start) {
12471                                         r->end = next->end;
12472                                         r->next = next->next;
12473                                         free(next);
12474                                         return 0;
12475                                 }
12476                         }
12477                         r->end = end;
12478                         return 0;
12479                 }
12480                 if (start < r->start)
12481                         break;
12482         }
12483         /*
12484          * Insert a new region element structure into the linked list
12485          */
12486         new_region = malloc(sizeof(struct region_el));
12487         if (!new_region)
12488                 return -1;
12489         new_region->start = start;
12490         new_region->end = start + n;
12491         new_region->next = r;
12492         if (prev)
12493                 prev->next = new_region;
12494         else
12495                 region->allocated = new_region;
12496         return 0;
12497 }
12498
12499 /*
12500  * rehash.c --- rebuild hash tree directories
12501  *
12502  * Copyright (C) 2002 Theodore Ts'o
12503  *
12504  * %Begin-Header%
12505  * This file may be redistributed under the terms of the GNU Public
12506  * License.
12507  * %End-Header%
12508  *
12509  * This algorithm is designed for simplicity of implementation and to
12510  * pack the directory as much as possible.  It however requires twice
12511  * as much memory as the size of the directory.  The maximum size
12512  * directory supported using a 4k blocksize is roughly a gigabyte, and
12513  * so there may very well be problems with machines that don't have
12514  * virtual memory, and obscenely large directories.
12515  *
12516  * An alternate algorithm which is much more disk intensive could be
12517  * written, and probably will need to be written in the future.  The
12518  * design goals of such an algorithm are: (a) use (roughly) constant
12519  * amounts of memory, no matter how large the directory, (b) the
12520  * directory must be safe at all times, even if e2fsck is interrupted
12521  * in the middle, (c) we must use minimal amounts of extra disk
12522  * blocks.  This pretty much requires an incremental approach, where
12523  * we are reading from one part of the directory, and inserting into
12524  * the front half.  So the algorithm will have to keep track of a
12525  * moving block boundary between the new tree and the old tree, and
12526  * files will need to be moved from the old directory and inserted
12527  * into the new tree.  If the new directory requires space which isn't
12528  * yet available, blocks from the beginning part of the old directory
12529  * may need to be moved to the end of the directory to make room for
12530  * the new tree:
12531  *
12532  *    --------------------------------------------------------
12533  *    |  new tree   |        | old tree                      |
12534  *    --------------------------------------------------------
12535  *                  ^ ptr    ^ptr
12536  *                tail new   head old
12537  *
12538  * This is going to be a pain in the tuckus to implement, and will
12539  * require a lot more disk accesses.  So I'm going to skip it for now;
12540  * it's only really going to be an issue for really, really big
12541  * filesystems (when we reach the level of tens of millions of files
12542  * in a single directory).  It will probably be easier to simply
12543  * require that e2fsck use VM first.
12544  */
12545
12546 struct fill_dir_struct {
12547         char *buf;
12548         struct ext2_inode *inode;
12549         int err;
12550         e2fsck_t ctx;
12551         struct hash_entry *harray;
12552         int max_array, num_array;
12553         int dir_size;
12554         int compress;
12555         ino_t parent;
12556 };
12557
12558 struct hash_entry {
12559         ext2_dirhash_t  hash;
12560         ext2_dirhash_t  minor_hash;
12561         struct ext2_dir_entry   *dir;
12562 };
12563
12564 struct out_dir {
12565         int             num;
12566         int             max;
12567         char            *buf;
12568         ext2_dirhash_t  *hashes;
12569 };
12570
12571 static int fill_dir_block(ext2_filsys fs,
12572                           blk_t *block_nr,
12573                           e2_blkcnt_t blockcnt,
12574                           blk_t ref_block EXT2FS_ATTR((unused)),
12575                           int ref_offset EXT2FS_ATTR((unused)),
12576                           void *priv_data)
12577 {
12578         struct fill_dir_struct  *fd = (struct fill_dir_struct *) priv_data;
12579         struct hash_entry       *new_array, *ent;
12580         struct ext2_dir_entry   *dirent;
12581         char                    *dir;
12582         unsigned int            offset, dir_offset;
12583
12584         if (blockcnt < 0)
12585                 return 0;
12586
12587         offset = blockcnt * fs->blocksize;
12588         if (offset + fs->blocksize > fd->inode->i_size) {
12589                 fd->err = EXT2_ET_DIR_CORRUPTED;
12590                 return BLOCK_ABORT;
12591         }
12592         dir = (fd->buf+offset);
12593         if (HOLE_BLKADDR(*block_nr)) {
12594                 memset(dir, 0, fs->blocksize);
12595                 dirent = (struct ext2_dir_entry *) dir;
12596                 dirent->rec_len = fs->blocksize;
12597         } else {
12598                 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
12599                 if (fd->err)
12600                         return BLOCK_ABORT;
12601         }
12602         /* While the directory block is "hot", index it. */
12603         dir_offset = 0;
12604         while (dir_offset < fs->blocksize) {
12605                 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
12606                 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
12607                     (dirent->rec_len < 8) ||
12608                     ((dirent->rec_len % 4) != 0) ||
12609                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
12610                         fd->err = EXT2_ET_DIR_CORRUPTED;
12611                         return BLOCK_ABORT;
12612                 }
12613                 dir_offset += dirent->rec_len;
12614                 if (dirent->inode == 0)
12615                         continue;
12616                 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
12617                     (dirent->name[0] == '.'))
12618                         continue;
12619                 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
12620                     (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
12621                         fd->parent = dirent->inode;
12622                         continue;
12623                 }
12624                 if (fd->num_array >= fd->max_array) {
12625                         new_array = realloc(fd->harray,
12626                             sizeof(struct hash_entry) * (fd->max_array+500));
12627                         if (!new_array) {
12628                                 fd->err = ENOMEM;
12629                                 return BLOCK_ABORT;
12630                         }
12631                         fd->harray = new_array;
12632                         fd->max_array += 500;
12633                 }
12634                 ent = fd->harray + fd->num_array++;
12635                 ent->dir = dirent;
12636                 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
12637                 if (fd->compress)
12638                         ent->hash = ent->minor_hash = 0;
12639                 else {
12640                         fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
12641                                                  dirent->name,
12642                                                  dirent->name_len & 0xFF,
12643                                                  fs->super->s_hash_seed,
12644                                                  &ent->hash, &ent->minor_hash);
12645                         if (fd->err)
12646                                 return BLOCK_ABORT;
12647                 }
12648         }
12649
12650         return 0;
12651 }
12652
12653 /* Used for sorting the hash entry */
12654 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
12655 {
12656         const struct hash_entry *he_a = (const struct hash_entry *) a;
12657         const struct hash_entry *he_b = (const struct hash_entry *) b;
12658         int     ret;
12659         int     min_len;
12660
12661         min_len = he_a->dir->name_len;
12662         if (min_len > he_b->dir->name_len)
12663                 min_len = he_b->dir->name_len;
12664
12665         ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
12666         if (ret == 0) {
12667                 if (he_a->dir->name_len > he_b->dir->name_len)
12668                         ret = 1;
12669                 else if (he_a->dir->name_len < he_b->dir->name_len)
12670                         ret = -1;
12671                 else
12672                         ret = he_b->dir->inode - he_a->dir->inode;
12673         }
12674         return ret;
12675 }
12676
12677 /* Used for sorting the hash entry */
12678 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
12679 {
12680         const struct hash_entry *he_a = (const struct hash_entry *) a;
12681         const struct hash_entry *he_b = (const struct hash_entry *) b;
12682         int     ret;
12683
12684         if (he_a->hash > he_b->hash)
12685                 ret = 1;
12686         else if (he_a->hash < he_b->hash)
12687                 ret = -1;
12688         else {
12689                 if (he_a->minor_hash > he_b->minor_hash)
12690                         ret = 1;
12691                 else if (he_a->minor_hash < he_b->minor_hash)
12692                         ret = -1;
12693                 else
12694                         ret = name_cmp(a, b);
12695         }
12696         return ret;
12697 }
12698
12699 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
12700                                 int blocks)
12701 {
12702         void                    *new_mem;
12703
12704         if (outdir->max) {
12705                 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
12706                 if (!new_mem)
12707                         return ENOMEM;
12708                 outdir->buf = new_mem;
12709                 new_mem = realloc(outdir->hashes,
12710                                   blocks * sizeof(ext2_dirhash_t));
12711                 if (!new_mem)
12712                         return ENOMEM;
12713                 outdir->hashes = new_mem;
12714         } else {
12715                 outdir->buf = malloc(blocks * fs->blocksize);
12716                 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
12717                 outdir->num = 0;
12718         }
12719         outdir->max = blocks;
12720         return 0;
12721 }
12722
12723 static void free_out_dir(struct out_dir *outdir)
12724 {
12725         if (outdir->buf)
12726                 free(outdir->buf);
12727         if (outdir->hashes)
12728                 free(outdir->hashes);
12729         outdir->max = 0;
12730         outdir->num =0;
12731 }
12732
12733 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
12734                          char ** ret)
12735 {
12736         errcode_t       retval;
12737
12738         if (outdir->num >= outdir->max) {
12739                 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
12740                 if (retval)
12741                         return retval;
12742         }
12743         *ret = outdir->buf + (outdir->num++ * fs->blocksize);
12744         memset(*ret, 0, fs->blocksize);
12745         return 0;
12746 }
12747
12748 /*
12749  * This function is used to make a unique filename.  We do this by
12750  * appending ~0, and then incrementing the number.  However, we cannot
12751  * expand the length of the filename beyond the padding available in
12752  * the directory entry.
12753  */
12754 static void mutate_name(char *str, __u16 *len)
12755 {
12756         int     i;
12757         __u16   l = *len & 0xFF, h = *len & 0xff00;
12758
12759         /*
12760          * First check to see if it looks the name has been mutated
12761          * already
12762          */
12763         for (i = l-1; i > 0; i--) {
12764                 if (!isdigit(str[i]))
12765                         break;
12766         }
12767         if ((i == l-1) || (str[i] != '~')) {
12768                 if (((l-1) & 3) < 2)
12769                         l += 2;
12770                 else
12771                         l = (l+3) & ~3;
12772                 str[l-2] = '~';
12773                 str[l-1] = '0';
12774                 *len = l | h;
12775                 return;
12776         }
12777         for (i = l-1; i >= 0; i--) {
12778                 if (isdigit(str[i])) {
12779                         if (str[i] == '9')
12780                                 str[i] = '0';
12781                         else {
12782                                 str[i]++;
12783                                 return;
12784                         }
12785                         continue;
12786                 }
12787                 if (i == 1) {
12788                         if (str[0] == 'z')
12789                                 str[0] = 'A';
12790                         else if (str[0] == 'Z') {
12791                                 str[0] = '~';
12792                                 str[1] = '0';
12793                         } else
12794                                 str[0]++;
12795                 } else if (i > 0) {
12796                         str[i] = '1';
12797                         str[i-1] = '~';
12798                 } else {
12799                         if (str[0] == '~')
12800                                 str[0] = 'a';
12801                         else
12802                                 str[0]++;
12803                 }
12804                 break;
12805         }
12806 }
12807
12808 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
12809                                     ext2_ino_t ino,
12810                                     struct fill_dir_struct *fd)
12811 {
12812         struct problem_context  pctx;
12813         struct hash_entry       *ent, *prev;
12814         int                     i, j;
12815         int                     fixed = 0;
12816         char                    new_name[256];
12817         __u16                   new_len;
12818
12819         clear_problem_context(&pctx);
12820         pctx.ino = ino;
12821
12822         for (i=1; i < fd->num_array; i++) {
12823                 ent = fd->harray + i;
12824                 prev = ent - 1;
12825                 if (!ent->dir->inode ||
12826                     ((ent->dir->name_len & 0xFF) !=
12827                      (prev->dir->name_len & 0xFF)) ||
12828                     (strncmp(ent->dir->name, prev->dir->name,
12829                              ent->dir->name_len & 0xFF)))
12830                         continue;
12831                 pctx.dirent = ent->dir;
12832                 if ((ent->dir->inode == prev->dir->inode) &&
12833                     fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
12834                         e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
12835                         ent->dir->inode = 0;
12836                         fixed++;
12837                         continue;
12838                 }
12839                 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
12840                 new_len = ent->dir->name_len;
12841                 mutate_name(new_name, &new_len);
12842                 for (j=0; j < fd->num_array; j++) {
12843                         if ((i==j) ||
12844                             ((ent->dir->name_len & 0xFF) !=
12845                              (fd->harray[j].dir->name_len & 0xFF)) ||
12846                             (strncmp(new_name, fd->harray[j].dir->name,
12847                                      new_len & 0xFF)))
12848                                 continue;
12849                         mutate_name(new_name, &new_len);
12850
12851                         j = -1;
12852                 }
12853                 new_name[new_len & 0xFF] = 0;
12854                 pctx.str = new_name;
12855                 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
12856                         memcpy(ent->dir->name, new_name, new_len & 0xFF);
12857                         ent->dir->name_len = new_len;
12858                         ext2fs_dirhash(fs->super->s_def_hash_version,
12859                                        ent->dir->name,
12860                                        ent->dir->name_len & 0xFF,
12861                                        fs->super->s_hash_seed,
12862                                        &ent->hash, &ent->minor_hash);
12863                         fixed++;
12864                 }
12865         }
12866         return fixed;
12867 }
12868
12869
12870 static errcode_t copy_dir_entries(ext2_filsys fs,
12871                                   struct fill_dir_struct *fd,
12872                                   struct out_dir *outdir)
12873 {
12874         errcode_t               retval;
12875         char                    *block_start;
12876         struct hash_entry       *ent;
12877         struct ext2_dir_entry   *dirent;
12878         int                     i, rec_len, left;
12879         ext2_dirhash_t          prev_hash;
12880         int                     offset;
12881
12882         outdir->max = 0;
12883         retval = alloc_size_dir(fs, outdir,
12884                                 (fd->dir_size / fs->blocksize) + 2);
12885         if (retval)
12886                 return retval;
12887         outdir->num = fd->compress ? 0 : 1;
12888         offset = 0;
12889         outdir->hashes[0] = 0;
12890         prev_hash = 1;
12891         if ((retval = get_next_block(fs, outdir, &block_start)))
12892                 return retval;
12893         dirent = (struct ext2_dir_entry *) block_start;
12894         left = fs->blocksize;
12895         for (i=0; i < fd->num_array; i++) {
12896                 ent = fd->harray + i;
12897                 if (ent->dir->inode == 0)
12898                         continue;
12899                 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
12900                 if (rec_len > left) {
12901                         if (left)
12902                                 dirent->rec_len += left;
12903                         if ((retval = get_next_block(fs, outdir,
12904                                                       &block_start)))
12905                                 return retval;
12906                         offset = 0;
12907                 }
12908                 left = fs->blocksize - offset;
12909                 dirent = (struct ext2_dir_entry *) (block_start + offset);
12910                 if (offset == 0) {
12911                         if (ent->hash == prev_hash)
12912                                 outdir->hashes[outdir->num-1] = ent->hash | 1;
12913                         else
12914                                 outdir->hashes[outdir->num-1] = ent->hash;
12915                 }
12916                 dirent->inode = ent->dir->inode;
12917                 dirent->name_len = ent->dir->name_len;
12918                 dirent->rec_len = rec_len;
12919                 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
12920                 offset += rec_len;
12921                 left -= rec_len;
12922                 if (left < 12) {
12923                         dirent->rec_len += left;
12924                         offset += left;
12925                         left = 0;
12926                 }
12927                 prev_hash = ent->hash;
12928         }
12929         if (left)
12930                 dirent->rec_len += left;
12931
12932         return 0;
12933 }
12934
12935
12936 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
12937                                     ext2_ino_t ino, ext2_ino_t parent)
12938 {
12939         struct ext2_dir_entry           *dir;
12940         struct ext2_dx_root_info        *root;
12941         struct ext2_dx_countlimit       *limits;
12942         int                             filetype = 0;
12943
12944         if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
12945                 filetype = EXT2_FT_DIR << 8;
12946
12947         memset(buf, 0, fs->blocksize);
12948         dir = (struct ext2_dir_entry *) buf;
12949         dir->inode = ino;
12950         dir->name[0] = '.';
12951         dir->name_len = 1 | filetype;
12952         dir->rec_len = 12;
12953         dir = (struct ext2_dir_entry *) (buf + 12);
12954         dir->inode = parent;
12955         dir->name[0] = '.';
12956         dir->name[1] = '.';
12957         dir->name_len = 2 | filetype;
12958         dir->rec_len = fs->blocksize - 12;
12959
12960         root = (struct ext2_dx_root_info *) (buf+24);
12961         root->reserved_zero = 0;
12962         root->hash_version = fs->super->s_def_hash_version;
12963         root->info_length = 8;
12964         root->indirect_levels = 0;
12965         root->unused_flags = 0;
12966
12967         limits = (struct ext2_dx_countlimit *) (buf+32);
12968         limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
12969         limits->count = 0;
12970
12971         return root;
12972 }
12973
12974
12975 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
12976 {
12977         struct ext2_dir_entry           *dir;
12978         struct ext2_dx_countlimit       *limits;
12979
12980         memset(buf, 0, fs->blocksize);
12981         dir = (struct ext2_dir_entry *) buf;
12982         dir->inode = 0;
12983         dir->rec_len = fs->blocksize;
12984
12985         limits = (struct ext2_dx_countlimit *) (buf+8);
12986         limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
12987         limits->count = 0;
12988
12989         return (struct ext2_dx_entry *) limits;
12990 }
12991
12992 /*
12993  * This function takes the leaf nodes which have been written in
12994  * outdir, and populates the root node and any necessary interior nodes.
12995  */
12996 static errcode_t calculate_tree(ext2_filsys fs,
12997                                 struct out_dir *outdir,
12998                                 ext2_ino_t ino,
12999                                 ext2_ino_t parent)
13000 {
13001         struct ext2_dx_root_info        *root_info;
13002         struct ext2_dx_entry            *root, *dx_ent = 0;
13003         struct ext2_dx_countlimit       *root_limit, *limit;
13004         errcode_t                       retval;
13005         char                            * block_start;
13006         int                             i, c1, c2, nblks;
13007         int                             limit_offset, root_offset;
13008
13009         root_info = set_root_node(fs, outdir->buf, ino, parent);
13010         root_offset = limit_offset = ((char *) root_info - outdir->buf) +
13011                 root_info->info_length;
13012         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
13013         c1 = root_limit->limit;
13014         nblks = outdir->num;
13015
13016         /* Write out the pointer blocks */
13017         if (nblks-1 <= c1) {
13018                 /* Just write out the root block, and we're done */
13019                 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
13020                 for (i=1; i < nblks; i++) {
13021                         root->block = ext2fs_cpu_to_le32(i);
13022                         if (i != 1)
13023                                 root->hash =
13024                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
13025                         root++;
13026                         c1--;
13027                 }
13028         } else {
13029                 c2 = 0;
13030                 limit = 0;
13031                 root_info->indirect_levels = 1;
13032                 for (i=1; i < nblks; i++) {
13033                         if (c1 == 0)
13034                                 return ENOSPC;
13035                         if (c2 == 0) {
13036                                 if (limit)
13037                                         limit->limit = limit->count =
13038                 ext2fs_cpu_to_le16(limit->limit);
13039                                 root = (struct ext2_dx_entry *)
13040                                         (outdir->buf + root_offset);
13041                                 root->block = ext2fs_cpu_to_le32(outdir->num);
13042                                 if (i != 1)
13043                                         root->hash =
13044                         ext2fs_cpu_to_le32(outdir->hashes[i]);
13045                                 if ((retval =  get_next_block(fs, outdir,
13046                                                               &block_start)))
13047                                         return retval;
13048                                 dx_ent = set_int_node(fs, block_start);
13049                                 limit = (struct ext2_dx_countlimit *) dx_ent;
13050                                 c2 = limit->limit;
13051                                 root_offset += sizeof(struct ext2_dx_entry);
13052                                 c1--;
13053                         }
13054                         dx_ent->block = ext2fs_cpu_to_le32(i);
13055                         if (c2 != limit->limit)
13056                                 dx_ent->hash =
13057                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
13058                         dx_ent++;
13059                         c2--;
13060                 }
13061                 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
13062                 limit->limit = ext2fs_cpu_to_le16(limit->limit);
13063         }
13064         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
13065         root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
13066         root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
13067
13068         return 0;
13069 }
13070
13071 struct write_dir_struct {
13072         struct out_dir *outdir;
13073         errcode_t       err;
13074         e2fsck_t        ctx;
13075         int             cleared;
13076 };
13077
13078 /*
13079  * Helper function which writes out a directory block.
13080  */
13081 static int write_dir_block(ext2_filsys fs,
13082                            blk_t        *block_nr,
13083                            e2_blkcnt_t blockcnt,
13084                            blk_t ref_block EXT2FS_ATTR((unused)),
13085                            int ref_offset EXT2FS_ATTR((unused)),
13086                            void *priv_data)
13087 {
13088         struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
13089         blk_t   blk;
13090         char    *dir;
13091
13092         if (*block_nr == 0)
13093                 return 0;
13094         if (blockcnt >= wd->outdir->num) {
13095                 e2fsck_read_bitmaps(wd->ctx);
13096                 blk = *block_nr;
13097                 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
13098                 ext2fs_block_alloc_stats(fs, blk, -1);
13099                 *block_nr = 0;
13100                 wd->cleared++;
13101                 return BLOCK_CHANGED;
13102         }
13103         if (blockcnt < 0)
13104                 return 0;
13105
13106         dir = wd->outdir->buf + (blockcnt * fs->blocksize);
13107         wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
13108         if (wd->err)
13109                 return BLOCK_ABORT;
13110         return 0;
13111 }
13112
13113 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
13114                                  struct out_dir *outdir,
13115                                  ext2_ino_t ino, int compress)
13116 {
13117         struct write_dir_struct wd;
13118         errcode_t       retval;
13119         struct ext2_inode       inode;
13120
13121         retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
13122         if (retval)
13123                 return retval;
13124
13125         wd.outdir = outdir;
13126         wd.err = 0;
13127         wd.ctx = ctx;
13128         wd.cleared = 0;
13129
13130         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
13131                                        write_dir_block, &wd);
13132         if (retval)
13133                 return retval;
13134         if (wd.err)
13135                 return wd.err;
13136
13137         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
13138         if (compress)
13139                 inode.i_flags &= ~EXT2_INDEX_FL;
13140         else
13141                 inode.i_flags |= EXT2_INDEX_FL;
13142         inode.i_size = outdir->num * fs->blocksize;
13143         inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
13144         e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
13145
13146         return 0;
13147 }
13148
13149 errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
13150 {
13151         ext2_filsys             fs = ctx->fs;
13152         errcode_t               retval;
13153         struct ext2_inode       inode;
13154         char                    *dir_buf = 0;
13155         struct fill_dir_struct  fd;
13156         struct out_dir          outdir;
13157
13158         outdir.max = outdir.num = 0;
13159         outdir.buf = 0;
13160         outdir.hashes = 0;
13161         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
13162
13163         retval = ENOMEM;
13164         fd.harray = 0;
13165         dir_buf = malloc(inode.i_size);
13166         if (!dir_buf)
13167                 goto errout;
13168
13169         fd.max_array = inode.i_size / 32;
13170         fd.num_array = 0;
13171         fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
13172         if (!fd.harray)
13173                 goto errout;
13174
13175         fd.ctx = ctx;
13176         fd.buf = dir_buf;
13177         fd.inode = &inode;
13178         fd.err = 0;
13179         fd.dir_size = 0;
13180         fd.compress = 0;
13181         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
13182             (inode.i_size / fs->blocksize) < 2)
13183                 fd.compress = 1;
13184         fd.parent = 0;
13185
13186         /* Read in the entire directory into memory */
13187         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
13188                                        fill_dir_block, &fd);
13189         if (fd.err) {
13190                 retval = fd.err;
13191                 goto errout;
13192         }
13193
13194 #if 0
13195         printf("%d entries (%d bytes) found in inode %d\n",
13196                fd.num_array, fd.dir_size, ino);
13197 #endif
13198
13199         /* Sort the list */
13200 resort:
13201         if (fd.compress)
13202                 qsort(fd.harray+2, fd.num_array-2,
13203                       sizeof(struct hash_entry), name_cmp);
13204         else
13205                 qsort(fd.harray, fd.num_array,
13206                       sizeof(struct hash_entry), hash_cmp);
13207
13208         /*
13209          * Look for duplicates
13210          */
13211         if (duplicate_search_and_fix(ctx, fs, ino, &fd))
13212                 goto resort;
13213
13214         if (ctx->options & E2F_OPT_NO) {
13215                 retval = 0;
13216                 goto errout;
13217         }
13218
13219         /*
13220          * Copy the directory entries.  In a htree directory these
13221          * will become the leaf nodes.
13222          */
13223         retval = copy_dir_entries(fs, &fd, &outdir);
13224         if (retval)
13225                 goto errout;
13226
13227         free(dir_buf); dir_buf = 0;
13228
13229         if (!fd.compress) {
13230                 /* Calculate the interior nodes */
13231                 retval = calculate_tree(fs, &outdir, ino, fd.parent);
13232                 if (retval)
13233                         goto errout;
13234         }
13235
13236         retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
13237         if (retval)
13238                 goto errout;
13239
13240 errout:
13241         if (dir_buf)
13242                 free(dir_buf);
13243         if (fd.harray)
13244                 free(fd.harray);
13245
13246         free_out_dir(&outdir);
13247         return retval;
13248 }
13249
13250 void e2fsck_rehash_directories(e2fsck_t ctx)
13251 {
13252         struct problem_context  pctx;
13253 #ifdef RESOURCE_TRACK
13254         struct resource_track   rtrack;
13255 #endif
13256         struct dir_info         *dir;
13257         ext2_u32_iterate        iter;
13258         ext2_ino_t              ino;
13259         errcode_t               retval;
13260         int                     i, cur, max, all_dirs, dir_index, first = 1;
13261
13262 #ifdef RESOURCE_TRACK
13263         init_resource_track(&rtrack);
13264 #endif
13265
13266         all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
13267
13268         if (!ctx->dirs_to_hash && !all_dirs)
13269                 return;
13270
13271         e2fsck_get_lost_and_found(ctx, 0);
13272
13273         clear_problem_context(&pctx);
13274
13275         dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
13276         cur = 0;
13277         if (all_dirs) {
13278                 i = 0;
13279                 max = e2fsck_get_num_dirinfo(ctx);
13280         } else {
13281                 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
13282                                                        &iter);
13283                 if (retval) {
13284                         pctx.errcode = retval;
13285                         fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
13286                         return;
13287                 }
13288                 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
13289         }
13290         while (1) {
13291                 if (all_dirs) {
13292                         if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
13293                                 break;
13294                         ino = dir->ino;
13295                 } else {
13296                         if (!ext2fs_u32_list_iterate(iter, &ino))
13297                                 break;
13298                 }
13299                 if (ino == ctx->lost_and_found)
13300                         continue;
13301                 pctx.dir = ino;
13302                 if (first) {
13303                         fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
13304                         first = 0;
13305                 }
13306 #if 0
13307                 fix_problem(ctx, PR_3A_OPTIMIZE_DIR, &pctx);
13308 #endif
13309                 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
13310                 if (pctx.errcode) {
13311                         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
13312                         fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
13313                 }
13314                 if (ctx->progress && !ctx->progress_fd)
13315                         e2fsck_simple_progress(ctx, "Rebuilding directory",
13316                                100.0 * (float) (++cur) / (float) max, ino);
13317         }
13318         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
13319         if (!all_dirs)
13320                 ext2fs_u32_list_iterate_end(iter);
13321
13322         if (ctx->dirs_to_hash)
13323                 ext2fs_u32_list_free(ctx->dirs_to_hash);
13324         ctx->dirs_to_hash = 0;
13325
13326 #ifdef RESOURCE_TRACK
13327         if (ctx->options & E2F_OPT_TIME2) {
13328                 e2fsck_clear_progbar(ctx);
13329                 print_resource_track("Pass 3A", &rtrack);
13330         }
13331 #endif
13332 }
13333 /*
13334  * linux/fs/revoke.c
13335  *
13336  * Written by Stephen C. Tweedie <sct@redhat.com>, 2000
13337  *
13338  * Copyright 2000 Red Hat corp --- All Rights Reserved
13339  *
13340  * This file is part of the Linux kernel and is made available under
13341  * the terms of the GNU General Public License, version 2, or at your
13342  * option, any later version, incorporated herein by reference.
13343  *
13344  * Journal revoke routines for the generic filesystem journaling code;
13345  * part of the ext2fs journaling system.
13346  *
13347  * Revoke is the mechanism used to prevent old log records for deleted
13348  * metadata from being replayed on top of newer data using the same
13349  * blocks.  The revoke mechanism is used in two separate places:
13350  *
13351  * + Commit: during commit we write the entire list of the current
13352  *   transaction's revoked blocks to the journal
13353  *
13354  * + Recovery: during recovery we record the transaction ID of all
13355  *   revoked blocks.  If there are multiple revoke records in the log
13356  *   for a single block, only the last one counts, and if there is a log
13357  *   entry for a block beyond the last revoke, then that log entry still
13358  *   gets replayed.
13359  *
13360  * We can get interactions between revokes and new log data within a
13361  * single transaction:
13362  *
13363  * Block is revoked and then journaled:
13364  *   The desired end result is the journaling of the new block, so we
13365  *   cancel the revoke before the transaction commits.
13366  *
13367  * Block is journaled and then revoked:
13368  *   The revoke must take precedence over the write of the block, so we
13369  *   need either to cancel the journal entry or to write the revoke
13370  *   later in the log than the log block.  In this case, we choose the
13371  *   latter: journaling a block cancels any revoke record for that block
13372  *   in the current transaction, so any revoke for that block in the
13373  *   transaction must have happened after the block was journaled and so
13374  *   the revoke must take precedence.
13375  *
13376  * Block is revoked and then written as data:
13377  *   The data write is allowed to succeed, but the revoke is _not_
13378  *   cancelled.  We still need to prevent old log records from
13379  *   overwriting the new data.  We don't even need to clear the revoke
13380  *   bit here.
13381  *
13382  * Revoke information on buffers is a tri-state value:
13383  *
13384  * RevokeValid clear:   no cached revoke status, need to look it up
13385  * RevokeValid set, Revoked clear:
13386  *                      buffer has not been revoked, and cancel_revoke
13387  *                      need do nothing.
13388  * RevokeValid set, Revoked set:
13389  *                      buffer has been revoked.
13390  */
13391
13392 static kmem_cache_t *revoke_record_cache;
13393 static kmem_cache_t *revoke_table_cache;
13394
13395 /* Each revoke record represents one single revoked block.  During
13396    journal replay, this involves recording the transaction ID of the
13397    last transaction to revoke this block. */
13398
13399 struct jbd_revoke_record_s
13400 {
13401         struct list_head  hash;
13402         tid_t             sequence;     /* Used for recovery only */
13403         unsigned long     blocknr;
13404 };
13405
13406
13407 /* The revoke table is just a simple hash table of revoke records. */
13408 struct jbd_revoke_table_s
13409 {
13410         /* It is conceivable that we might want a larger hash table
13411          * for recovery.  Must be a power of two. */
13412         int               hash_size;
13413         int               hash_shift;
13414         struct list_head *hash_table;
13415 };
13416
13417
13418 #ifdef __KERNEL__
13419 static void write_one_revoke_record(journal_t *, transaction_t *,
13420                                     struct journal_head **, int *,
13421                                     struct jbd_revoke_record_s *);
13422 static void flush_descriptor(journal_t *, struct journal_head *, int);
13423 #endif
13424
13425 /* Utility functions to maintain the revoke table */
13426
13427 /* Borrowed from buffer.c: this is a tried and tested block hash function */
13428 static inline int hash(journal_t *journal, unsigned long block)
13429 {
13430         struct jbd_revoke_table_s *table = journal->j_revoke;
13431         int hash_shift = table->hash_shift;
13432
13433         return ((block << (hash_shift - 6)) ^
13434                 (block >> 13) ^
13435                 (block << (hash_shift - 12))) & (table->hash_size - 1);
13436 }
13437
13438 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
13439                               tid_t seq)
13440 {
13441         struct list_head *hash_list;
13442         struct jbd_revoke_record_s *record;
13443
13444 #ifdef __KERNEL__
13445 repeat:
13446 #endif
13447         record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
13448         if (!record)
13449                 goto oom;
13450
13451         record->sequence = seq;
13452         record->blocknr = blocknr;
13453         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13454         list_add(&record->hash, hash_list);
13455         return 0;
13456
13457 oom:
13458 #ifdef __KERNEL__
13459         if (!journal_oom_retry)
13460                 return -ENOMEM;
13461         jbd_debug(1, "ENOMEM in " __FUNCTION__ ", retrying.\n");
13462         current->policy |= SCHED_YIELD;
13463         schedule();
13464         goto repeat;
13465 #else
13466         return -ENOMEM;
13467 #endif
13468 }
13469
13470 /* Find a revoke record in the journal's hash table. */
13471
13472 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
13473                                                       unsigned long blocknr)
13474 {
13475         struct list_head *hash_list;
13476         struct jbd_revoke_record_s *record;
13477
13478         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13479
13480         record = (struct jbd_revoke_record_s *) hash_list->next;
13481         while (&(record->hash) != hash_list) {
13482                 if (record->blocknr == blocknr)
13483                         return record;
13484                 record = (struct jbd_revoke_record_s *) record->hash.next;
13485         }
13486         return NULL;
13487 }
13488
13489 int journal_init_revoke_caches(void)
13490 {
13491         revoke_record_cache = kmem_cache_create("revoke_record",
13492                                            sizeof(struct jbd_revoke_record_s),
13493                                            0, SLAB_HWCACHE_ALIGN, NULL, NULL);
13494         if (revoke_record_cache == 0)
13495                 return -ENOMEM;
13496
13497         revoke_table_cache = kmem_cache_create("revoke_table",
13498                                            sizeof(struct jbd_revoke_table_s),
13499                                            0, 0, NULL, NULL);
13500         if (revoke_table_cache == 0) {
13501                 kmem_cache_destroy(revoke_record_cache);
13502                 revoke_record_cache = NULL;
13503                 return -ENOMEM;
13504         }
13505         return 0;
13506 }
13507
13508 void journal_destroy_revoke_caches(void)
13509 {
13510         kmem_cache_destroy(revoke_record_cache);
13511         revoke_record_cache = 0;
13512         kmem_cache_destroy(revoke_table_cache);
13513         revoke_table_cache = 0;
13514 }
13515
13516 /* Initialise the revoke table for a given journal to a given size. */
13517
13518 int journal_init_revoke(journal_t *journal, int hash_size)
13519 {
13520         int shift, tmp;
13521
13522         J_ASSERT (journal->j_revoke == NULL);
13523
13524         journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
13525         if (!journal->j_revoke)
13526                 return -ENOMEM;
13527
13528         /* Check that the hash_size is a power of two */
13529         J_ASSERT ((hash_size & (hash_size-1)) == 0);
13530
13531         journal->j_revoke->hash_size = hash_size;
13532
13533         shift = 0;
13534         tmp = hash_size;
13535         while((tmp >>= 1UL) != 0UL)
13536                 shift++;
13537         journal->j_revoke->hash_shift = shift;
13538
13539         journal->j_revoke->hash_table =
13540                 kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
13541         if (!journal->j_revoke->hash_table) {
13542                 kmem_cache_free(revoke_table_cache, journal->j_revoke);
13543                 journal->j_revoke = NULL;
13544                 return -ENOMEM;
13545         }
13546
13547         for (tmp = 0; tmp < hash_size; tmp++)
13548                 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
13549
13550         return 0;
13551 }
13552
13553 /* Destoy a journal's revoke table.  The table must already be empty! */
13554
13555 void journal_destroy_revoke(journal_t *journal)
13556 {
13557         struct jbd_revoke_table_s *table;
13558         struct list_head *hash_list;
13559         int i;
13560
13561         table = journal->j_revoke;
13562         if (!table)
13563                 return;
13564
13565         for (i=0; i<table->hash_size; i++) {
13566                 hash_list = &table->hash_table[i];
13567                 J_ASSERT (list_empty(hash_list));
13568         }
13569
13570         kfree(table->hash_table);
13571         kmem_cache_free(revoke_table_cache, table);
13572         journal->j_revoke = NULL;
13573 }
13574
13575
13576 #ifdef __KERNEL__
13577
13578 /*
13579  * journal_revoke: revoke a given buffer_head from the journal.  This
13580  * prevents the block from being replayed during recovery if we take a
13581  * crash after this current transaction commits.  Any subsequent
13582  * metadata writes of the buffer in this transaction cancel the
13583  * revoke.
13584  *
13585  * Note that this call may block --- it is up to the caller to make
13586  * sure that there are no further calls to journal_write_metadata
13587  * before the revoke is complete.  In ext3, this implies calling the
13588  * revoke before clearing the block bitmap when we are deleting
13589  * metadata.
13590  *
13591  * Revoke performs a journal_forget on any buffer_head passed in as a
13592  * parameter, but does _not_ forget the buffer_head if the bh was only
13593  * found implicitly.
13594  *
13595  * bh_in may not be a journalled buffer - it may have come off
13596  * the hash tables without an attached journal_head.
13597  *
13598  * If bh_in is non-zero, journal_revoke() will decrement its b_count
13599  * by one.
13600  */
13601
13602 int journal_revoke(handle_t *handle, unsigned long blocknr,
13603                    struct buffer_head *bh_in)
13604 {
13605         struct buffer_head *bh = NULL;
13606         journal_t *journal;
13607         kdev_t dev;
13608         int err;
13609
13610         if (bh_in)
13611                 BUFFER_TRACE(bh_in, "enter");
13612
13613         journal = handle->h_transaction->t_journal;
13614         if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)){
13615                 J_ASSERT (!"Cannot set revoke feature!");
13616                 return -EINVAL;
13617         }
13618
13619         dev = journal->j_fs_dev;
13620         bh = bh_in;
13621
13622         if (!bh) {
13623                 bh = get_hash_table(dev, blocknr, journal->j_blocksize);
13624                 if (bh)
13625                         BUFFER_TRACE(bh, "found on hash");
13626         }
13627 #ifdef JBD_EXPENSIVE_CHECKING
13628         else {
13629                 struct buffer_head *bh2;
13630
13631                 /* If there is a different buffer_head lying around in
13632                  * memory anywhere... */
13633                 bh2 = get_hash_table(dev, blocknr, journal->j_blocksize);
13634                 if (bh2) {
13635                         /* ... and it has RevokeValid status... */
13636                         if ((bh2 != bh) &&
13637                             test_bit(BH_RevokeValid, &bh2->b_state))
13638                                 /* ...then it better be revoked too,
13639                                  * since it's illegal to create a revoke
13640                                  * record against a buffer_head which is
13641                                  * not marked revoked --- that would
13642                                  * risk missing a subsequent revoke
13643                                  * cancel. */
13644                                 J_ASSERT_BH(bh2, test_bit(BH_Revoked, &
13645                                                           bh2->b_state));
13646                         __brelse(bh2);
13647                 }
13648         }
13649 #endif
13650
13651         /* We really ought not ever to revoke twice in a row without
13652            first having the revoke cancelled: it's illegal to free a
13653            block twice without allocating it in between! */
13654         if (bh) {
13655                 J_ASSERT_BH(bh, !test_bit(BH_Revoked, &bh->b_state));
13656                 set_bit(BH_Revoked, &bh->b_state);
13657                 set_bit(BH_RevokeValid, &bh->b_state);
13658                 if (bh_in) {
13659                         BUFFER_TRACE(bh_in, "call journal_forget");
13660                         journal_forget(handle, bh_in);
13661                 } else {
13662                         BUFFER_TRACE(bh, "call brelse");
13663                         __brelse(bh);
13664                 }
13665         }
13666
13667         lock_journal(journal);
13668         jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in);
13669         err = insert_revoke_hash(journal, blocknr,
13670                                 handle->h_transaction->t_tid);
13671         unlock_journal(journal);
13672         BUFFER_TRACE(bh_in, "exit");
13673         return err;
13674 }
13675
13676 /*
13677  * Cancel an outstanding revoke.  For use only internally by the
13678  * journaling code (called from journal_get_write_access).
13679  *
13680  * We trust the BH_Revoked bit on the buffer if the buffer is already
13681  * being journaled: if there is no revoke pending on the buffer, then we
13682  * don't do anything here.
13683  *
13684  * This would break if it were possible for a buffer to be revoked and
13685  * discarded, and then reallocated within the same transaction.  In such
13686  * a case we would have lost the revoked bit, but when we arrived here
13687  * the second time we would still have a pending revoke to cancel.  So,
13688  * do not trust the Revoked bit on buffers unless RevokeValid is also
13689  * set.
13690  *
13691  * The caller must have the journal locked.
13692  */
13693 int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
13694 {
13695         struct jbd_revoke_record_s *record;
13696         journal_t *journal = handle->h_transaction->t_journal;
13697         int need_cancel;
13698         int did_revoke = 0;     /* akpm: debug */
13699         struct buffer_head *bh = jh2bh(jh);
13700
13701         jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
13702
13703         /* Is the existing Revoke bit valid?  If so, we trust it, and
13704          * only perform the full cancel if the revoke bit is set.  If
13705          * not, we can't trust the revoke bit, and we need to do the
13706          * full search for a revoke record. */
13707         if (test_and_set_bit(BH_RevokeValid, &bh->b_state))
13708                 need_cancel = (test_and_clear_bit(BH_Revoked, &bh->b_state));
13709         else {
13710                 need_cancel = 1;
13711                 clear_bit(BH_Revoked, &bh->b_state);
13712         }
13713
13714         if (need_cancel) {
13715                 record = find_revoke_record(journal, bh->b_blocknr);
13716                 if (record) {
13717                         jbd_debug(4, "cancelled existing revoke on "
13718                                   "blocknr %lu\n", bh->b_blocknr);
13719                         list_del(&record->hash);
13720                         kmem_cache_free(revoke_record_cache, record);
13721                         did_revoke = 1;
13722                 }
13723         }
13724
13725 #ifdef JBD_EXPENSIVE_CHECKING
13726         /* There better not be one left behind by now! */
13727         record = find_revoke_record(journal, bh->b_blocknr);
13728         J_ASSERT_JH(jh, record == NULL);
13729 #endif
13730
13731         /* Finally, have we just cleared revoke on an unhashed
13732          * buffer_head?  If so, we'd better make sure we clear the
13733          * revoked status on any hashed alias too, otherwise the revoke
13734          * state machine will get very upset later on. */
13735         if (need_cancel && !bh->b_pprev) {
13736                 struct buffer_head *bh2;
13737                 bh2 = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
13738                 if (bh2) {
13739                         clear_bit(BH_Revoked, &bh2->b_state);
13740                         __brelse(bh2);
13741                 }
13742         }
13743
13744         return did_revoke;
13745 }
13746
13747
13748 /*
13749  * Write revoke records to the journal for all entries in the current
13750  * revoke hash, deleting the entries as we go.
13751  *
13752  * Called with the journal lock held.
13753  */
13754
13755 void journal_write_revoke_records(journal_t *journal,
13756                                   transaction_t *transaction)
13757 {
13758         struct journal_head *descriptor;
13759         struct jbd_revoke_record_s *record;
13760         struct jbd_revoke_table_s *revoke;
13761         struct list_head *hash_list;
13762         int i, offset, count;
13763
13764         descriptor = NULL;
13765         offset = 0;
13766         count = 0;
13767         revoke = journal->j_revoke;
13768
13769         for (i = 0; i < revoke->hash_size; i++) {
13770                 hash_list = &revoke->hash_table[i];
13771
13772                 while (!list_empty(hash_list)) {
13773                         record = (struct jbd_revoke_record_s *)
13774                                 hash_list->next;
13775                         write_one_revoke_record(journal, transaction,
13776                                                 &descriptor, &offset,
13777                                                 record);
13778                         count++;
13779                         list_del(&record->hash);
13780                         kmem_cache_free(revoke_record_cache, record);
13781                 }
13782         }
13783         if (descriptor)
13784                 flush_descriptor(journal, descriptor, offset);
13785         jbd_debug(1, "Wrote %d revoke records\n", count);
13786 }
13787
13788 /*
13789  * Write out one revoke record.  We need to create a new descriptor
13790  * block if the old one is full or if we have not already created one.
13791  */
13792
13793 static void write_one_revoke_record(journal_t *journal,
13794                                     transaction_t *transaction,
13795                                     struct journal_head **descriptorp,
13796                                     int *offsetp,
13797                                     struct jbd_revoke_record_s *record)
13798 {
13799         struct journal_head *descriptor;
13800         int offset;
13801         journal_header_t *header;
13802
13803         /* If we are already aborting, this all becomes a noop.  We
13804            still need to go round the loop in
13805            journal_write_revoke_records in order to free all of the
13806            revoke records: only the IO to the journal is omitted. */
13807         if (is_journal_aborted(journal))
13808                 return;
13809
13810         descriptor = *descriptorp;
13811         offset = *offsetp;
13812
13813         /* Make sure we have a descriptor with space left for the record */
13814         if (descriptor) {
13815                 if (offset == journal->j_blocksize) {
13816                         flush_descriptor(journal, descriptor, offset);
13817                         descriptor = NULL;
13818                 }
13819         }
13820
13821         if (!descriptor) {
13822                 descriptor = journal_get_descriptor_buffer(journal);
13823                 if (!descriptor)
13824                         return;
13825                 header = (journal_header_t *) &jh2bh(descriptor)->b_data[0];
13826                 header->h_magic     = htonl(JFS_MAGIC_NUMBER);
13827                 header->h_blocktype = htonl(JFS_REVOKE_BLOCK);
13828                 header->h_sequence  = htonl(transaction->t_tid);
13829
13830                 /* Record it so that we can wait for IO completion later */
13831                 JBUFFER_TRACE(descriptor, "file as BJ_LogCtl");
13832                 journal_file_buffer(descriptor, transaction, BJ_LogCtl);
13833
13834                 offset = sizeof(journal_revoke_header_t);
13835                 *descriptorp = descriptor;
13836         }
13837
13838         * ((unsigned int *)(&jh2bh(descriptor)->b_data[offset])) =
13839                 htonl(record->blocknr);
13840         offset += 4;
13841         *offsetp = offset;
13842 }
13843
13844 /*
13845  * Flush a revoke descriptor out to the journal.  If we are aborting,
13846  * this is a noop; otherwise we are generating a buffer which needs to
13847  * be waited for during commit, so it has to go onto the appropriate
13848  * journal buffer list.
13849  */
13850
13851 static void flush_descriptor(journal_t *journal,
13852                              struct journal_head *descriptor,
13853                              int offset)
13854 {
13855         journal_revoke_header_t *header;
13856
13857         if (is_journal_aborted(journal)) {
13858                 JBUFFER_TRACE(descriptor, "brelse");
13859                 __brelse(jh2bh(descriptor));
13860                 return;
13861         }
13862
13863         header = (journal_revoke_header_t *) jh2bh(descriptor)->b_data;
13864         header->r_count = htonl(offset);
13865         set_bit(BH_JWrite, &jh2bh(descriptor)->b_state);
13866         {
13867                 struct buffer_head *bh = jh2bh(descriptor);
13868                 BUFFER_TRACE(bh, "write");
13869                 ll_rw_block (WRITE, 1, &bh);
13870         }
13871 }
13872
13873 #endif
13874
13875 /*
13876  * Revoke support for recovery.
13877  *
13878  * Recovery needs to be able to:
13879  *
13880  *  record all revoke records, including the tid of the latest instance
13881  *  of each revoke in the journal
13882  *
13883  *  check whether a given block in a given transaction should be replayed
13884  *  (ie. has not been revoked by a revoke record in that or a subsequent
13885  *  transaction)
13886  *
13887  *  empty the revoke table after recovery.
13888  */
13889
13890 /*
13891  * First, setting revoke records.  We create a new revoke record for
13892  * every block ever revoked in the log as we scan it for recovery, and
13893  * we update the existing records if we find multiple revokes for a
13894  * single block.
13895  */
13896
13897 int journal_set_revoke(journal_t *journal,
13898                        unsigned long blocknr,
13899                        tid_t sequence)
13900 {
13901         struct jbd_revoke_record_s *record;
13902
13903         record = find_revoke_record(journal, blocknr);
13904         if (record) {
13905                 /* If we have multiple occurences, only record the
13906                  * latest sequence number in the hashed record */
13907                 if (tid_gt(sequence, record->sequence))
13908                         record->sequence = sequence;
13909                 return 0;
13910         }
13911         return insert_revoke_hash(journal, blocknr, sequence);
13912 }
13913
13914 /*
13915  * Test revoke records.  For a given block referenced in the log, has
13916  * that block been revoked?  A revoke record with a given transaction
13917  * sequence number revokes all blocks in that transaction and earlier
13918  * ones, but later transactions still need replayed.
13919  */
13920
13921 int journal_test_revoke(journal_t *journal,
13922                         unsigned long blocknr,
13923                         tid_t sequence)
13924 {
13925         struct jbd_revoke_record_s *record;
13926
13927         record = find_revoke_record(journal, blocknr);
13928         if (!record)
13929                 return 0;
13930         if (tid_gt(sequence, record->sequence))
13931                 return 0;
13932         return 1;
13933 }
13934
13935 /*
13936  * Finally, once recovery is over, we need to clear the revoke table so
13937  * that it can be reused by the running filesystem.
13938  */
13939
13940 void journal_clear_revoke(journal_t *journal)
13941 {
13942         int i;
13943         struct list_head *hash_list;
13944         struct jbd_revoke_record_s *record;
13945         struct jbd_revoke_table_s *revoke_var;
13946
13947         revoke_var = journal->j_revoke;
13948
13949         for (i = 0; i < revoke_var->hash_size; i++) {
13950                 hash_list = &revoke_var->hash_table[i];
13951                 while (!list_empty(hash_list)) {
13952                         record = (struct jbd_revoke_record_s*) hash_list->next;
13953                         list_del(&record->hash);
13954                         kmem_cache_free(revoke_record_cache, record);
13955                 }
13956         }
13957 }
13958
13959 /*
13960  * e2fsck.c - superblock checks
13961  *
13962  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
13963  *
13964  * %Begin-Header%
13965  * This file may be redistributed under the terms of the GNU Public
13966  * License.
13967  * %End-Header%
13968  */
13969
13970 #define MIN_CHECK 1
13971 #define MAX_CHECK 2
13972
13973 static void check_super_value(e2fsck_t ctx, const char *descr,
13974                               unsigned long value, int flags,
13975                               unsigned long min_val, unsigned long max_val)
13976 {
13977         struct          problem_context pctx;
13978
13979         if (((flags & MIN_CHECK) && (value < min_val)) ||
13980             ((flags & MAX_CHECK) && (value > max_val))) {
13981                 clear_problem_context(&pctx);
13982                 pctx.num = value;
13983                 pctx.str = descr;
13984                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13985                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13986         }
13987 }
13988
13989 /*
13990  * This routine may get stubbed out in special compilations of the
13991  * e2fsck code..
13992  */
13993 #ifndef EXT2_SPECIAL_DEVICE_SIZE
13994 errcode_t e2fsck_get_device_size(e2fsck_t ctx)
13995 {
13996         return (ext2fs_get_device_size(ctx->filesystem_name,
13997                                        EXT2_BLOCK_SIZE(ctx->fs->super),
13998                                        &ctx->num_blocks));
13999 }
14000 #endif
14001
14002 /*
14003  * helper function to release an inode
14004  */
14005 struct process_block_struct {
14006         e2fsck_t        ctx;
14007         char            *buf;
14008         struct problem_context *pctx;
14009         int             truncating;
14010         int             truncate_offset;
14011         e2_blkcnt_t     truncate_block;
14012         int             truncated_blocks;
14013         int             abort;
14014         errcode_t       errcode;
14015 };
14016
14017 static int release_inode_block(ext2_filsys fs,
14018                                blk_t    *block_nr,
14019                                e2_blkcnt_t blockcnt,
14020                                blk_t    ref_blk EXT2FS_ATTR((unused)),
14021                                int      ref_offset EXT2FS_ATTR((unused)),
14022                                void *priv_data)
14023 {
14024         struct process_block_struct *pb;
14025         e2fsck_t                ctx;
14026         struct problem_context  *pctx;
14027         blk_t                   blk = *block_nr;
14028         int                     retval = 0;
14029
14030         pb = (struct process_block_struct *) priv_data;
14031         ctx = pb->ctx;
14032         pctx = pb->pctx;
14033
14034         pctx->blk = blk;
14035         pctx->blkcount = blockcnt;
14036
14037         if (HOLE_BLKADDR(blk))
14038                 return 0;
14039
14040         if ((blk < fs->super->s_first_data_block) ||
14041             (blk >= fs->super->s_blocks_count)) {
14042                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
14043         return_abort:
14044                 pb->abort = 1;
14045                 return BLOCK_ABORT;
14046         }
14047
14048         if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
14049                 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
14050                 goto return_abort;
14051         }
14052
14053         /*
14054          * If we are deleting an orphan, then we leave the fields alone.
14055          * If we are truncating an orphan, then update the inode fields
14056          * and clean up any partial block data.
14057          */
14058         if (pb->truncating) {
14059                 /*
14060                  * We only remove indirect blocks if they are
14061                  * completely empty.
14062                  */
14063                 if (blockcnt < 0) {
14064                         int     i, limit;
14065                         blk_t   *bp;
14066
14067                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
14068                                                         pb->buf);
14069                         if (pb->errcode)
14070                                 goto return_abort;
14071
14072                         limit = fs->blocksize >> 2;
14073                         for (i = 0, bp = (blk_t *) pb->buf;
14074                              i < limit;  i++, bp++)
14075                                 if (*bp)
14076                                         return 0;
14077                 }
14078                 /*
14079                  * We don't remove direct blocks until we've reached
14080                  * the truncation block.
14081                  */
14082                 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
14083                         return 0;
14084                 /*
14085                  * If part of the last block needs truncating, we do
14086                  * it here.
14087                  */
14088                 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
14089                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
14090                                                         pb->buf);
14091                         if (pb->errcode)
14092                                 goto return_abort;
14093                         memset(pb->buf + pb->truncate_offset, 0,
14094                                fs->blocksize - pb->truncate_offset);
14095                         pb->errcode = io_channel_write_blk(fs->io, blk, 1,
14096                                                          pb->buf);
14097                         if (pb->errcode)
14098                                 goto return_abort;
14099                 }
14100                 pb->truncated_blocks++;
14101                 *block_nr = 0;
14102                 retval |= BLOCK_CHANGED;
14103         }
14104
14105         ext2fs_block_alloc_stats(fs, blk, -1);
14106         return retval;
14107 }
14108
14109 /*
14110  * This function releases an inode.  Returns 1 if an inconsistency was
14111  * found.  If the inode has a link count, then it is being truncated and
14112  * not deleted.
14113  */
14114 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
14115                                 struct ext2_inode *inode, char *block_buf,
14116                                 struct problem_context *pctx)
14117 {
14118         struct process_block_struct     pb;
14119         ext2_filsys                     fs = ctx->fs;
14120         errcode_t                       retval;
14121         __u32                           count;
14122
14123         if (!ext2fs_inode_has_valid_blocks(inode))
14124                 return 0;
14125
14126         pb.buf = block_buf + 3 * ctx->fs->blocksize;
14127         pb.ctx = ctx;
14128         pb.abort = 0;
14129         pb.errcode = 0;
14130         pb.pctx = pctx;
14131         if (inode->i_links_count) {
14132                 pb.truncating = 1;
14133                 pb.truncate_block = (e2_blkcnt_t)
14134                         ((((long long)inode->i_size_high << 32) +
14135                           inode->i_size + fs->blocksize - 1) /
14136                          fs->blocksize);
14137                 pb.truncate_offset = inode->i_size % fs->blocksize;
14138         } else {
14139                 pb.truncating = 0;
14140                 pb.truncate_block = 0;
14141                 pb.truncate_offset = 0;
14142         }
14143         pb.truncated_blocks = 0;
14144         retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
14145                                       block_buf, release_inode_block, &pb);
14146         if (retval) {
14147                 com_err("release_inode_blocks", retval,
14148                         _("while calling ext2fs_block_iterate for inode %d"),
14149                         ino);
14150                 return 1;
14151         }
14152         if (pb.abort)
14153                 return 1;
14154
14155         /* Refresh the inode since ext2fs_block_iterate may have changed it */
14156         e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
14157
14158         if (pb.truncated_blocks)
14159                 inode->i_blocks -= pb.truncated_blocks *
14160                         (fs->blocksize / 512);
14161
14162         if (inode->i_file_acl) {
14163                 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
14164                                                    block_buf, -1, &count);
14165                 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
14166                         retval = 0;
14167                         count = 1;
14168                 }
14169                 if (retval) {
14170                         com_err("release_inode_blocks", retval,
14171                 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
14172                                 ino);
14173                         return 1;
14174                 }
14175                 if (count == 0)
14176                         ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
14177                 inode->i_file_acl = 0;
14178         }
14179         return 0;
14180 }
14181
14182 /*
14183  * This function releases all of the orphan inodes.  It returns 1 if
14184  * it hit some error, and 0 on success.
14185  */
14186 static int release_orphan_inodes(e2fsck_t ctx)
14187 {
14188         ext2_filsys fs = ctx->fs;
14189         ext2_ino_t      ino, next_ino;
14190         struct ext2_inode inode;
14191         struct problem_context pctx;
14192         char *block_buf;
14193
14194         if ((ino = fs->super->s_last_orphan) == 0)
14195                 return 0;
14196
14197         /*
14198          * Win or lose, we won't be using the head of the orphan inode
14199          * list again.
14200          */
14201         fs->super->s_last_orphan = 0;
14202         ext2fs_mark_super_dirty(fs);
14203
14204         /*
14205          * If the filesystem contains errors, don't run the orphan
14206          * list, since the orphan list can't be trusted; and we're
14207          * going to be running a full e2fsck run anyway...
14208          */
14209         if (fs->super->s_state & EXT2_ERROR_FS)
14210                 return 0;
14211
14212         if ((ino < EXT2_FIRST_INODE(fs->super)) ||
14213             (ino > fs->super->s_inodes_count)) {
14214                 clear_problem_context(&pctx);
14215                 pctx.ino = ino;
14216                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
14217                 return 1;
14218         }
14219
14220         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
14221                                                     "block iterate buffer");
14222         e2fsck_read_bitmaps(ctx);
14223
14224         while (ino) {
14225                 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
14226                 clear_problem_context(&pctx);
14227                 pctx.ino = ino;
14228                 pctx.inode = &inode;
14229                 pctx.str = inode.i_links_count ? _("Truncating") :
14230                         _("Clearing");
14231
14232                 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
14233
14234                 next_ino = inode.i_dtime;
14235                 if (next_ino &&
14236                     ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
14237                      (next_ino > fs->super->s_inodes_count))) {
14238                         pctx.ino = next_ino;
14239                         fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
14240                         goto return_abort;
14241                 }
14242
14243                 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
14244                         goto return_abort;
14245
14246                 if (!inode.i_links_count) {
14247                         ext2fs_inode_alloc_stats2(fs, ino, -1,
14248                                                   LINUX_S_ISDIR(inode.i_mode));
14249                         inode.i_dtime = time(0);
14250                 } else {
14251                         inode.i_dtime = 0;
14252                 }
14253                 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
14254                 ino = next_ino;
14255         }
14256         ext2fs_free_mem(&block_buf);
14257         return 0;
14258 return_abort:
14259         ext2fs_free_mem(&block_buf);
14260         return 1;
14261 }
14262
14263 /*
14264  * Check the resize inode to make sure it is sane.  We check both for
14265  * the case where on-line resizing is not enabled (in which case the
14266  * resize inode should be cleared) as well as the case where on-line
14267  * resizing is enabled.
14268  */
14269 static void check_resize_inode(e2fsck_t ctx)
14270 {
14271         ext2_filsys fs = ctx->fs;
14272         struct ext2_inode inode;
14273         struct problem_context  pctx;
14274         int             i, j, gdt_off, ind_off;
14275         blk_t           blk, pblk, expect;
14276         __u32           *dind_buf = 0, *ind_buf;
14277         errcode_t       retval;
14278
14279         clear_problem_context(&pctx);
14280
14281         /*
14282          * If the resize inode feature isn't set, then
14283          * s_reserved_gdt_blocks must be zero.
14284          */
14285         if (!(fs->super->s_feature_compat &
14286               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
14287                 if (fs->super->s_reserved_gdt_blocks) {
14288                         pctx.num = fs->super->s_reserved_gdt_blocks;
14289                         if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
14290                                         &pctx)) {
14291                                 fs->super->s_reserved_gdt_blocks = 0;
14292                                 ext2fs_mark_super_dirty(fs);
14293                         }
14294                 }
14295         }
14296
14297         /* Read the resizde inode */
14298         pctx.ino = EXT2_RESIZE_INO;
14299         retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
14300         if (retval) {
14301                 if (fs->super->s_feature_compat &
14302                     EXT2_FEATURE_COMPAT_RESIZE_INODE)
14303                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
14304                 return;
14305         }
14306
14307         /*
14308          * If the resize inode feature isn't set, check to make sure
14309          * the resize inode is cleared; then we're done.
14310          */
14311         if (!(fs->super->s_feature_compat &
14312               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
14313                 for (i=0; i < EXT2_N_BLOCKS; i++) {
14314                         if (inode.i_block[i])
14315                                 break;
14316                 }
14317                 if ((i < EXT2_N_BLOCKS) &&
14318                     fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
14319                         memset(&inode, 0, sizeof(inode));
14320                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
14321                                            "clear_resize");
14322                 }
14323                 return;
14324         }
14325
14326         /*
14327          * The resize inode feature is enabled; check to make sure the
14328          * only block in use is the double indirect block
14329          */
14330         blk = inode.i_block[EXT2_DIND_BLOCK];
14331         for (i=0; i < EXT2_N_BLOCKS; i++) {
14332                 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
14333                         break;
14334         }
14335         if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
14336             !(inode.i_mode & LINUX_S_IFREG) ||
14337             (blk < fs->super->s_first_data_block ||
14338              blk >= fs->super->s_blocks_count)) {
14339         resize_inode_invalid:
14340                 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
14341                         memset(&inode, 0, sizeof(inode));
14342                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
14343                                            "clear_resize");
14344                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
14345                 }
14346                 if (!(ctx->options & E2F_OPT_READONLY)) {
14347                         fs->super->s_state &= ~EXT2_VALID_FS;
14348                         ext2fs_mark_super_dirty(fs);
14349                 }
14350                 goto cleanup;
14351         }
14352         dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
14353                                                     "resize dind buffer");
14354         ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
14355
14356         retval = ext2fs_read_ind_block(fs, blk, dind_buf);
14357         if (retval)
14358                 goto resize_inode_invalid;
14359
14360         gdt_off = fs->desc_blocks;
14361         pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
14362         for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
14363              i++, gdt_off++, pblk++) {
14364                 gdt_off %= fs->blocksize/4;
14365                 if (dind_buf[gdt_off] != pblk)
14366                         goto resize_inode_invalid;
14367                 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
14368                 if (retval)
14369                         goto resize_inode_invalid;
14370                 ind_off = 0;
14371                 for (j = 1; j < fs->group_desc_count; j++) {
14372                         if (!ext2fs_bg_has_super(fs, j))
14373                                 continue;
14374                         expect = pblk + (j * fs->super->s_blocks_per_group);
14375                         if (ind_buf[ind_off] != expect)
14376                                 goto resize_inode_invalid;
14377                         ind_off++;
14378                 }
14379         }
14380
14381 cleanup:
14382         if (dind_buf)
14383                 ext2fs_free_mem(&dind_buf);
14384
14385  }
14386
14387 void check_super_block(e2fsck_t ctx)
14388 {
14389         ext2_filsys fs = ctx->fs;
14390         blk_t   first_block, last_block;
14391         struct ext2_super_block *sb = fs->super;
14392         struct ext2_group_desc *gd;
14393         blk_t   blocks_per_group = fs->super->s_blocks_per_group;
14394         blk_t   bpg_max;
14395         int     inodes_per_block;
14396         int     ipg_max;
14397         int     inode_size;
14398         dgrp_t  i;
14399         blk_t   should_be;
14400         struct problem_context  pctx;
14401         __u32   free_blocks = 0, free_inodes = 0;
14402
14403         inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
14404         ipg_max = inodes_per_block * (blocks_per_group - 4);
14405         if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
14406                 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
14407         bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
14408         if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
14409                 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
14410
14411         ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
14412                  sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
14413         ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
14414                  sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
14415         ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
14416                 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
14417
14418         clear_problem_context(&pctx);
14419
14420         /*
14421          * Verify the super block constants...
14422          */
14423         check_super_value(ctx, "inodes_count", sb->s_inodes_count,
14424                           MIN_CHECK, 1, 0);
14425         check_super_value(ctx, "blocks_count", sb->s_blocks_count,
14426                           MIN_CHECK, 1, 0);
14427         check_super_value(ctx, "first_data_block", sb->s_first_data_block,
14428                           MAX_CHECK, 0, sb->s_blocks_count);
14429         check_super_value(ctx, "log_block_size", sb->s_log_block_size,
14430                           MIN_CHECK | MAX_CHECK, 0,
14431                           EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
14432         check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
14433                           MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
14434         check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
14435                           MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
14436                           bpg_max);
14437         check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
14438                           MIN_CHECK | MAX_CHECK, 8, bpg_max);
14439         check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
14440                           MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
14441         check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
14442                           MAX_CHECK, 0, sb->s_blocks_count / 2);
14443         check_super_value(ctx, "reserved_gdt_blocks",
14444                           sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
14445                           fs->blocksize/4);
14446         inode_size = EXT2_INODE_SIZE(sb);
14447         check_super_value(ctx, "inode_size",
14448                           inode_size, MIN_CHECK | MAX_CHECK,
14449                           EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
14450         if (inode_size & (inode_size - 1)) {
14451                 pctx.num = inode_size;
14452                 pctx.str = "inode_size";
14453                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
14454                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
14455                 return;
14456         }
14457
14458         if (!ctx->num_blocks) {
14459                 pctx.errcode = e2fsck_get_device_size(ctx);
14460                 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
14461                         fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
14462                         ctx->flags |= E2F_FLAG_ABORT;
14463                         return;
14464                 }
14465                 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
14466                     (ctx->num_blocks < sb->s_blocks_count)) {
14467                         pctx.blk = sb->s_blocks_count;
14468                         pctx.blk2 = ctx->num_blocks;
14469                         if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
14470                                 ctx->flags |= E2F_FLAG_ABORT;
14471                                 return;
14472                         }
14473                 }
14474         }
14475
14476         if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
14477                 pctx.blk = EXT2_BLOCK_SIZE(sb);
14478                 pctx.blk2 = EXT2_FRAG_SIZE(sb);
14479                 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
14480                 ctx->flags |= E2F_FLAG_ABORT;
14481                 return;
14482         }
14483
14484         should_be = sb->s_frags_per_group >>
14485                 (sb->s_log_block_size - sb->s_log_frag_size);
14486         if (sb->s_blocks_per_group != should_be) {
14487                 pctx.blk = sb->s_blocks_per_group;
14488                 pctx.blk2 = should_be;
14489                 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
14490                 ctx->flags |= E2F_FLAG_ABORT;
14491                 return;
14492         }
14493
14494         should_be = (sb->s_log_block_size == 0) ? 1 : 0;
14495         if (sb->s_first_data_block != should_be) {
14496                 pctx.blk = sb->s_first_data_block;
14497                 pctx.blk2 = should_be;
14498                 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
14499                 ctx->flags |= E2F_FLAG_ABORT;
14500                 return;
14501         }
14502
14503         should_be = sb->s_inodes_per_group * fs->group_desc_count;
14504         if (sb->s_inodes_count != should_be) {
14505                 pctx.ino = sb->s_inodes_count;
14506                 pctx.ino2 = should_be;
14507                 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
14508                         sb->s_inodes_count = should_be;
14509                         ext2fs_mark_super_dirty(fs);
14510                 }
14511         }
14512
14513         /*
14514          * Verify the group descriptors....
14515          */
14516         first_block =  sb->s_first_data_block;
14517         last_block = first_block + blocks_per_group;
14518
14519         for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
14520                 pctx.group = i;
14521
14522                 if (i == fs->group_desc_count - 1)
14523                         last_block = sb->s_blocks_count;
14524                 if ((gd->bg_block_bitmap < first_block) ||
14525                     (gd->bg_block_bitmap >= last_block)) {
14526                         pctx.blk = gd->bg_block_bitmap;
14527                         if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
14528                                 gd->bg_block_bitmap = 0;
14529                 }
14530                 if (gd->bg_block_bitmap == 0) {
14531                         ctx->invalid_block_bitmap_flag[i]++;
14532                         ctx->invalid_bitmaps++;
14533                 }
14534                 if ((gd->bg_inode_bitmap < first_block) ||
14535                     (gd->bg_inode_bitmap >= last_block)) {
14536                         pctx.blk = gd->bg_inode_bitmap;
14537                         if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
14538                                 gd->bg_inode_bitmap = 0;
14539                 }
14540                 if (gd->bg_inode_bitmap == 0) {
14541                         ctx->invalid_inode_bitmap_flag[i]++;
14542                         ctx->invalid_bitmaps++;
14543                 }
14544                 if ((gd->bg_inode_table < first_block) ||
14545                     ((gd->bg_inode_table +
14546                       fs->inode_blocks_per_group - 1) >= last_block)) {
14547                         pctx.blk = gd->bg_inode_table;
14548                         if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
14549                                 gd->bg_inode_table = 0;
14550                 }
14551                 if (gd->bg_inode_table == 0) {
14552                         ctx->invalid_inode_table_flag[i]++;
14553                         ctx->invalid_bitmaps++;
14554                 }
14555                 free_blocks += gd->bg_free_blocks_count;
14556                 free_inodes += gd->bg_free_inodes_count;
14557                 first_block += sb->s_blocks_per_group;
14558                 last_block += sb->s_blocks_per_group;
14559
14560                 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
14561                     (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
14562                     (gd->bg_used_dirs_count > sb->s_inodes_per_group))
14563                         ext2fs_unmark_valid(fs);
14564
14565         }
14566
14567         /*
14568          * Update the global counts from the block group counts.  This
14569          * is needed for an experimental patch which eliminates
14570          * locking the entire filesystem when allocating blocks or
14571          * inodes; if the filesystem is not unmounted cleanly, the
14572          * global counts may not be accurate.
14573          */
14574         if ((free_blocks != sb->s_free_blocks_count) ||
14575             (free_inodes != sb->s_free_inodes_count)) {
14576                 if (ctx->options & E2F_OPT_READONLY)
14577                         ext2fs_unmark_valid(fs);
14578                 else {
14579                         sb->s_free_blocks_count = free_blocks;
14580                         sb->s_free_inodes_count = free_inodes;
14581                         ext2fs_mark_super_dirty(fs);
14582                 }
14583         }
14584
14585         if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
14586             (sb->s_free_inodes_count > sb->s_inodes_count))
14587                 ext2fs_unmark_valid(fs);
14588
14589
14590         /*
14591          * If we have invalid bitmaps, set the error state of the
14592          * filesystem.
14593          */
14594         if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
14595                 sb->s_state &= ~EXT2_VALID_FS;
14596                 ext2fs_mark_super_dirty(fs);
14597         }
14598
14599         clear_problem_context(&pctx);
14600
14601 #ifndef EXT2_SKIP_UUID
14602         /*
14603          * If the UUID field isn't assigned, assign it.
14604          */
14605         if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
14606                 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
14607                         uuid_generate(sb->s_uuid);
14608                         ext2fs_mark_super_dirty(fs);
14609                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
14610                 }
14611         }
14612 #endif
14613
14614         /*
14615          * For the Hurd, check to see if the filetype option is set,
14616          * since it doesn't support it.
14617          */
14618         if (!(ctx->options & E2F_OPT_READONLY) &&
14619             fs->super->s_creator_os == EXT2_OS_HURD &&
14620             (fs->super->s_feature_incompat &
14621              EXT2_FEATURE_INCOMPAT_FILETYPE)) {
14622                 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
14623                         fs->super->s_feature_incompat &=
14624                                 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
14625                         ext2fs_mark_super_dirty(fs);
14626
14627                 }
14628         }
14629
14630         /*
14631          * If we have any of the compatibility flags set, we need to have a
14632          * revision 1 filesystem.  Most kernels will not check the flags on
14633          * a rev 0 filesystem and we may have corruption issues because of
14634          * the incompatible changes to the filesystem.
14635          */
14636         if (!(ctx->options & E2F_OPT_READONLY) &&
14637             fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
14638             (fs->super->s_feature_compat ||
14639              fs->super->s_feature_ro_compat ||
14640              fs->super->s_feature_incompat) &&
14641             fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
14642                 ext2fs_update_dynamic_rev(fs);
14643                 ext2fs_mark_super_dirty(fs);
14644         }
14645
14646         check_resize_inode(ctx);
14647
14648         /*
14649          * Clean up any orphan inodes, if present.
14650          */
14651         if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
14652                 fs->super->s_state &= ~EXT2_VALID_FS;
14653                 ext2fs_mark_super_dirty(fs);
14654         }
14655
14656         /*
14657          * Move the ext3 journal file, if necessary.
14658          */
14659         e2fsck_move_ext3_journal(ctx);
14660         return;
14661 }
14662 /*
14663  * swapfs.c --- byte-swap an ext2 filesystem
14664  *
14665  * Copyright 1996, 1997 by Theodore Ts'o
14666  *
14667  * %Begin-Header%
14668  * This file may be redistributed under the terms of the GNU Public
14669  * License.
14670  * %End-Header%
14671  *
14672  */
14673
14674 #ifdef ENABLE_SWAPFS
14675
14676 struct swap_block_struct {
14677         ext2_ino_t      ino;
14678         int             isdir;
14679         errcode_t       errcode;
14680         char            *dir_buf;
14681         struct ext2_inode *inode;
14682 };
14683
14684 /*
14685  * This is a helper function for block_iterate.  We mark all of the
14686  * indirect and direct blocks as changed, so that block_iterate will
14687  * write them out.
14688  */
14689 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
14690                       void *priv_data)
14691 {
14692         errcode_t       retval;
14693
14694         struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
14695
14696         if (sb->isdir && (blockcnt >= 0) && *block_nr) {
14697                 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
14698                 if (retval) {
14699                         sb->errcode = retval;
14700                         return BLOCK_ABORT;
14701                 }
14702                 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
14703                 if (retval) {
14704                         sb->errcode = retval;
14705                         return BLOCK_ABORT;
14706                 }
14707         }
14708         if (blockcnt >= 0) {
14709                 if (blockcnt < EXT2_NDIR_BLOCKS)
14710                         return 0;
14711                 return BLOCK_CHANGED;
14712         }
14713         if (blockcnt == BLOCK_COUNT_IND) {
14714                 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
14715                         return 0;
14716                 return BLOCK_CHANGED;
14717         }
14718         if (blockcnt == BLOCK_COUNT_DIND) {
14719                 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
14720                         return 0;
14721                 return BLOCK_CHANGED;
14722         }
14723         if (blockcnt == BLOCK_COUNT_TIND) {
14724                 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
14725                         return 0;
14726                 return BLOCK_CHANGED;
14727         }
14728         return BLOCK_CHANGED;
14729 }
14730
14731 /*
14732  * This function is responsible for byte-swapping all of the indirect,
14733  * block pointers.  It is also responsible for byte-swapping directories.
14734  */
14735 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
14736                               struct ext2_inode *inode)
14737 {
14738         errcode_t                       retval;
14739         struct swap_block_struct        sb;
14740
14741         sb.ino = ino;
14742         sb.inode = inode;
14743         sb.dir_buf = block_buf + ctx->fs->blocksize*3;
14744         sb.errcode = 0;
14745         sb.isdir = 0;
14746         if (LINUX_S_ISDIR(inode->i_mode))
14747                 sb.isdir = 1;
14748
14749         retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
14750                                       swap_block, &sb);
14751         if (retval) {
14752                 com_err("swap_inode_blocks", retval,
14753                         _("while calling ext2fs_block_iterate"));
14754                 ctx->flags |= E2F_FLAG_ABORT;
14755                 return;
14756         }
14757         if (sb.errcode) {
14758                 com_err("swap_inode_blocks", sb.errcode,
14759                         _("while calling iterator function"));
14760                 ctx->flags |= E2F_FLAG_ABORT;
14761                 return;
14762         }
14763 }
14764
14765 static void swap_inodes(e2fsck_t ctx)
14766 {
14767         ext2_filsys fs = ctx->fs;
14768         dgrp_t                  group;
14769         unsigned int            i;
14770         ext2_ino_t              ino = 1;
14771         char                    *buf, *block_buf;
14772         errcode_t               retval;
14773         struct ext2_inode *     inode;
14774
14775         e2fsck_use_inode_shortcuts(ctx, 1);
14776
14777         retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
14778                                 &buf);
14779         if (retval) {
14780                 com_err("swap_inodes", retval,
14781                         _("while allocating inode buffer"));
14782                 ctx->flags |= E2F_FLAG_ABORT;
14783                 return;
14784         }
14785         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
14786                                                     "block interate buffer");
14787         for (group = 0; group < fs->group_desc_count; group++) {
14788                 retval = io_channel_read_blk(fs->io,
14789                       fs->group_desc[group].bg_inode_table,
14790                       fs->inode_blocks_per_group, buf);
14791                 if (retval) {
14792                         com_err("swap_inodes", retval,
14793                                 _("while reading inode table (group %d)"),
14794                                 group);
14795                         ctx->flags |= E2F_FLAG_ABORT;
14796                         return;
14797                 }
14798                 inode = (struct ext2_inode *) buf;
14799                 for (i=0; i < fs->super->s_inodes_per_group;
14800                      i++, ino++, inode++) {
14801                         ctx->stashed_ino = ino;
14802                         ctx->stashed_inode = inode;
14803
14804                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
14805                                 ext2fs_swap_inode(fs, inode, inode, 0);
14806
14807                         /*
14808                          * Skip deleted files.
14809                          */
14810                         if (inode->i_links_count == 0)
14811                                 continue;
14812
14813                         if (LINUX_S_ISDIR(inode->i_mode) ||
14814                             ((inode->i_block[EXT2_IND_BLOCK] ||
14815                               inode->i_block[EXT2_DIND_BLOCK] ||
14816                               inode->i_block[EXT2_TIND_BLOCK]) &&
14817                              ext2fs_inode_has_valid_blocks(inode)))
14818                                 swap_inode_blocks(ctx, ino, block_buf, inode);
14819
14820                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14821                                 return;
14822
14823                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14824                                 ext2fs_swap_inode(fs, inode, inode, 1);
14825                 }
14826                 retval = io_channel_write_blk(fs->io,
14827                       fs->group_desc[group].bg_inode_table,
14828                       fs->inode_blocks_per_group, buf);
14829                 if (retval) {
14830                         com_err("swap_inodes", retval,
14831                                 _("while writing inode table (group %d)"),
14832                                 group);
14833                         ctx->flags |= E2F_FLAG_ABORT;
14834                         return;
14835                 }
14836         }
14837         ext2fs_free_mem(&buf);
14838         ext2fs_free_mem(&block_buf);
14839         e2fsck_use_inode_shortcuts(ctx, 0);
14840         ext2fs_flush_icache(fs);
14841 }
14842
14843 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
14844 /*
14845  * On the PowerPC, the big-endian variant of the ext2 filesystem
14846  * has its bitmaps stored as 32-bit words with bit 0 as the LSB
14847  * of each word.  Thus a bitmap with only bit 0 set would be, as
14848  * a string of bytes, 00 00 00 01 00 ...
14849  * To cope with this, we byte-reverse each word of a bitmap if
14850  * we have a big-endian filesystem, that is, if we are *not*
14851  * byte-swapping other word-sized numbers.
14852  */
14853 #define EXT2_BIG_ENDIAN_BITMAPS
14854 #endif
14855
14856 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14857 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
14858 {
14859         __u32 *p = (__u32 *) bmap->bitmap;
14860         int n, nbytes = (bmap->end - bmap->start + 7) / 8;
14861
14862         for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
14863                 *p = ext2fs_swab32(*p);
14864 }
14865 #endif
14866
14867
14868 #ifdef ENABLE_SWAPFS
14869 void swap_filesys(e2fsck_t ctx)
14870 {
14871         ext2_filsys fs = ctx->fs;
14872 #ifdef RESOURCE_TRACK
14873         struct resource_track   rtrack;
14874
14875         init_resource_track(&rtrack);
14876 #endif
14877
14878         if (!(ctx->options & E2F_OPT_PREEN))
14879                 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
14880
14881 #ifdef MTRACE
14882         mtrace_print("Byte swap");
14883 #endif
14884
14885         if (fs->super->s_mnt_count) {
14886                 fprintf(stderr, _("%s: the filesystem must be freshly "
14887                         "checked using fsck\n"
14888                         "and not mounted before trying to "
14889                         "byte-swap it.\n"), ctx->device_name);
14890                 ctx->flags |= E2F_FLAG_ABORT;
14891                 return;
14892         }
14893         if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
14894                 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
14895                                EXT2_FLAG_SWAP_BYTES_WRITE);
14896                 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
14897         } else {
14898                 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
14899                 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
14900         }
14901         swap_inodes(ctx);
14902         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14903                 return;
14904         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14905                 fs->flags |= EXT2_FLAG_SWAP_BYTES;
14906         fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
14907                        EXT2_FLAG_SWAP_BYTES_WRITE);
14908
14909 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14910         e2fsck_read_bitmaps(ctx);
14911         ext2fs_swap_bitmap(fs->inode_map);
14912         ext2fs_swap_bitmap(fs->block_map);
14913         fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
14914 #endif
14915         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
14916         ext2fs_flush(fs);
14917         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
14918
14919 #ifdef RESOURCE_TRACK
14920         if (ctx->options & E2F_OPT_TIME2)
14921                 print_resource_track(_("Byte swap"), &rtrack);
14922 #endif
14923 }
14924 #endif  /* ENABLE_SWAPFS */
14925
14926 #endif
14927 /*
14928  * util.c --- miscellaneous utilities
14929  *
14930  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
14931  *
14932  * %Begin-Header%
14933  * This file may be redistributed under the terms of the GNU Public
14934  * License.
14935  * %End-Header%
14936  */
14937
14938 #ifdef HAVE_CONIO_H
14939 #undef HAVE_TERMIOS_H
14940 #include <conio.h>
14941 #define read_a_char()   getch()
14942 #else
14943 #ifdef HAVE_TERMIOS_H
14944 #include <termios.h>
14945 #endif
14946 #endif
14947
14948 #if 0
14949 void fatal_error(e2fsck_t ctx, const char *msg)
14950 {
14951         if (msg)
14952                 fprintf (stderr, "e2fsck: %s\n", msg);
14953         if (ctx->fs && ctx->fs->io) {
14954                 if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
14955                         io_channel_flush(ctx->fs->io);
14956                 else
14957                         fprintf(stderr, "e2fsck: io manager magic bad!\n");
14958         }
14959         ctx->flags |= E2F_FLAG_ABORT;
14960         if (ctx->flags & E2F_FLAG_SETJMP_OK)
14961                 longjmp(ctx->abort_loc, 1);
14962         exit(FSCK_ERROR);
14963 }
14964 #endif
14965
14966 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
14967                              const char *description)
14968 {
14969         void *ret;
14970         char buf[256];
14971
14972 #ifdef DEBUG_ALLOCATE_MEMORY
14973         printf("Allocating %d bytes for %s...\n", size, description);
14974 #endif
14975         ret = malloc(size);
14976         if (!ret) {
14977                 sprintf(buf, "Can't allocate %s\n", description);
14978                 fatal_error(ctx, buf);
14979         }
14980         memset(ret, 0, size);
14981         return ret;
14982 }
14983
14984 char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
14985                   const char *str, int len)
14986 {
14987         char    *ret;
14988
14989         if (!str)
14990                 return NULL;
14991         if (!len)
14992                 len = strlen(str);
14993         ret = malloc(len+1);
14994         if (ret) {
14995                 strncpy(ret, str, len);
14996                 ret[len] = 0;
14997         }
14998         return ret;
14999 }
15000
15001 #ifndef HAVE_CONIO_H
15002 static int read_a_char(void)
15003 {
15004         char    c;
15005         int     r;
15006         int     fail = 0;
15007
15008         while(1) {
15009                 if (e2fsck_global_ctx &&
15010                     (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
15011                         return 3;
15012                 }
15013                 r = read(0, &c, 1);
15014                 if (r == 1)
15015                         return c;
15016                 if (fail++ > 100)
15017                         break;
15018         }
15019         return EOF;
15020 }
15021 #endif
15022
15023 int ask_yn(const char * string, int def)
15024 {
15025         int             c;
15026         const char      *defstr;
15027         const char      *short_yes = _("yY");
15028         const char      *short_no = _("nN");
15029
15030 #ifdef HAVE_TERMIOS_H
15031         struct termios  termios, tmp;
15032
15033         tcgetattr (0, &termios);
15034         tmp = termios;
15035         tmp.c_lflag &= ~(ICANON | ECHO);
15036         tmp.c_cc[VMIN] = 1;
15037         tmp.c_cc[VTIME] = 0;
15038         tcsetattr (0, TCSANOW, &tmp);
15039 #endif
15040
15041         if (def == 1)
15042                 defstr = _(_("<y>"));
15043         else if (def == 0)
15044                 defstr = _(_("<n>"));
15045         else
15046                 defstr = _(" (y/n)");
15047         printf("%s%s? ", string, defstr);
15048         while (1) {
15049                 fflush (stdout);
15050                 if ((c = read_a_char()) == EOF)
15051                         break;
15052                 if (c == 3) {
15053 #ifdef HAVE_TERMIOS_H
15054                         tcsetattr (0, TCSANOW, &termios);
15055 #endif
15056                         if (e2fsck_global_ctx &&
15057                             e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
15058                                 puts("\n");
15059                                 longjmp(e2fsck_global_ctx->abort_loc, 1);
15060                         }
15061                         puts(_("cancelled!\n"));
15062                         return 0;
15063                 }
15064                 if (strchr(short_yes, (char) c)) {
15065                         def = 1;
15066                         break;
15067                 }
15068                 else if (strchr(short_no, (char) c)) {
15069                         def = 0;
15070                         break;
15071                 }
15072                 else if ((c == ' ' || c == '\n') && (def != -1))
15073                         break;
15074         }
15075         if (def)
15076                 puts(_("yes\n"));
15077         else
15078                 puts (_("no\n"));
15079 #ifdef HAVE_TERMIOS_H
15080         tcsetattr (0, TCSANOW, &termios);
15081 #endif
15082         return def;
15083 }
15084
15085 int ask (e2fsck_t ctx, const char * string, int def)
15086 {
15087         if (ctx->options & E2F_OPT_NO) {
15088                 printf (_("%s? no\n\n"), string);
15089                 return 0;
15090         }
15091         if (ctx->options & E2F_OPT_YES) {
15092                 printf (_("%s? yes\n\n"), string);
15093                 return 1;
15094         }
15095         if (ctx->options & E2F_OPT_PREEN) {
15096                 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
15097                 return def;
15098         }
15099         return ask_yn(string, def);
15100 }
15101
15102 void e2fsck_read_bitmaps(e2fsck_t ctx)
15103 {
15104         ext2_filsys fs = ctx->fs;
15105         errcode_t       retval;
15106
15107         if (ctx->invalid_bitmaps) {
15108                 com_err(ctx->program_name, 0,
15109                     _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
15110                         ctx->device_name);
15111                 fatal_error(ctx, 0);
15112         }
15113
15114         ehandler_operation(_("reading inode and block bitmaps"));
15115         retval = ext2fs_read_bitmaps(fs);
15116         ehandler_operation(0);
15117         if (retval) {
15118                 com_err(ctx->program_name, retval,
15119                         _("while retrying to read bitmaps for %s"),
15120                         ctx->device_name);
15121                 fatal_error(ctx, 0);
15122         }
15123 }
15124
15125 void e2fsck_write_bitmaps(e2fsck_t ctx)
15126 {
15127         ext2_filsys fs = ctx->fs;
15128         errcode_t       retval;
15129
15130         if (ext2fs_test_bb_dirty(fs)) {
15131                 ehandler_operation(_("writing block bitmaps"));
15132                 retval = ext2fs_write_block_bitmap(fs);
15133                 ehandler_operation(0);
15134                 if (retval) {
15135                         com_err(ctx->program_name, retval,
15136                             _("while retrying to write block bitmaps for %s"),
15137                                 ctx->device_name);
15138                         fatal_error(ctx, 0);
15139                 }
15140         }
15141
15142         if (ext2fs_test_ib_dirty(fs)) {
15143                 ehandler_operation(_("writing inode bitmaps"));
15144                 retval = ext2fs_write_inode_bitmap(fs);
15145                 ehandler_operation(0);
15146                 if (retval) {
15147                         com_err(ctx->program_name, retval,
15148                             _("while retrying to write inode bitmaps for %s"),
15149                                 ctx->device_name);
15150                         fatal_error(ctx, 0);
15151                 }
15152         }
15153 }
15154
15155 void preenhalt(e2fsck_t ctx)
15156 {
15157         ext2_filsys fs = ctx->fs;
15158
15159         if (!(ctx->options & E2F_OPT_PREEN))
15160                 return;
15161         fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
15162                 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
15163                ctx->device_name);
15164         if (fs != NULL) {
15165                 fs->super->s_state |= EXT2_ERROR_FS;
15166                 ext2fs_mark_super_dirty(fs);
15167                 ext2fs_close(fs);
15168         }
15169         exit(FSCK_UNCORRECTED);
15170 }
15171
15172 #ifdef RESOURCE_TRACK
15173 void init_resource_track(struct resource_track *track)
15174 {
15175 #ifdef HAVE_GETRUSAGE
15176         struct rusage r;
15177 #endif
15178
15179         track->brk_start = sbrk(0);
15180         gettimeofday(&track->time_start, 0);
15181 #ifdef HAVE_GETRUSAGE
15182 #ifdef sun
15183         memset(&r, 0, sizeof(struct rusage));
15184 #endif
15185         getrusage(RUSAGE_SELF, &r);
15186         track->user_start = r.ru_utime;
15187         track->system_start = r.ru_stime;
15188 #else
15189         track->user_start.tv_sec = track->user_start.tv_usec = 0;
15190         track->system_start.tv_sec = track->system_start.tv_usec = 0;
15191 #endif
15192 }
15193
15194 static _INLINE_ float timeval_subtract(struct timeval *tv1,
15195                                        struct timeval *tv2)
15196 {
15197         return ((tv1->tv_sec - tv2->tv_sec) +
15198                 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
15199 }
15200
15201 void print_resource_track(const char *desc, struct resource_track *track)
15202 {
15203 #ifdef HAVE_GETRUSAGE
15204         struct rusage r;
15205 #endif
15206 #ifdef HAVE_MALLINFO
15207         struct mallinfo malloc_info;
15208 #endif
15209         struct timeval time_end;
15210
15211         gettimeofday(&time_end, 0);
15212
15213         if (desc)
15214                 printf("%s: ", desc);
15215
15216 #ifdef HAVE_MALLINFO
15217 #define kbytes(x)       (((x) + 1023) / 1024)
15218
15219         malloc_info = mallinfo();
15220         printf(_("Memory used: %dk/%dk (%dk/%dk), "),
15221                kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
15222                kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
15223 #else
15224         printf(_("Memory used: %d, "),
15225                (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
15226 #endif
15227 #ifdef HAVE_GETRUSAGE
15228         getrusage(RUSAGE_SELF, &r);
15229
15230         printf(_("time: %5.2f/%5.2f/%5.2f\n"),
15231                timeval_subtract(&time_end, &track->time_start),
15232                timeval_subtract(&r.ru_utime, &track->user_start),
15233                timeval_subtract(&r.ru_stime, &track->system_start));
15234 #else
15235         printf(_("elapsed time: %6.3f\n"),
15236                timeval_subtract(&time_end, &track->time_start));
15237 #endif
15238 }
15239 #endif /* RESOURCE_TRACK */
15240
15241 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
15242                               struct ext2_inode * inode, const char *proc)
15243 {
15244         int retval;
15245
15246         retval = ext2fs_read_inode(ctx->fs, ino, inode);
15247         if (retval) {
15248                 com_err("ext2fs_read_inode", retval,
15249                         _("while reading inode %ld in %s"), ino, proc);
15250                 fatal_error(ctx, 0);
15251         }
15252 }
15253
15254 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
15255                                struct ext2_inode * inode, int bufsize,
15256                                const char *proc)
15257 {
15258         int retval;
15259
15260         retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
15261         if (retval) {
15262                 com_err("ext2fs_write_inode", retval,
15263                         _("while writing inode %ld in %s"), ino, proc);
15264                 fatal_error(ctx, 0);
15265         }
15266 }
15267
15268 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
15269                                struct ext2_inode * inode, const char *proc)
15270 {
15271         int retval;
15272
15273         retval = ext2fs_write_inode(ctx->fs, ino, inode);
15274         if (retval) {
15275                 com_err("ext2fs_write_inode", retval,
15276                         _("while writing inode %ld in %s"), ino, proc);
15277                 fatal_error(ctx, 0);
15278         }
15279 }
15280
15281 #ifdef MTRACE
15282 void mtrace_print(char *mesg)
15283 {
15284         FILE    *malloc_get_mallstream();
15285         FILE    *f = malloc_get_mallstream();
15286
15287         if (f)
15288                 fprintf(f, "============= %s\n", mesg);
15289 }
15290 #endif
15291
15292 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
15293                    io_manager manager)
15294 {
15295         struct ext2_super_block *sb;
15296         io_channel              io = NULL;
15297         void                    *buf = NULL;
15298         int                     blocksize;
15299         blk_t                   superblock, ret_sb = 8193;
15300
15301         if (fs && fs->super) {
15302                 ret_sb = (fs->super->s_blocks_per_group +
15303                           fs->super->s_first_data_block);
15304                 if (ctx) {
15305                         ctx->superblock = ret_sb;
15306                         ctx->blocksize = fs->blocksize;
15307                 }
15308                 return ret_sb;
15309         }
15310
15311         if (ctx) {
15312                 if (ctx->blocksize) {
15313                         ret_sb = ctx->blocksize * 8;
15314                         if (ctx->blocksize == 1024)
15315                                 ret_sb++;
15316                         ctx->superblock = ret_sb;
15317                         return ret_sb;
15318                 }
15319                 ctx->superblock = ret_sb;
15320                 ctx->blocksize = 1024;
15321         }
15322
15323         if (!name || !manager)
15324                 goto cleanup;
15325
15326         if (manager->open(name, 0, &io) != 0)
15327                 goto cleanup;
15328
15329         if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
15330                 goto cleanup;
15331         sb = (struct ext2_super_block *) buf;
15332
15333         for (blocksize = EXT2_MIN_BLOCK_SIZE;
15334              blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
15335                 superblock = blocksize*8;
15336                 if (blocksize == 1024)
15337                         superblock++;
15338                 io_channel_set_blksize(io, blocksize);
15339                 if (io_channel_read_blk(io, superblock,
15340                                         -SUPERBLOCK_SIZE, buf))
15341                         continue;
15342 #ifdef EXT2FS_ENABLE_SWAPFS
15343                 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
15344                         ext2fs_swap_super(sb);
15345 #endif
15346                 if (sb->s_magic == EXT2_SUPER_MAGIC) {
15347                         ret_sb = superblock;
15348                         if (ctx) {
15349                                 ctx->superblock = superblock;
15350                                 ctx->blocksize = blocksize;
15351                         }
15352                         break;
15353                 }
15354         }
15355
15356 cleanup:
15357         if (io)
15358                 io_channel_close(io);
15359         if (buf)
15360                 ext2fs_free_mem(&buf);
15361         return (ret_sb);
15362 }
15363
15364 /*
15365  * Given a mode, return the ext2 file type
15366  */
15367 int ext2_file_type(unsigned int mode)
15368 {
15369         if (LINUX_S_ISREG(mode))
15370                 return EXT2_FT_REG_FILE;
15371
15372         if (LINUX_S_ISDIR(mode))
15373                 return EXT2_FT_DIR;
15374
15375         if (LINUX_S_ISCHR(mode))
15376                 return EXT2_FT_CHRDEV;
15377
15378         if (LINUX_S_ISBLK(mode))
15379                 return EXT2_FT_BLKDEV;
15380
15381         if (LINUX_S_ISLNK(mode))
15382                 return EXT2_FT_SYMLINK;
15383
15384         if (LINUX_S_ISFIFO(mode))
15385                 return EXT2_FT_FIFO;
15386
15387         if (LINUX_S_ISSOCK(mode))
15388                 return EXT2_FT_SOCK;
15389
15390         return 0;
15391 }
15392 /*
15393  * unix.c - The unix-specific code for e2fsck
15394  *
15395  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
15396  *
15397  * %Begin-Header%
15398  * This file may be redistributed under the terms of the GNU Public
15399  * License.
15400  * %End-Header%
15401  */
15402
15403
15404
15405 /* Command line options */
15406 static int swapfs;
15407 #ifdef ENABLE_SWAPFS
15408 static int normalize_swapfs;
15409 #endif
15410 static int cflag;               /* check disk */
15411 static int show_version_only;
15412 static int verbose;
15413
15414 static int replace_bad_blocks;
15415 static int keep_bad_blocks;
15416 static char *bad_blocks_file;
15417
15418 #ifdef __CONFIG_JBD_DEBUG__E2FS         /* Enabled by configure --enable-jfs-debug */
15419 int journal_enable_debug = -1;
15420 #endif
15421
15422 #if 0
15423 static void usage(e2fsck_t ctx)
15424 {
15425         fprintf(stderr,
15426                 _("Usage: %s [-panyrcdfvstDFSV] [-b superblock] [-B blocksize]\n"
15427                 "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
15428                 "\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal]\n"
15429                 "\t\t[-E extended-options] device\n"),
15430                 ctx->program_name);
15431
15432         fprintf(stderr, _("\nEmergency help:\n"
15433                 " -p                   Automatic repair (no questions)\n"
15434                 " -n                   Make no changes to the filesystem\n"
15435                 " -y                   Assume \"yes\" to all questions\n"
15436                 " -c                   Check for bad blocks and add them to the badblock list\n"
15437                 " -f                   Force checking even if filesystem is marked clean\n"));
15438         fprintf(stderr, _(""
15439                 " -v                   Be verbose\n"
15440                 " -b superblock        Use alternative superblock\n"
15441                 " -B blocksize         Force blocksize when looking for superblock\n"
15442                 " -j external-journal  Set location of the external journal\n"
15443                 " -l bad_blocks_file   Add to badblocks list\n"
15444                 " -L bad_blocks_file   Set badblocks list\n"
15445                 ));
15446
15447         exit(FSCK_USAGE);
15448 }
15449 #endif
15450
15451 static void show_stats(e2fsck_t ctx)
15452 {
15453         ext2_filsys fs = ctx->fs;
15454         int inodes, inodes_used, blocks, blocks_used;
15455         int dir_links;
15456         int num_files, num_links;
15457         int frag_percent;
15458
15459         dir_links = 2 * ctx->fs_directory_count - 1;
15460         num_files = ctx->fs_total_count - dir_links;
15461         num_links = ctx->fs_links_count - dir_links;
15462         inodes = fs->super->s_inodes_count;
15463         inodes_used = (fs->super->s_inodes_count -
15464                        fs->super->s_free_inodes_count);
15465         blocks = fs->super->s_blocks_count;
15466         blocks_used = (fs->super->s_blocks_count -
15467                        fs->super->s_free_blocks_count);
15468
15469         frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
15470         frag_percent = (frag_percent + 5) / 10;
15471
15472         if (!verbose) {
15473                 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
15474                        ctx->device_name, inodes_used, inodes,
15475                        frag_percent / 10, frag_percent % 10,
15476                        blocks_used, blocks);
15477                 return;
15478         }
15479         printf (P_("\n%8d inode used (%d%%)\n", "\n%8d inodes used (%d%%)\n",
15480                    inodes_used), inodes_used, 100 * inodes_used / inodes);
15481         printf (P_("%8d non-contiguous inode (%0d.%d%%)\n",
15482                    "%8d non-contiguous inodes (%0d.%d%%)\n",
15483                    ctx->fs_fragmented),
15484                 ctx->fs_fragmented, frag_percent / 10, frag_percent % 10);
15485         printf (_("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
15486                 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
15487         printf (P_("%8d block used (%d%%)\n", "%8d blocks used (%d%%)\n",
15488                    blocks_used),
15489                 blocks_used, (int) ((long long) 100 * blocks_used / blocks));
15490         printf (P_("%8d bad block\n", "%8d bad blocks\n",
15491                    ctx->fs_badblocks_count), ctx->fs_badblocks_count);
15492         printf (P_("%8d large file\n", "%8d large files\n",
15493                    ctx->large_files), ctx->large_files);
15494         printf (P_("\n%8d regular file\n", "\n%8d regular files\n",
15495                    ctx->fs_regular_count), ctx->fs_regular_count);
15496         printf (P_("%8d directory\n", "%8d directories\n",
15497                    ctx->fs_directory_count), ctx->fs_directory_count);
15498         printf (P_("%8d character device file\n",
15499                    "%8d character device files\n", ctx->fs_chardev_count),
15500                 ctx->fs_chardev_count);
15501         printf (P_("%8d block device file\n", "%8d block device files\n",
15502                    ctx->fs_blockdev_count), ctx->fs_blockdev_count);
15503         printf (P_("%8d fifo\n", "%8d fifos\n", ctx->fs_fifo_count),
15504                 ctx->fs_fifo_count);
15505         printf (P_("%8d link\n", "%8d links\n",
15506                    ctx->fs_links_count - dir_links),
15507                 ctx->fs_links_count - dir_links);
15508         printf (P_("%8d symbolic link", "%8d symbolic links",
15509                    ctx->fs_symlinks_count), ctx->fs_symlinks_count);
15510         printf (P_(" (%d fast symbolic link)\n", " (%d fast symbolic links)\n",
15511                    ctx->fs_fast_symlinks_count), ctx->fs_fast_symlinks_count);
15512         printf (P_("%8d socket\n", "%8d sockets\n", ctx->fs_sockets_count),
15513                 ctx->fs_sockets_count);
15514         printf ("--------\n");
15515         printf (P_("%8d file\n", "%8d files\n",
15516                    ctx->fs_total_count - dir_links),
15517                 ctx->fs_total_count - dir_links);
15518 }
15519
15520 static void check_mount(e2fsck_t ctx)
15521 {
15522         errcode_t       retval;
15523         int             cont;
15524
15525         retval = ext2fs_check_if_mounted(ctx->filesystem_name,
15526                                          &ctx->mount_flags);
15527         if (retval) {
15528                 com_err("ext2fs_check_if_mount", retval,
15529                         _("while determining whether %s is mounted."),
15530                         ctx->filesystem_name);
15531                 return;
15532         }
15533
15534         /*
15535          * If the filesystem isn't mounted, or it's the root filesystem
15536          * and it's mounted read-only, then everything's fine.
15537          */
15538         if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
15539             ((ctx->mount_flags & EXT2_MF_ISROOT) &&
15540              (ctx->mount_flags & EXT2_MF_READONLY)))
15541                 return;
15542
15543         if (ctx->options & E2F_OPT_READONLY) {
15544                 printf(_("Warning!  %s is mounted.\n"), ctx->filesystem_name);
15545                 return;
15546         }
15547
15548         printf(_("%s is mounted.  "), ctx->filesystem_name);
15549         if (!ctx->interactive)
15550                 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
15551         printf(_("\n\n\007\007\007\007WARNING!!!  "
15552                "Running e2fsck on a mounted filesystem may cause\n"
15553                "SEVERE filesystem damage.\007\007\007\n\n"));
15554         cont = ask_yn(_("Do you really want to continue"), -1);
15555         if (!cont) {
15556                 printf (_("check aborted.\n"));
15557                 exit (0);
15558         }
15559         return;
15560 }
15561
15562 static int is_on_batt(void)
15563 {
15564         FILE    *f;
15565         DIR     *d;
15566         char    tmp[80], tmp2[80], fname[80];
15567         unsigned int    acflag;
15568         struct dirent*  de;
15569
15570         f = fopen("/proc/apm", "r");
15571         if (f) {
15572                 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
15573                         acflag = 1;
15574                 fclose(f);
15575                 return (acflag != 1);
15576         }
15577         d = opendir("/proc/acpi/ac_adapter");
15578         if (d) {
15579                 while ((de=readdir(d)) != NULL) {
15580                         if (!strncmp(".", de->d_name, 1))
15581                                 continue;
15582                         snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
15583                                  de->d_name);
15584                         f = fopen(fname, "r");
15585                         if (!f)
15586                                 continue;
15587                         if (fscanf(f, "%s %s", tmp2, tmp) != 2)
15588                                 tmp[0] = 0;
15589                         fclose(f);
15590                         if (strncmp(tmp, "off-line", 8) == 0) {
15591                                 closedir(d);
15592                                 return 1;
15593                         }
15594                 }
15595                 closedir(d);
15596         }
15597         return 0;
15598 }
15599
15600 /*
15601  * This routine checks to see if a filesystem can be skipped; if so,
15602  * it will exit with E2FSCK_OK.  Under some conditions it will print a
15603  * message explaining why a check is being forced.
15604  */
15605 static void check_if_skip(e2fsck_t ctx)
15606 {
15607         ext2_filsys fs = ctx->fs;
15608         const char *reason = NULL;
15609         unsigned int reason_arg = 0;
15610         long next_check;
15611         int batt = is_on_batt();
15612         time_t now = time(0);
15613
15614         if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
15615             cflag || swapfs)
15616                 return;
15617
15618         if ((fs->super->s_state & EXT2_ERROR_FS) ||
15619             !ext2fs_test_valid(fs))
15620                 reason = _(" contains a file system with errors");
15621         else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
15622                 reason = _(" was not cleanly unmounted");
15623         else if ((fs->super->s_max_mnt_count > 0) &&
15624                  (fs->super->s_mnt_count >=
15625                   (unsigned) fs->super->s_max_mnt_count)) {
15626                 reason = _(" has been mounted %u times without being checked");
15627                 reason_arg = fs->super->s_mnt_count;
15628                 if (batt && (fs->super->s_mnt_count <
15629                              (unsigned) fs->super->s_max_mnt_count*2))
15630                         reason = 0;
15631         } else if (fs->super->s_checkinterval &&
15632                    ((now - fs->super->s_lastcheck) >=
15633                     fs->super->s_checkinterval)) {
15634                 reason = _(" has gone %u days without being checked");
15635                 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
15636                 if (batt && ((now - fs->super->s_lastcheck) <
15637                              fs->super->s_checkinterval*2))
15638                         reason = 0;
15639         }
15640         if (reason) {
15641                 fputs(ctx->device_name, stdout);
15642                 printf(reason, reason_arg);
15643                 fputs(_(", check forced.\n"), stdout);
15644                 return;
15645         }
15646         printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
15647                fs->super->s_inodes_count - fs->super->s_free_inodes_count,
15648                fs->super->s_inodes_count,
15649                fs->super->s_blocks_count - fs->super->s_free_blocks_count,
15650                fs->super->s_blocks_count);
15651         next_check = 100000;
15652         if (fs->super->s_max_mnt_count > 0) {
15653                 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
15654                 if (next_check <= 0)
15655                         next_check = 1;
15656         }
15657         if (fs->super->s_checkinterval &&
15658             ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
15659                 next_check = 1;
15660         if (next_check <= 5) {
15661                 if (next_check == 1)
15662                         fputs(_(" (check after next mount)"), stdout);
15663                 else
15664                         printf(_(" (check in %ld mounts)"), next_check);
15665         }
15666         fputc('\n', stdout);
15667         ext2fs_close(fs);
15668         ctx->fs = NULL;
15669         e2fsck_free_context(ctx);
15670         exit(FSCK_OK);
15671 }
15672
15673 /*
15674  * For completion notice
15675  */
15676 struct percent_tbl {
15677         int     max_pass;
15678         int     table[32];
15679 };
15680 static struct percent_tbl e2fsck_tbl = {
15681         5, { 0, 70, 90, 92,  95, 100 }
15682 };
15683 static char bar[128], spaces[128];
15684
15685 static float calc_percent(struct percent_tbl *tbl, int pass, int curr,
15686                           int max)
15687 {
15688         float   percent;
15689
15690         if (pass <= 0)
15691                 return 0.0;
15692         if (pass > tbl->max_pass || max == 0)
15693                 return 100.0;
15694         percent = ((float) curr) / ((float) max);
15695         return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
15696                 + tbl->table[pass-1]);
15697 }
15698
15699 extern void e2fsck_clear_progbar(e2fsck_t ctx)
15700 {
15701         if (!(ctx->flags & E2F_FLAG_PROG_BAR))
15702                 return;
15703
15704         printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
15705                ctx->stop_meta);
15706         fflush(stdout);
15707         ctx->flags &= ~E2F_FLAG_PROG_BAR;
15708 }
15709
15710 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
15711                            unsigned int dpynum)
15712 {
15713         static const char spinner[] = "\\|/-";
15714         int     i;
15715         unsigned int    tick;
15716         struct timeval  tv;
15717         int dpywidth;
15718         int fixed_percent;
15719
15720         if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
15721                 return 0;
15722
15723         /*
15724          * Calculate the new progress position.  If the
15725          * percentage hasn't changed, then we skip out right
15726          * away.
15727          */
15728         fixed_percent = (int) ((10 * percent) + 0.5);
15729         if (ctx->progress_last_percent == fixed_percent)
15730                 return 0;
15731         ctx->progress_last_percent = fixed_percent;
15732
15733         /*
15734          * If we've already updated the spinner once within
15735          * the last 1/8th of a second, no point doing it
15736          * again.
15737          */
15738         gettimeofday(&tv, NULL);
15739         tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
15740         if ((tick == ctx->progress_last_time) &&
15741             (fixed_percent != 0) && (fixed_percent != 1000))
15742                 return 0;
15743         ctx->progress_last_time = tick;
15744
15745         /*
15746          * Advance the spinner, and note that the progress bar
15747          * will be on the screen
15748          */
15749         ctx->progress_pos = (ctx->progress_pos+1) & 3;
15750         ctx->flags |= E2F_FLAG_PROG_BAR;
15751
15752         dpywidth = 66 - strlen(label);
15753         dpywidth = 8 * (dpywidth / 8);
15754         if (dpynum)
15755                 dpywidth -= 8;
15756
15757         i = ((percent * dpywidth) + 50) / 100;
15758         printf("%s%s: |%s%s", ctx->start_meta, label,
15759                bar + (sizeof(bar) - (i+1)),
15760                spaces + (sizeof(spaces) - (dpywidth - i + 1)));
15761         if (fixed_percent == 1000)
15762                 fputc('|', stdout);
15763         else
15764                 fputc(spinner[ctx->progress_pos & 3], stdout);
15765         printf(" %4.1f%%  ", percent);
15766         if (dpynum)
15767                 printf("%u\r", dpynum);
15768         else
15769                 fputs(" \r", stdout);
15770         fputs(ctx->stop_meta, stdout);
15771
15772         if (fixed_percent == 1000)
15773                 e2fsck_clear_progbar(ctx);
15774         fflush(stdout);
15775
15776         return 0;
15777 }
15778
15779 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
15780                                   unsigned long cur, unsigned long max)
15781 {
15782         char buf[80];
15783         float percent;
15784
15785         if (pass == 0)
15786                 return 0;
15787
15788         if (ctx->progress_fd) {
15789                 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
15790                 write(ctx->progress_fd, buf, strlen(buf));
15791         } else {
15792                 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
15793                 e2fsck_simple_progress(ctx, ctx->device_name,
15794                                        percent, 0);
15795         }
15796         return 0;
15797 }
15798
15799 #define PATH_SET "PATH=/sbin"
15800
15801 static void reserve_stdio_fds(void)
15802 {
15803         int     fd;
15804
15805         while (1) {
15806                 fd = open("/dev/null", O_RDWR);
15807                 if (fd > 2)
15808                         break;
15809                 if (fd < 0) {
15810                         fprintf(stderr, _("ERROR: Couldn't open "
15811                                 "/dev/null (%s)\n"),
15812                                 strerror(errno));
15813                         break;
15814                 }
15815         }
15816         close(fd);
15817 }
15818
15819 static void signal_progress_on(int sig EXT2FS_ATTR((unused)))
15820 {
15821         e2fsck_t ctx = e2fsck_global_ctx;
15822
15823         if (!ctx)
15824                 return;
15825
15826         ctx->progress = e2fsck_update_progress;
15827         ctx->progress_fd = 0;
15828 }
15829
15830 static void signal_progress_off(int sig EXT2FS_ATTR((unused)))
15831 {
15832         e2fsck_t ctx = e2fsck_global_ctx;
15833
15834         if (!ctx)
15835                 return;
15836
15837         e2fsck_clear_progbar(ctx);
15838         ctx->progress = 0;
15839 }
15840
15841 static void signal_cancel(int sig EXT2FS_ATTR((unused)))
15842 {
15843         e2fsck_t ctx = e2fsck_global_ctx;
15844
15845         if (!ctx)
15846                 exit(FSCK_CANCELED);
15847
15848         ctx->flags |= E2F_FLAG_CANCEL;
15849 }
15850
15851 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
15852 {
15853         char    *buf, *token, *next, *p, *arg;
15854         int     ea_ver;
15855         int     extended_usage = 0;
15856
15857         buf = string_copy(ctx, opts, 0);
15858         for (token = buf; token && *token; token = next) {
15859                 p = strchr(token, ',');
15860                 next = 0;
15861                 if (p) {
15862                         *p = 0;
15863                         next = p+1;
15864                 }
15865                 arg = strchr(token, '=');
15866                 if (arg) {
15867                         *arg = 0;
15868                         arg++;
15869                 }
15870                 if (strcmp(token, "ea_ver") == 0) {
15871                         if (!arg) {
15872                                 extended_usage++;
15873                                 continue;
15874                         }
15875                         ea_ver = strtoul(arg, &p, 0);
15876                         if (*p ||
15877                             ((ea_ver != 1) && (ea_ver != 2))) {
15878                                 fprintf(stderr,
15879                                         _("Invalid EA version.\n"));
15880                                 extended_usage++;
15881                                 continue;
15882                         }
15883                         ctx->ext_attr_ver = ea_ver;
15884                 } else
15885                         extended_usage++;
15886         }
15887         if (extended_usage) {
15888                 fprintf(stderr, _("Extended options are separated by commas, "
15889                         "and may take an argument which\n"
15890                         "is set off by an equals ('=') sign.  "
15891                         "Valid raid options are:\n"
15892                         "\tea_ver=<ea_version (1 or 2)\n\n"));
15893                 exit(1);
15894         }
15895 }
15896
15897
15898 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
15899 {
15900         int             flush = 0;
15901         int             c, fd;
15902 #ifdef MTRACE
15903         extern void     *mallwatch;
15904 #endif
15905         e2fsck_t        ctx;
15906         errcode_t       retval;
15907         struct sigaction        sa;
15908         char            *extended_opts = 0;
15909
15910         retval = e2fsck_allocate_context(&ctx);
15911         if (retval)
15912                 return retval;
15913
15914         *ret_ctx = ctx;
15915
15916         setvbuf(stdout, NULL, _IONBF, BUFSIZ);
15917         setvbuf(stderr, NULL, _IONBF, BUFSIZ);
15918         if (isatty(0) && isatty(1)) {
15919                 ctx->interactive = 1;
15920         } else {
15921                 ctx->start_meta[0] = '\001';
15922                 ctx->stop_meta[0] = '\002';
15923         }
15924         memset(bar, '=', sizeof(bar)-1);
15925         memset(spaces, ' ', sizeof(spaces)-1);
15926         blkid_get_cache(&ctx->blkid, NULL);
15927
15928         if (argc && *argv)
15929                 ctx->program_name = *argv;
15930         else
15931                 ctx->program_name = "e2fsck";
15932         while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
15933                 switch (c) {
15934                 case 'C':
15935                         ctx->progress = e2fsck_update_progress;
15936                         ctx->progress_fd = atoi(optarg);
15937                         if (!ctx->progress_fd)
15938                                 break;
15939                         /* Validate the file descriptor to avoid disasters */
15940                         fd = dup(ctx->progress_fd);
15941                         if (fd < 0) {
15942                                 fprintf(stderr,
15943                                 _("Error validating file descriptor %d: %s\n"),
15944                                         ctx->progress_fd,
15945                                         error_message(errno));
15946                                 fatal_error(ctx,
15947                         _("Invalid completion information file descriptor"));
15948                         } else
15949                                 close(fd);
15950                         break;
15951                 case 'D':
15952                         ctx->options |= E2F_OPT_COMPRESS_DIRS;
15953                         break;
15954                 case 'E':
15955                         extended_opts = optarg;
15956                         break;
15957                 case 'p':
15958                 case 'a':
15959                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
15960                         conflict_opt:
15961                                 fatal_error(ctx,
15962         _("Only one the options -p/-a, -n or -y may be specified."));
15963                         }
15964                         ctx->options |= E2F_OPT_PREEN;
15965                         break;
15966                 case 'n':
15967                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
15968                                 goto conflict_opt;
15969                         ctx->options |= E2F_OPT_NO;
15970                         break;
15971                 case 'y':
15972                         if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
15973                                 goto conflict_opt;
15974                         ctx->options |= E2F_OPT_YES;
15975                         break;
15976                 case 't':
15977 #ifdef RESOURCE_TRACK
15978                         if (ctx->options & E2F_OPT_TIME)
15979                                 ctx->options |= E2F_OPT_TIME2;
15980                         else
15981                                 ctx->options |= E2F_OPT_TIME;
15982 #else
15983                         fprintf(stderr, _("The -t option is not "
15984                                 "supported on this version of e2fsck.\n"));
15985 #endif
15986                         break;
15987                 case 'c':
15988                         if (cflag++)
15989                                 ctx->options |= E2F_OPT_WRITECHECK;
15990                         ctx->options |= E2F_OPT_CHECKBLOCKS;
15991                         break;
15992                 case 'r':
15993                         /* What we do by default, anyway! */
15994                         break;
15995                 case 'b':
15996                         ctx->use_superblock = atoi(optarg);
15997                         ctx->flags |= E2F_FLAG_SB_SPECIFIED;
15998                         break;
15999                 case 'B':
16000                         ctx->blocksize = atoi(optarg);
16001                         break;
16002                 case 'I':
16003                         ctx->inode_buffer_blocks = atoi(optarg);
16004                         break;
16005                 case 'j':
16006                         ctx->journal_name = string_copy(ctx, optarg, 0);
16007                         break;
16008                 case 'P':
16009                         ctx->process_inode_size = atoi(optarg);
16010                         break;
16011                 case 'L':
16012                         replace_bad_blocks++;
16013                 case 'l':
16014                         bad_blocks_file = string_copy(ctx, optarg, 0);
16015                         break;
16016                 case 'd':
16017                         ctx->options |= E2F_OPT_DEBUG;
16018                         break;
16019                 case 'f':
16020                         ctx->options |= E2F_OPT_FORCE;
16021                         break;
16022                 case 'F':
16023                         flush = 1;
16024                         break;
16025                 case 'v':
16026                         verbose = 1;
16027                         break;
16028                 case 'V':
16029                         show_version_only = 1;
16030                         break;
16031 #ifdef MTRACE
16032                 case 'M':
16033                         mallwatch = (void *) strtol(optarg, NULL, 0);
16034                         break;
16035 #endif
16036                 case 'N':
16037                         ctx->device_name = optarg;
16038                         break;
16039 #ifdef ENABLE_SWAPFS
16040                 case 's':
16041                         normalize_swapfs = 1;
16042                 case 'S':
16043                         swapfs = 1;
16044                         break;
16045 #else
16046                 case 's':
16047                 case 'S':
16048                         fprintf(stderr, _("Byte-swapping filesystems "
16049                                           "not compiled in this version "
16050                                           "of e2fsck\n"));
16051                         exit(1);
16052 #endif
16053                 case 'k':
16054                         keep_bad_blocks++;
16055                         break;
16056                 default:
16057                         usage();
16058                 }
16059         if (show_version_only)
16060                 return 0;
16061         if (optind != argc - 1)
16062                 usage();
16063         if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
16064             !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
16065                 ctx->options |= E2F_OPT_READONLY;
16066         ctx->io_options = strchr(argv[optind], '?');
16067         if (ctx->io_options)
16068                 *ctx->io_options++ = 0;
16069         ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
16070         if (!ctx->filesystem_name) {
16071                 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
16072                         argv[optind]);
16073                 fatal_error(ctx, 0);
16074         }
16075         if (extended_opts)
16076                 parse_extended_opts(ctx, extended_opts);
16077
16078         if (flush) {
16079                 fd = open(ctx->filesystem_name, O_RDONLY, 0);
16080                 if (fd < 0) {
16081                         com_err("open", errno,
16082                                 _("while opening %s for flushing"),
16083                                 ctx->filesystem_name);
16084                         fatal_error(ctx, 0);
16085                 }
16086                 if ((retval = ext2fs_sync_device(fd, 1))) {
16087                         com_err("ext2fs_sync_device", retval,
16088                                 _("while trying to flush %s"),
16089                                 ctx->filesystem_name);
16090                         fatal_error(ctx, 0);
16091                 }
16092                 close(fd);
16093         }
16094 #ifdef ENABLE_SWAPFS
16095         if (swapfs) {
16096                 if (cflag || bad_blocks_file) {
16097                         fprintf(stderr, _("Incompatible options not "
16098                                           "allowed when byte-swapping.\n"));
16099                         exit(FSCK_USAGE);
16100                 }
16101         }
16102 #endif
16103         if (cflag && bad_blocks_file) {
16104                 fprintf(stderr, _("The -c and the -l/-L options may "
16105                                   "not be both used at the same time.\n"));
16106                 exit(FSCK_USAGE);
16107         }
16108         /*
16109          * Set up signal action
16110          */
16111         memset(&sa, 0, sizeof(struct sigaction));
16112         sa.sa_handler = signal_cancel;
16113         sigaction(SIGINT, &sa, 0);
16114         sigaction(SIGTERM, &sa, 0);
16115 #ifdef SA_RESTART
16116         sa.sa_flags = SA_RESTART;
16117 #endif
16118         e2fsck_global_ctx = ctx;
16119         sa.sa_handler = signal_progress_on;
16120         sigaction(SIGUSR1, &sa, 0);
16121         sa.sa_handler = signal_progress_off;
16122         sigaction(SIGUSR2, &sa, 0);
16123
16124         /* Update our PATH to include /sbin if we need to run badblocks  */
16125         if (cflag) {
16126                 char *oldpath = getenv("PATH");
16127                 if (oldpath) {
16128                         char *newpath;
16129
16130                         newpath = (char *) malloc(sizeof (PATH_SET) + 1 +
16131                                                   strlen (oldpath));
16132                         if (!newpath)
16133                                 fatal_error(ctx, "Couldn't malloc() newpath");
16134                         strcpy (newpath, PATH_SET);
16135                         strcat (newpath, ":");
16136                         strcat (newpath, oldpath);
16137                         putenv (newpath);
16138                 } else
16139                         putenv (PATH_SET);
16140         }
16141 #ifdef __CONFIG_JBD_DEBUG__E2FS
16142         if (getenv("E2FSCK_JBD_DEBUG"))
16143                 journal_enable_debug = atoi(getenv("E2FSCK_JBD_DEBUG"));
16144 #endif
16145         return 0;
16146 }
16147
16148 static const char *my_ver_string = E2FSPROGS_VERSION;
16149 static const char *my_ver_date = E2FSPROGS_DATE;
16150
16151 int e2fsck_main (int argc, char *argv[])
16152 {
16153         errcode_t       retval = 0;
16154         int             exit_value = FSCK_OK;
16155         ext2_filsys     fs = 0;
16156         io_manager      io_ptr;
16157         struct ext2_super_block *sb;
16158         const char      *lib_ver_date;
16159         int             my_ver, lib_ver;
16160         e2fsck_t        ctx;
16161         struct problem_context pctx;
16162         int flags, run_result;
16163
16164         clear_problem_context(&pctx);
16165 #ifdef MTRACE
16166         mtrace();
16167 #endif
16168 #ifdef MCHECK
16169         mcheck(0);
16170 #endif
16171 #ifdef ENABLE_NLS
16172         setlocale(LC_MESSAGES, "");
16173         setlocale(LC_CTYPE, "");
16174         bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
16175         textdomain(NLS_CAT_NAME);
16176 #endif
16177         my_ver = ext2fs_parse_version_string(my_ver_string);
16178         lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
16179         if (my_ver > lib_ver) {
16180                 fprintf( stderr, _("Error: ext2fs library version "
16181                         "out of date!\n"));
16182                 show_version_only++;
16183         }
16184
16185         retval = PRS(argc, argv, &ctx);
16186         if (retval) {
16187                 com_err("e2fsck", retval,
16188                         _("while trying to initialize program"));
16189                 exit(FSCK_ERROR);
16190         }
16191         reserve_stdio_fds();
16192
16193 #ifdef RESOURCE_TRACK
16194         init_resource_track(&ctx->global_rtrack);
16195 #endif
16196
16197         if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
16198                 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
16199                          my_ver_date);
16200
16201         if (show_version_only) {
16202                 fprintf(stderr, _("\tUsing %s, %s\n"),
16203                         error_message(EXT2_ET_BASE), lib_ver_date);
16204                 exit(FSCK_OK);
16205         }
16206
16207         check_mount(ctx);
16208
16209         if (!(ctx->options & E2F_OPT_PREEN) &&
16210             !(ctx->options & E2F_OPT_NO) &&
16211             !(ctx->options & E2F_OPT_YES)) {
16212                 if (!ctx->interactive)
16213                         fatal_error(ctx,
16214                                     _("need terminal for interactive repairs"));
16215         }
16216         ctx->superblock = ctx->use_superblock;
16217 restart:
16218 #ifdef CONFIG_TESTIO_DEBUG
16219         io_ptr = test_io_manager;
16220         test_io_backing_manager = unix_io_manager;
16221 #else
16222         io_ptr = unix_io_manager;
16223 #endif
16224         flags = 0;
16225         if ((ctx->options & E2F_OPT_READONLY) == 0)
16226                 flags |= EXT2_FLAG_RW;
16227
16228         if (ctx->superblock && ctx->blocksize) {
16229                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
16230                                       flags, ctx->superblock, ctx->blocksize,
16231                                       io_ptr, &fs);
16232         } else if (ctx->superblock) {
16233                 int blocksize;
16234                 for (blocksize = EXT2_MIN_BLOCK_SIZE;
16235                      blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
16236                         retval = ext2fs_open2(ctx->filesystem_name,
16237                                               ctx->io_options, flags,
16238                                               ctx->superblock, blocksize,
16239                                               io_ptr, &fs);
16240                         if (!retval)
16241                                 break;
16242                 }
16243         } else
16244                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
16245                                       flags, 0, 0, io_ptr, &fs);
16246         if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
16247             !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
16248             ((retval == EXT2_ET_BAD_MAGIC) ||
16249              ((retval == 0) && ext2fs_check_desc(fs)))) {
16250                 if (!fs || (fs->group_desc_count > 1)) {
16251                         printf(_("%s trying backup blocks...\n"),
16252                                retval ? _("Couldn't find ext2 superblock,") :
16253                                _("Group descriptors look bad..."));
16254                         get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
16255                         if (fs)
16256                                 ext2fs_close(fs);
16257                         goto restart;
16258                 }
16259         }
16260         if (retval) {
16261                 com_err(ctx->program_name, retval, _("while trying to open %s"),
16262                         ctx->filesystem_name);
16263                 if (retval == EXT2_ET_REV_TOO_HIGH) {
16264                         printf(_("The filesystem revision is apparently "
16265                                "too high for this version of e2fsck.\n"
16266                                "(Or the filesystem superblock "
16267                                "is corrupt)\n\n"));
16268                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
16269                 } else if (retval == EXT2_ET_SHORT_READ)
16270                         printf(_("Could this be a zero-length partition?\n"));
16271                 else if ((retval == EPERM) || (retval == EACCES))
16272                         printf(_("You must have %s access to the "
16273                                "filesystem or be root\n"),
16274                                (ctx->options & E2F_OPT_READONLY) ?
16275                                "r/o" : "r/w");
16276                 else if (retval == ENXIO)
16277                         printf(_("Possibly non-existent or swap device?\n"));
16278 #ifdef EROFS
16279                 else if (retval == EROFS)
16280                         printf(_("Disk write-protected; use the -n option "
16281                                "to do a read-only\n"
16282                                "check of the device.\n"));
16283 #endif
16284                 else
16285                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
16286                 fatal_error(ctx, 0);
16287         }
16288         ctx->fs = fs;
16289         fs->priv_data = ctx;
16290         sb = fs->super;
16291         if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
16292                 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
16293                         _("while trying to open %s"),
16294                         ctx->filesystem_name);
16295         get_newer:
16296                 fatal_error(ctx, _("Get a newer version of e2fsck!"));
16297         }
16298
16299         /*
16300          * Set the device name, which is used whenever we print error
16301          * or informational messages to the user.
16302          */
16303         if (ctx->device_name == 0 &&
16304             (sb->s_volume_name[0] != 0)) {
16305                 ctx->device_name = string_copy(ctx, sb->s_volume_name,
16306                                                sizeof(sb->s_volume_name));
16307         }
16308         if (ctx->device_name == 0)
16309                 ctx->device_name = ctx->filesystem_name;
16310
16311         /*
16312          * Make sure the ext3 superblock fields are consistent.
16313          */
16314         retval = e2fsck_check_ext3_journal(ctx);
16315         if (retval) {
16316                 com_err(ctx->program_name, retval,
16317                         _("while checking ext3 journal for %s"),
16318                         ctx->device_name);
16319                 fatal_error(ctx, 0);
16320         }
16321
16322         /*
16323          * Check to see if we need to do ext3-style recovery.  If so,
16324          * do it, and then restart the fsck.
16325          */
16326         if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
16327                 if (ctx->options & E2F_OPT_READONLY) {
16328                         printf(_("Warning: skipping journal recovery "
16329                                  "because doing a read-only filesystem "
16330                                  "check.\n"));
16331                         io_channel_flush(ctx->fs->io);
16332                 } else {
16333                         if (ctx->flags & E2F_FLAG_RESTARTED) {
16334                                 /*
16335                                  * Whoops, we attempted to run the
16336                                  * journal twice.  This should never
16337                                  * happen, unless the hardware or
16338                                  * device driver is being bogus.
16339                                  */
16340                                 com_err(ctx->program_name, 0,
16341                                         _("unable to set superblock flags on %s\n"), ctx->device_name);
16342                                 fatal_error(ctx, 0);
16343                         }
16344                         retval = e2fsck_run_ext3_journal(ctx);
16345                         if (retval) {
16346                                 com_err(ctx->program_name, retval,
16347                                 _("while recovering ext3 journal of %s"),
16348                                         ctx->device_name);
16349                                 fatal_error(ctx, 0);
16350                         }
16351                         ext2fs_close(ctx->fs);
16352                         ctx->fs = 0;
16353                         ctx->flags |= E2F_FLAG_RESTARTED;
16354                         goto restart;
16355                 }
16356         }
16357
16358         /*
16359          * Check for compatibility with the feature sets.  We need to
16360          * be more stringent than ext2fs_open().
16361          */
16362         if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
16363             (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
16364                 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
16365                         "(%s)", ctx->device_name);
16366                 goto get_newer;
16367         }
16368         if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
16369                 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
16370                         "(%s)", ctx->device_name);
16371                 goto get_newer;
16372         }
16373 #ifdef ENABLE_COMPRESSION
16374         if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
16375                 com_err(ctx->program_name, 0,
16376                         _("Warning: compression support is experimental.\n"));
16377 #endif
16378 #ifndef ENABLE_HTREE
16379         if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
16380                 com_err(ctx->program_name, 0,
16381                         _("E2fsck not compiled with HTREE support,\n\t"
16382                           "but filesystem %s has HTREE directories.\n"),
16383                         ctx->device_name);
16384                 goto get_newer;
16385         }
16386 #endif
16387
16388         /*
16389          * If the user specified a specific superblock, presumably the
16390          * master superblock has been trashed.  So we mark the
16391          * superblock as dirty, so it can be written out.
16392          */
16393         if (ctx->superblock &&
16394             !(ctx->options & E2F_OPT_READONLY))
16395                 ext2fs_mark_super_dirty(fs);
16396
16397         /*
16398          * We only update the master superblock because (a) paranoia;
16399          * we don't want to corrupt the backup superblocks, and (b) we
16400          * don't need to update the mount count and last checked
16401          * fields in the backup superblock (the kernel doesn't
16402          * update the backup superblocks anyway).
16403          */
16404         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
16405
16406         ehandler_init(fs->io);
16407
16408         if (ctx->superblock)
16409                 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
16410         ext2fs_mark_valid(fs);
16411         check_super_block(ctx);
16412         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16413                 fatal_error(ctx, 0);
16414         check_if_skip(ctx);
16415         if (bad_blocks_file)
16416                 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
16417         else if (cflag)
16418                 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
16419         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16420                 fatal_error(ctx, 0);
16421 #ifdef ENABLE_SWAPFS
16422         if (normalize_swapfs) {
16423                 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ==
16424                     ext2fs_native_flag()) {
16425                         fprintf(stderr, _("%s: Filesystem byte order "
16426                                 "already normalized.\n"), ctx->device_name);
16427                         fatal_error(ctx, 0);
16428                 }
16429         }
16430         if (swapfs) {
16431                 swap_filesys(ctx);
16432                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16433                         fatal_error(ctx, 0);
16434         }
16435 #endif
16436
16437         /*
16438          * Mark the system as valid, 'til proven otherwise
16439          */
16440         ext2fs_mark_valid(fs);
16441
16442         retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
16443         if (retval) {
16444                 com_err(ctx->program_name, retval,
16445                         _("while reading bad blocks inode"));
16446                 preenhalt(ctx);
16447                 printf(_("This doesn't bode well,"
16448                          " but we'll try to go on...\n"));
16449         }
16450
16451         run_result = e2fsck_run(ctx);
16452         e2fsck_clear_progbar(ctx);
16453         if (run_result == E2F_FLAG_RESTART) {
16454                 printf(_("Restarting e2fsck from the beginning...\n"));
16455                 retval = e2fsck_reset_context(ctx);
16456                 if (retval) {
16457                         com_err(ctx->program_name, retval,
16458                                 _("while resetting context"));
16459                         fatal_error(ctx, 0);
16460                 }
16461                 ext2fs_close(fs);
16462                 goto restart;
16463         }
16464         if (run_result & E2F_FLAG_CANCEL) {
16465                 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
16466                        ctx->device_name : ctx->filesystem_name);
16467                 exit_value |= FSCK_CANCELED;
16468         }
16469         if (run_result & E2F_FLAG_ABORT)
16470                 fatal_error(ctx, _("aborted"));
16471
16472 #ifdef MTRACE
16473         mtrace_print("Cleanup");
16474 #endif
16475         if (ext2fs_test_changed(fs)) {
16476                 exit_value |= FSCK_NONDESTRUCT;
16477                 if (!(ctx->options & E2F_OPT_PREEN))
16478                     printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
16479                                ctx->device_name);
16480                 if (ctx->mount_flags & EXT2_MF_ISROOT) {
16481                         printf(_("%s: ***** REBOOT LINUX *****\n"),
16482                                ctx->device_name);
16483                         exit_value |= FSCK_REBOOT;
16484                 }
16485         }
16486         if (!ext2fs_test_valid(fs)) {
16487                 printf(_("\n%s: ********** WARNING: Filesystem still has "
16488                          "errors **********\n\n"), ctx->device_name);
16489                 exit_value |= FSCK_UNCORRECTED;
16490                 exit_value &= ~FSCK_NONDESTRUCT;
16491         }
16492         if (exit_value & FSCK_CANCELED)
16493                 exit_value &= ~FSCK_NONDESTRUCT;
16494         else {
16495                 show_stats(ctx);
16496                 if (!(ctx->options & E2F_OPT_READONLY)) {
16497                         if (ext2fs_test_valid(fs)) {
16498                                 if (!(sb->s_state & EXT2_VALID_FS))
16499                                         exit_value |= FSCK_NONDESTRUCT;
16500                                 sb->s_state = EXT2_VALID_FS;
16501                         } else
16502                                 sb->s_state &= ~EXT2_VALID_FS;
16503                         sb->s_mnt_count = 0;
16504                         sb->s_lastcheck = time(NULL);
16505                         ext2fs_mark_super_dirty(fs);
16506                 }
16507         }
16508
16509         e2fsck_write_bitmaps(ctx);
16510
16511         ext2fs_close(fs);
16512         ctx->fs = NULL;
16513         free(ctx->filesystem_name);
16514         free(ctx->journal_name);
16515         e2fsck_free_context(ctx);
16516
16517 #ifdef RESOURCE_TRACK
16518         if (ctx->options & E2F_OPT_TIME)
16519                 print_resource_track(NULL, &ctx->global_rtrack);
16520 #endif
16521
16522         return exit_value;
16523 }