diff options
author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-28 15:16:22 +0000 |
---|---|---|
committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-28 15:16:22 +0000 |
commit | 69d728be18f6780421c71390ab15e3ae9374e3b2 (patch) | |
tree | dc257a920a49d417809dc10dc94a6d397ca46c1e | |
parent | 747fc5d5fda30e7d4314d8abe80029f3792602d6 (diff) | |
download | busybox-w32-69d728be18f6780421c71390ab15e3ae9374e3b2.tar.gz busybox-w32-69d728be18f6780421c71390ab15e3ae9374e3b2.tar.bz2 busybox-w32-69d728be18f6780421c71390ab15e3ae9374e3b2.zip |
more const, inline, forward declaration usage, strip 20k source size ;-)
-rw-r--r-- | e2fsprogs/e2fsbb.h | 2 | ||||
-rw-r--r-- | e2fsprogs/e2fsck.c | 1635 |
2 files changed, 459 insertions, 1178 deletions
diff --git a/e2fsprogs/e2fsbb.h b/e2fsprogs/e2fsbb.h index 45079df81..7e4d1ab48 100644 --- a/e2fsprogs/e2fsbb.h +++ b/e2fsprogs/e2fsbb.h | |||
@@ -29,7 +29,6 @@ typedef long errcode_t; | |||
29 | /* NLS crap */ | 29 | /* NLS crap */ |
30 | #define _(x) x | 30 | #define _(x) x |
31 | #define N_(x) x | 31 | #define N_(x) x |
32 | #define P_(singular, plural, n) ((n) == 1 ? (singular) : (plural)) | ||
33 | 32 | ||
34 | /* misc crap */ | 33 | /* misc crap */ |
35 | #define fatal_error(err, msg) bb_error_msg_and_die(msg) | 34 | #define fatal_error(err, msg) bb_error_msg_and_die(msg) |
@@ -38,7 +37,6 @@ typedef long errcode_t; | |||
38 | 37 | ||
39 | /* header defines */ | 38 | /* header defines */ |
40 | #define ENABLE_HTREE 1 | 39 | #define ENABLE_HTREE 1 |
41 | #define HAVE_DIRENT_H 1 | ||
42 | #define HAVE_ERRNO_H 1 | 40 | #define HAVE_ERRNO_H 1 |
43 | #define HAVE_EXT2_IOCTLS 1 | 41 | #define HAVE_EXT2_IOCTLS 1 |
44 | #define HAVE_GETOPT_H 1 | 42 | #define HAVE_GETOPT_H 1 |
diff --git a/e2fsprogs/e2fsck.c b/e2fsprogs/e2fsck.c index 74bc9f7b8..3af03f433 100644 --- a/e2fsprogs/e2fsck.c +++ b/e2fsprogs/e2fsck.c | |||
@@ -1,9 +1,35 @@ | |||
1 | /* | 1 | /* |
2 | * e2fsck | 2 | * e2fsck |
3 | * | 3 | * |
4 | * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be | 4 | * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. |
5 | * This file may be | ||
5 | * redistributed under the terms of the GNU Public License. | 6 | * redistributed under the terms of the GNU Public License. |
6 | * | 7 | * |
8 | * | ||
9 | * Dictionary Abstract Data Type | ||
10 | * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> | ||
11 | * Free Software License: | ||
12 | * All rights are reserved by the author, with the following exceptions: | ||
13 | * Permission is granted to freely reproduce and distribute this software, | ||
14 | * possibly in exchange for a fee, provided that this copyright notice appears | ||
15 | * intact. Permission is also granted to adapt this software to produce | ||
16 | * derivative works, as long as the modified versions carry this copyright | ||
17 | * notice and additional notices stating that the work has been modified. | ||
18 | * This source code may be translated into executable form and incorporated | ||
19 | * into proprietary software; there is no requirement for such software to | ||
20 | * contain a copyright notice related to this source. | ||
21 | * | ||
22 | * linux/fs/recovery and linux/fs/revoke | ||
23 | * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 | ||
24 | * | ||
25 | * Copyright 1999-2000 Red Hat Software --- All Rights Reserved | ||
26 | * | ||
27 | * This file is part of the Linux kernel and is made available under | ||
28 | * the terms of the GNU General Public License, version 2, or at your | ||
29 | * option, any later version, incorporated herein by reference. | ||
30 | * | ||
31 | * Journal recovery routines for the generic filesystem journaling code; | ||
32 | * part of the ext2fs journaling system. | ||
7 | */ | 33 | */ |
8 | 34 | ||
9 | #ifndef _GNU_SOURCE | 35 | #ifndef _GNU_SOURCE |
@@ -172,16 +198,17 @@ struct resource_track { | |||
172 | #define E2F_PASS_5 5 | 198 | #define E2F_PASS_5 5 |
173 | #define E2F_PASS_1B 6 | 199 | #define E2F_PASS_1B 6 |
174 | 200 | ||
175 | /* | ||
176 | * Define the extended attribute refcount structure | ||
177 | */ | ||
178 | typedef struct ea_refcount *ext2_refcount_t; | ||
179 | 201 | ||
180 | /* | 202 | /* |
181 | * This is the global e2fsck structure. | 203 | * This is the global e2fsck structure. |
182 | */ | 204 | */ |
183 | typedef struct e2fsck_struct *e2fsck_t; | 205 | typedef struct e2fsck_struct *e2fsck_t; |
184 | 206 | ||
207 | /* | ||
208 | * Define the extended attribute refcount structure | ||
209 | */ | ||
210 | typedef struct ea_refcount *ext2_refcount_t; | ||
211 | |||
185 | struct e2fsck_struct { | 212 | struct e2fsck_struct { |
186 | ext2_filsys fs; | 213 | ext2_filsys fs; |
187 | const char *program_name; | 214 | const char *program_name; |
@@ -335,64 +362,10 @@ typedef struct region_struct *region_t; | |||
335 | * Procedure declarations | 362 | * Procedure declarations |
336 | */ | 363 | */ |
337 | 364 | ||
338 | static void e2fsck_pass1(e2fsck_t ctx); | ||
339 | static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf); | 365 | 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 | 366 | ||
390 | /* pass1.c */ | 367 | /* pass1.c */ |
391 | static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); | 368 | 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 | 369 | ||
397 | /* pass2.c */ | 370 | /* pass2.c */ |
398 | static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, | 371 | static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, |
@@ -406,34 +379,15 @@ 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, | 379 | static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, |
407 | int adj); | 380 | int adj); |
408 | 381 | ||
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 */ | 382 | /* 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); | 383 | static void e2fsck_rehash_directories(e2fsck_t ctx); |
418 | 384 | ||
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 */ | 385 | /* util.c */ |
429 | static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, | 386 | static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, |
430 | const char *description); | 387 | const char *description); |
431 | static int ask(e2fsck_t ctx, const char * string, int def); | 388 | 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); | 389 | static void e2fsck_read_bitmaps(e2fsck_t ctx); |
434 | static void e2fsck_write_bitmaps(e2fsck_t ctx); | ||
435 | static void preenhalt(e2fsck_t ctx); | 390 | static void preenhalt(e2fsck_t ctx); |
436 | static char *string_copy(e2fsck_t ctx, const char *str, int len); | ||
437 | #ifdef RESOURCE_TRACK | 391 | #ifdef RESOURCE_TRACK |
438 | static void print_resource_track(const char *desc, | 392 | static void print_resource_track(const char *desc, |
439 | struct resource_track *track); | 393 | struct resource_track *track); |
@@ -448,7 +402,6 @@ static void mtrace_print(char *mesg); | |||
448 | #endif | 402 | #endif |
449 | static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, | 403 | static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, |
450 | const char *name, io_manager manager); | 404 | const char *name, io_manager manager); |
451 | static int ext2_file_type(unsigned int mode); | ||
452 | 405 | ||
453 | /* unix.c */ | 406 | /* unix.c */ |
454 | static void e2fsck_clear_progbar(e2fsck_t ctx); | 407 | static void e2fsck_clear_progbar(e2fsck_t ctx); |
@@ -477,15 +430,15 @@ struct problem_context { | |||
477 | * handled as a set. The user answers once for a particular latch | 430 | * handled as a set. The user answers once for a particular latch |
478 | * group. | 431 | * group. |
479 | */ | 432 | */ |
480 | #define PR_LATCH_MASK 0x0ff0 /* Latch mask */ | 433 | #define PR_LATCH_MASK 0x0ff0 /* Latch mask */ |
481 | #define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */ | 434 | #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) */ | 435 | #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. */ | 436 | #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. */ | 437 | #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */ |
485 | #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */ | 438 | #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */ |
486 | #define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */ | 439 | #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 */ | 440 | #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */ |
488 | #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */ | 441 | #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */ |
489 | #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */ | 442 | #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */ |
490 | 443 | ||
491 | #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1) | 444 | #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1) |
@@ -1339,28 +1292,12 @@ static int end_problem_latch(e2fsck_t ctx, int mask); | |||
1339 | static int set_latch_flags(int mask, int setflags, int clearflags); | 1292 | static int set_latch_flags(int mask, int setflags, int clearflags); |
1340 | static void clear_problem_context(struct problem_context *ctx); | 1293 | static void clear_problem_context(struct problem_context *ctx); |
1341 | 1294 | ||
1342 | /* message.c */ | ||
1343 | static void print_e2fsck_message(e2fsck_t ctx, const char *msg, | ||
1344 | struct problem_context *pctx, int first); | ||
1345 | |||
1346 | /* | 1295 | /* |
1347 | * Dictionary Abstract Data Type | 1296 | * Dictionary Abstract Data Type |
1348 | * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> | 1297 | * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> |
1349 | * | 1298 | * |
1350 | * Free Software License: | 1299 | * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz |
1351 | * | 1300 | * kazlib_1_20 |
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 | */ | 1301 | */ |
1365 | 1302 | ||
1366 | #ifndef DICT_H | 1303 | #ifndef DICT_H |
@@ -1389,17 +1326,14 @@ typedef struct dnode_t { | |||
1389 | } dnode_t; | 1326 | } dnode_t; |
1390 | 1327 | ||
1391 | typedef int (*dict_comp_t)(const void *, const void *); | 1328 | typedef int (*dict_comp_t)(const void *, const void *); |
1392 | typedef dnode_t *(*dnode_alloc_t)(void *); | 1329 | typedef void (*dnode_free_t)(dnode_t *); |
1393 | typedef void (*dnode_free_t)(dnode_t *, void *); | ||
1394 | 1330 | ||
1395 | typedef struct dict_t { | 1331 | typedef struct dict_t { |
1396 | dnode_t dict_nilnode; | 1332 | dnode_t dict_nilnode; |
1397 | dictcount_t dict_nodecount; | 1333 | dictcount_t dict_nodecount; |
1398 | dictcount_t dict_maxcount; | 1334 | dictcount_t dict_maxcount; |
1399 | dict_comp_t dict_compare; | 1335 | dict_comp_t dict_compare; |
1400 | dnode_alloc_t dict_allocnode; | ||
1401 | dnode_free_t dict_freenode; | 1336 | dnode_free_t dict_freenode; |
1402 | void *dict_context; | ||
1403 | int dict_dupes; | 1337 | int dict_dupes; |
1404 | } dict_t; | 1338 | } dict_t; |
1405 | 1339 | ||
@@ -1410,19 +1344,6 @@ typedef struct dict_load_t { | |||
1410 | dnode_t dict_nilnode; | 1344 | dnode_t dict_nilnode; |
1411 | } dict_load_t; | 1345 | } dict_load_t; |
1412 | 1346 | ||
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) | 1347 | #define dict_count(D) ((D)->dict_nodecount) |
1427 | #define dnode_get(N) ((N)->dict_data) | 1348 | #define dnode_get(N) ((N)->dict_data) |
1428 | #define dnode_getkey(N) ((N)->dict_key) | 1349 | #define dnode_getkey(N) ((N)->dict_key) |
@@ -1480,11 +1401,6 @@ typedef struct { | |||
1480 | } kmem_cache_t; | 1401 | } kmem_cache_t; |
1481 | 1402 | ||
1482 | #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length) | 1403 | #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 | 1404 | ||
1489 | /* | 1405 | /* |
1490 | * We use the standard libext2fs portability tricks for inline | 1406 | * We use the standard libext2fs portability tricks for inline |
@@ -1494,6 +1410,7 @@ typedef struct { | |||
1494 | static _INLINE_ kmem_cache_t * do_cache_create(int len) | 1410 | static _INLINE_ kmem_cache_t * do_cache_create(int len) |
1495 | { | 1411 | { |
1496 | kmem_cache_t *new_cache; | 1412 | kmem_cache_t *new_cache; |
1413 | |||
1497 | new_cache = malloc(sizeof(*new_cache)); | 1414 | new_cache = malloc(sizeof(*new_cache)); |
1498 | if (new_cache) | 1415 | if (new_cache) |
1499 | new_cache->object_length = len; | 1416 | new_cache->object_length = len; |
@@ -1511,29 +1428,7 @@ static _INLINE_ void do_cache_destroy(kmem_cache_t *cache) | |||
1511 | #include "ext2fs/kernel-jbd.h" | 1428 | #include "ext2fs/kernel-jbd.h" |
1512 | 1429 | ||
1513 | /* | 1430 | /* |
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 | 1431 | * 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 | */ | 1432 | */ |
1538 | 1433 | ||
1539 | static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, | 1434 | static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, |
@@ -1546,7 +1441,7 @@ static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk) | |||
1546 | return; | 1441 | return; |
1547 | } | 1442 | } |
1548 | 1443 | ||
1549 | void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, | 1444 | static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, |
1550 | int replace_bad_blocks) | 1445 | int replace_bad_blocks) |
1551 | { | 1446 | { |
1552 | ext2_filsys fs = ctx->fs; | 1447 | ext2_filsys fs = ctx->fs; |
@@ -1659,22 +1554,6 @@ static int check_bb_inode_blocks(ext2_filsys fs, | |||
1659 | 1554 | ||
1660 | /* | 1555 | /* |
1661 | * Dictionary Abstract Data Type | 1556 | * 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 | */ | 1557 | */ |
1679 | 1558 | ||
1680 | 1559 | ||
@@ -1698,22 +1577,15 @@ static int check_bb_inode_blocks(ext2_filsys fs, | |||
1698 | #define data dict_data | 1577 | #define data dict_data |
1699 | 1578 | ||
1700 | #define nilnode dict_nilnode | 1579 | #define nilnode dict_nilnode |
1701 | #define nodecount dict_nodecount | ||
1702 | #define maxcount dict_maxcount | 1580 | #define maxcount dict_maxcount |
1703 | #define compare dict_compare | 1581 | #define compare dict_compare |
1704 | #define allocnode dict_allocnode | ||
1705 | #define freenode dict_freenode | ||
1706 | #define context dict_context | ||
1707 | #define dupes dict_dupes | 1582 | #define dupes dict_dupes |
1708 | 1583 | ||
1709 | #define dictptr dict_dictptr | ||
1710 | |||
1711 | #define dict_root(D) ((D)->nilnode.left) | 1584 | #define dict_root(D) ((D)->nilnode.left) |
1712 | #define dict_nil(D) (&(D)->nilnode) | 1585 | #define dict_nil(D) (&(D)->nilnode) |
1713 | #define DICT_DEPTH_MAX 64 | 1586 | #define DICT_DEPTH_MAX 64 |
1714 | 1587 | ||
1715 | static dnode_t *dnode_alloc(void *context); | 1588 | static void dnode_free(dnode_t *node); |
1716 | static void dnode_free(dnode_t *node, void *context); | ||
1717 | 1589 | ||
1718 | /* | 1590 | /* |
1719 | * Perform a ``left rotation'' adjustment on the tree. The given node P and | 1591 | * Perform a ``left rotation'' adjustment on the tree. The given node P and |
@@ -1783,7 +1655,7 @@ static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) | |||
1783 | return; | 1655 | return; |
1784 | free_nodes(dict, node->left, nil); | 1656 | free_nodes(dict, node->left, nil); |
1785 | free_nodes(dict, node->right, nil); | 1657 | free_nodes(dict, node->right, nil); |
1786 | dict->freenode(node, dict->context); | 1658 | dict->dict_freenode(node); |
1787 | } | 1659 | } |
1788 | 1660 | ||
1789 | /* | 1661 | /* |
@@ -1808,15 +1680,10 @@ static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) | |||
1808 | * Select a different set of node allocator routines. | 1680 | * Select a different set of node allocator routines. |
1809 | */ | 1681 | */ |
1810 | 1682 | ||
1811 | void dict_set_allocator(dict_t *dict, dnode_alloc_t al, | 1683 | static void dict_set_allocator(dict_t *dict, dnode_free_t fr) |
1812 | dnode_free_t fr, void *context) | ||
1813 | { | 1684 | { |
1814 | assert (dict_count(dict) == 0); | 1685 | assert (dict_count(dict) == 0); |
1815 | assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL)); | 1686 | dict->dict_freenode = fr; |
1816 | |||
1817 | dict->allocnode = al ? al : dnode_alloc; | ||
1818 | dict->freenode = fr ? fr : dnode_free; | ||
1819 | dict->context = context; | ||
1820 | } | 1687 | } |
1821 | 1688 | ||
1822 | /* | 1689 | /* |
@@ -1824,11 +1691,11 @@ void dict_set_allocator(dict_t *dict, dnode_alloc_t al, | |||
1824 | * installed free routine. The dictionary is emptied. | 1691 | * installed free routine. The dictionary is emptied. |
1825 | */ | 1692 | */ |
1826 | 1693 | ||
1827 | void dict_free_nodes(dict_t *dict) | 1694 | static void dict_free_nodes(dict_t *dict) |
1828 | { | 1695 | { |
1829 | dnode_t *nil = dict_nil(dict), *root = dict_root(dict); | 1696 | dnode_t *nil = dict_nil(dict), *root = dict_root(dict); |
1830 | free_nodes(dict, root, nil); | 1697 | free_nodes(dict, root, nil); |
1831 | dict->nodecount = 0; | 1698 | dict->dict_nodecount = 0; |
1832 | dict->nilnode.left = &dict->nilnode; | 1699 | dict->nilnode.left = &dict->nilnode; |
1833 | dict->nilnode.right = &dict->nilnode; | 1700 | dict->nilnode.right = &dict->nilnode; |
1834 | } | 1701 | } |
@@ -1837,13 +1704,11 @@ void dict_free_nodes(dict_t *dict) | |||
1837 | * Initialize a user-supplied dictionary object. | 1704 | * Initialize a user-supplied dictionary object. |
1838 | */ | 1705 | */ |
1839 | 1706 | ||
1840 | dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) | 1707 | static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) |
1841 | { | 1708 | { |
1842 | dict->compare = comp; | 1709 | dict->compare = comp; |
1843 | dict->allocnode = dnode_alloc; | 1710 | dict->dict_freenode = dnode_free; |
1844 | dict->freenode = dnode_free; | 1711 | dict->dict_nodecount = 0; |
1845 | dict->context = NULL; | ||
1846 | dict->nodecount = 0; | ||
1847 | dict->maxcount = maxcount; | 1712 | dict->maxcount = maxcount; |
1848 | dict->nilnode.left = &dict->nilnode; | 1713 | dict->nilnode.left = &dict->nilnode; |
1849 | dict->nilnode.right = &dict->nilnode; | 1714 | dict->nilnode.right = &dict->nilnode; |
@@ -1860,7 +1725,7 @@ dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) | |||
1860 | * located node is returned. | 1725 | * located node is returned. |
1861 | */ | 1726 | */ |
1862 | 1727 | ||
1863 | dnode_t *dict_lookup(dict_t *dict, const void *key) | 1728 | static dnode_t *dict_lookup(dict_t *dict, const void *key) |
1864 | { | 1729 | { |
1865 | dnode_t *root = dict_root(dict); | 1730 | dnode_t *root = dict_root(dict); |
1866 | dnode_t *nil = dict_nil(dict); | 1731 | dnode_t *nil = dict_nil(dict); |
@@ -1901,7 +1766,7 @@ dnode_t *dict_lookup(dict_t *dict, const void *key) | |||
1901 | * function returns true). | 1766 | * function returns true). |
1902 | */ | 1767 | */ |
1903 | 1768 | ||
1904 | void dict_insert(dict_t *dict, dnode_t *node, const void *key) | 1769 | static void dict_insert(dict_t *dict, dnode_t *node, const void *key) |
1905 | { | 1770 | { |
1906 | dnode_t *where = dict_root(dict), *nil = dict_nil(dict); | 1771 | dnode_t *where = dict_root(dict), *nil = dict_nil(dict); |
1907 | dnode_t *parent = nil, *uncle, *grandpa; | 1772 | dnode_t *parent = nil, *uncle, *grandpa; |
@@ -1933,7 +1798,7 @@ void dict_insert(dict_t *dict, dnode_t *node, const void *key) | |||
1933 | node->left = nil; | 1798 | node->left = nil; |
1934 | node->right = nil; | 1799 | node->right = nil; |
1935 | 1800 | ||
1936 | dict->nodecount++; | 1801 | dict->dict_nodecount++; |
1937 | 1802 | ||
1938 | /* red black adjustments */ | 1803 | /* red black adjustments */ |
1939 | 1804 | ||
@@ -1992,9 +1857,18 @@ void dict_insert(dict_t *dict, dnode_t *node, const void *key) | |||
1992 | * the data item. | 1857 | * the data item. |
1993 | */ | 1858 | */ |
1994 | 1859 | ||
1995 | int dict_alloc_insert(dict_t *dict, const void *key, void *data) | 1860 | static dnode_t *dnode_init(dnode_t *dnode, void *data) |
1996 | { | 1861 | { |
1997 | dnode_t *node = dict->allocnode(dict->context); | 1862 | dnode->data = data; |
1863 | dnode->parent = NULL; | ||
1864 | dnode->left = NULL; | ||
1865 | dnode->right = NULL; | ||
1866 | return dnode; | ||
1867 | } | ||
1868 | |||
1869 | static int dict_alloc_insert(dict_t *dict, const void *key, void *data) | ||
1870 | { | ||
1871 | dnode_t *node = malloc(sizeof(dnode_t)); | ||
1998 | 1872 | ||
1999 | if (node) { | 1873 | if (node) { |
2000 | dnode_init(node, data); | 1874 | dnode_init(node, data); |
@@ -2009,7 +1883,7 @@ int dict_alloc_insert(dict_t *dict, const void *key, void *data) | |||
2009 | * (that is, dict_isempty(dict) returns 1) a null pointer is returned. | 1883 | * (that is, dict_isempty(dict) returns 1) a null pointer is returned. |
2010 | */ | 1884 | */ |
2011 | 1885 | ||
2012 | dnode_t *dict_first(dict_t *dict) | 1886 | static dnode_t *dict_first(dict_t *dict) |
2013 | { | 1887 | { |
2014 | dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; | 1888 | dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; |
2015 | 1889 | ||
@@ -2027,7 +1901,7 @@ dnode_t *dict_first(dict_t *dict) | |||
2027 | * the nil node. | 1901 | * the nil node. |
2028 | */ | 1902 | */ |
2029 | 1903 | ||
2030 | dnode_t *dict_next(dict_t *dict, dnode_t *curr) | 1904 | static dnode_t *dict_next(dict_t *dict, dnode_t *curr) |
2031 | { | 1905 | { |
2032 | dnode_t *nil = dict_nil(dict), *parent, *left; | 1906 | dnode_t *nil = dict_nil(dict), *parent, *left; |
2033 | 1907 | ||
@@ -2048,43 +1922,12 @@ dnode_t *dict_next(dict_t *dict, dnode_t *curr) | |||
2048 | return (parent == nil) ? NULL : parent; | 1922 | return (parent == nil) ? NULL : parent; |
2049 | } | 1923 | } |
2050 | 1924 | ||
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 | 1925 | ||
2065 | static void dnode_free(dnode_t *node, void *context EXT2FS_ATTR((unused))) | 1926 | static void dnode_free(dnode_t *node) |
2066 | { | 1927 | { |
2067 | free(node); | 1928 | free(node); |
2068 | } | 1929 | } |
2069 | 1930 | ||
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 | 1931 | ||
2089 | #undef left | 1932 | #undef left |
2090 | #undef right | 1933 | #undef right |
@@ -2094,22 +1937,13 @@ const void *dnode_getkey(dnode_t *dnode) | |||
2094 | #undef data | 1937 | #undef data |
2095 | 1938 | ||
2096 | #undef nilnode | 1939 | #undef nilnode |
2097 | #undef nodecount | ||
2098 | #undef maxcount | 1940 | #undef maxcount |
2099 | #undef compare | 1941 | #undef compare |
2100 | #undef allocnode | ||
2101 | #undef freenode | ||
2102 | #undef context | ||
2103 | #undef dupes | 1942 | #undef dupes |
2104 | 1943 | ||
2105 | #undef dictptr | ||
2106 | |||
2107 | 1944 | ||
2108 | /* | 1945 | /* |
2109 | * dirinfo.c --- maintains the directory information table for e2fsck. | 1946 | * 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 | */ | 1947 | */ |
2114 | 1948 | ||
2115 | /* | 1949 | /* |
@@ -2117,7 +1951,7 @@ const void *dnode_getkey(dnode_t *dnode) | |||
2117 | * entry. During pass1, the passed-in parent is 0; it will get filled | 1951 | * entry. During pass1, the passed-in parent is 0; it will get filled |
2118 | * in during pass2. | 1952 | * in during pass2. |
2119 | */ | 1953 | */ |
2120 | void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) | 1954 | static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) |
2121 | { | 1955 | { |
2122 | struct dir_info *dir; | 1956 | struct dir_info *dir; |
2123 | int i, j; | 1957 | int i, j; |
@@ -2182,7 +2016,7 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) | |||
2182 | * get_dir_info() --- given an inode number, try to find the directory | 2016 | * get_dir_info() --- given an inode number, try to find the directory |
2183 | * information entry for it. | 2017 | * information entry for it. |
2184 | */ | 2018 | */ |
2185 | struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) | 2019 | static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) |
2186 | { | 2020 | { |
2187 | int low, high, mid; | 2021 | int low, high, mid; |
2188 | 2022 | ||
@@ -2212,7 +2046,7 @@ struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) | |||
2212 | /* | 2046 | /* |
2213 | * Free the dir_info structure when it isn't needed any more. | 2047 | * Free the dir_info structure when it isn't needed any more. |
2214 | */ | 2048 | */ |
2215 | void e2fsck_free_dir_info(e2fsck_t ctx) | 2049 | static void e2fsck_free_dir_info(e2fsck_t ctx) |
2216 | { | 2050 | { |
2217 | if (ctx->dir_info) { | 2051 | if (ctx->dir_info) { |
2218 | ext2fs_free_mem(&ctx->dir_info); | 2052 | ext2fs_free_mem(&ctx->dir_info); |
@@ -2225,7 +2059,7 @@ void e2fsck_free_dir_info(e2fsck_t ctx) | |||
2225 | /* | 2059 | /* |
2226 | * Return the count of number of directories in the dir_info structure | 2060 | * Return the count of number of directories in the dir_info structure |
2227 | */ | 2061 | */ |
2228 | int e2fsck_get_num_dirinfo(e2fsck_t ctx) | 2062 | static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx) |
2229 | { | 2063 | { |
2230 | return ctx->dir_info_count; | 2064 | return ctx->dir_info_count; |
2231 | } | 2065 | } |
@@ -2233,18 +2067,17 @@ int e2fsck_get_num_dirinfo(e2fsck_t ctx) | |||
2233 | /* | 2067 | /* |
2234 | * A simple interator function | 2068 | * A simple interator function |
2235 | */ | 2069 | */ |
2236 | struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control) | 2070 | static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control) |
2237 | { | 2071 | { |
2238 | if (*control >= ctx->dir_info_count) | 2072 | if (*control >= ctx->dir_info_count) |
2239 | return 0; | 2073 | return 0; |
2240 | 2074 | ||
2241 | return(ctx->dir_info + (*control)++); | 2075 | return(ctx->dir_info + (*control)++); |
2242 | } | 2076 | } |
2077 | |||
2243 | /* | 2078 | /* |
2244 | * dirinfo.c --- maintains the directory information table for e2fsck. | 2079 | * dirinfo.c --- maintains the directory information table for e2fsck. |
2245 | * | 2080 | * |
2246 | * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed | ||
2247 | * under the terms of the GNU Public License. | ||
2248 | */ | 2081 | */ |
2249 | 2082 | ||
2250 | #ifdef ENABLE_HTREE | 2083 | #ifdef ENABLE_HTREE |
@@ -2254,7 +2087,7 @@ struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control) | |||
2254 | * entry. During pass1, the passed-in parent is 0; it will get filled | 2087 | * entry. During pass1, the passed-in parent is 0; it will get filled |
2255 | * in during pass2. | 2088 | * in during pass2. |
2256 | */ | 2089 | */ |
2257 | void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks) | 2090 | static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks) |
2258 | { | 2091 | { |
2259 | struct dx_dir_info *dir; | 2092 | struct dx_dir_info *dir; |
2260 | int i, j; | 2093 | int i, j; |
@@ -2319,7 +2152,7 @@ void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks) | |||
2319 | * get_dx_dir_info() --- given an inode number, try to find the directory | 2152 | * get_dx_dir_info() --- given an inode number, try to find the directory |
2320 | * information entry for it. | 2153 | * information entry for it. |
2321 | */ | 2154 | */ |
2322 | struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino) | 2155 | static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino) |
2323 | { | 2156 | { |
2324 | int low, high, mid; | 2157 | int low, high, mid; |
2325 | 2158 | ||
@@ -2349,7 +2182,7 @@ struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino) | |||
2349 | /* | 2182 | /* |
2350 | * Free the dx_dir_info structure when it isn't needed any more. | 2183 | * Free the dx_dir_info structure when it isn't needed any more. |
2351 | */ | 2184 | */ |
2352 | void e2fsck_free_dx_dir_info(e2fsck_t ctx) | 2185 | static void e2fsck_free_dx_dir_info(e2fsck_t ctx) |
2353 | { | 2186 | { |
2354 | int i; | 2187 | int i; |
2355 | struct dx_dir_info *dir; | 2188 | struct dx_dir_info *dir; |
@@ -2372,7 +2205,7 @@ void e2fsck_free_dx_dir_info(e2fsck_t ctx) | |||
2372 | /* | 2205 | /* |
2373 | * A simple interator function | 2206 | * A simple interator function |
2374 | */ | 2207 | */ |
2375 | struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control) | 2208 | static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control) |
2376 | { | 2209 | { |
2377 | if (*control >= ctx->dx_dir_info_count) | 2210 | if (*control >= ctx->dx_dir_info_count) |
2378 | return 0; | 2211 | return 0; |
@@ -2384,18 +2217,12 @@ struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control) | |||
2384 | /* | 2217 | /* |
2385 | * e2fsck.c - a consistency checker for the new extended file system. | 2218 | * e2fsck.c - a consistency checker for the new extended file system. |
2386 | * | 2219 | * |
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 | */ | 2220 | */ |
2394 | 2221 | ||
2395 | /* | 2222 | /* |
2396 | * This function allocates an e2fsck context | 2223 | * This function allocates an e2fsck context |
2397 | */ | 2224 | */ |
2398 | errcode_t e2fsck_allocate_context(e2fsck_t *ret) | 2225 | static errcode_t e2fsck_allocate_context(e2fsck_t *ret) |
2399 | { | 2226 | { |
2400 | e2fsck_t context; | 2227 | e2fsck_t context; |
2401 | errcode_t retval; | 2228 | errcode_t retval; |
@@ -2413,11 +2240,33 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret) | |||
2413 | return 0; | 2240 | return 0; |
2414 | } | 2241 | } |
2415 | 2242 | ||
2243 | struct ea_refcount_el { | ||
2244 | blk_t ea_blk; | ||
2245 | int ea_count; | ||
2246 | }; | ||
2247 | |||
2248 | struct ea_refcount { | ||
2249 | blk_t count; | ||
2250 | blk_t size; | ||
2251 | blk_t cursor; | ||
2252 | struct ea_refcount_el *list; | ||
2253 | }; | ||
2254 | |||
2255 | static void ea_refcount_free(ext2_refcount_t refcount) | ||
2256 | { | ||
2257 | if (!refcount) | ||
2258 | return; | ||
2259 | |||
2260 | if (refcount->list) | ||
2261 | ext2fs_free_mem(&refcount->list); | ||
2262 | ext2fs_free_mem(&refcount); | ||
2263 | } | ||
2264 | |||
2416 | /* | 2265 | /* |
2417 | * This function resets an e2fsck context; it is called when e2fsck | 2266 | * This function resets an e2fsck context; it is called when e2fsck |
2418 | * needs to be restarted. | 2267 | * needs to be restarted. |
2419 | */ | 2268 | */ |
2420 | errcode_t e2fsck_reset_context(e2fsck_t ctx) | 2269 | static errcode_t e2fsck_reset_context(e2fsck_t ctx) |
2421 | { | 2270 | { |
2422 | ctx->flags = 0; | 2271 | ctx->flags = 0; |
2423 | ctx->lost_and_found = 0; | 2272 | ctx->lost_and_found = 0; |
@@ -2528,7 +2377,7 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) | |||
2528 | return 0; | 2377 | return 0; |
2529 | } | 2378 | } |
2530 | 2379 | ||
2531 | void e2fsck_free_context(e2fsck_t ctx) | 2380 | static void e2fsck_free_context(e2fsck_t ctx) |
2532 | { | 2381 | { |
2533 | if (!ctx) | 2382 | if (!ctx) |
2534 | return; | 2383 | return; |
@@ -2541,46 +2390,7 @@ void e2fsck_free_context(e2fsck_t ctx) | |||
2541 | } | 2390 | } |
2542 | 2391 | ||
2543 | /* | 2392 | /* |
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 | 2393 | * 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 | */ | 2394 | */ |
2585 | 2395 | ||
2586 | /* | 2396 | /* |
@@ -2590,29 +2400,9 @@ int e2fsck_run(e2fsck_t ctx) | |||
2590 | * removed from the array to save memory space. Once the EA block is | 2400 | * 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. | 2401 | * checked, its bit is set in the block_ea_map bitmap. |
2592 | */ | 2402 | */ |
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 | 2403 | ||
2610 | if (refcount->list) | ||
2611 | ext2fs_free_mem(&refcount->list); | ||
2612 | ext2fs_free_mem(&refcount); | ||
2613 | } | ||
2614 | 2404 | ||
2615 | errcode_t ea_refcount_create(int size, ext2_refcount_t *ret) | 2405 | static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret) |
2616 | { | 2406 | { |
2617 | ext2_refcount_t refcount; | 2407 | ext2_refcount_t refcount; |
2618 | errcode_t retval; | 2408 | errcode_t retval; |
@@ -2793,7 +2583,8 @@ retry: | |||
2793 | return 0; | 2583 | return 0; |
2794 | } | 2584 | } |
2795 | 2585 | ||
2796 | errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret) | 2586 | static errcode_t |
2587 | ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret) | ||
2797 | { | 2588 | { |
2798 | struct ea_refcount_el *el; | 2589 | struct ea_refcount_el *el; |
2799 | 2590 | ||
@@ -2807,7 +2598,8 @@ errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret) | |||
2807 | return 0; | 2598 | return 0; |
2808 | } | 2599 | } |
2809 | 2600 | ||
2810 | errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret) | 2601 | static errcode_t |
2602 | ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret) | ||
2811 | { | 2603 | { |
2812 | struct ea_refcount_el *el; | 2604 | struct ea_refcount_el *el; |
2813 | 2605 | ||
@@ -2822,7 +2614,8 @@ errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret) | |||
2822 | return 0; | 2614 | return 0; |
2823 | } | 2615 | } |
2824 | 2616 | ||
2825 | errcode_t ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count) | 2617 | static errcode_t |
2618 | ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count) | ||
2826 | { | 2619 | { |
2827 | struct ea_refcount_el *el; | 2620 | struct ea_refcount_el *el; |
2828 | 2621 | ||
@@ -2836,14 +2629,13 @@ errcode_t ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count) | |||
2836 | return 0; | 2629 | return 0; |
2837 | } | 2630 | } |
2838 | 2631 | ||
2839 | void ea_refcount_intr_begin(ext2_refcount_t refcount) | 2632 | static inline void ea_refcount_intr_begin(ext2_refcount_t refcount) |
2840 | { | 2633 | { |
2841 | refcount->cursor = 0; | 2634 | refcount->cursor = 0; |
2842 | } | 2635 | } |
2843 | 2636 | ||
2844 | 2637 | ||
2845 | blk_t ea_refcount_intr_next(ext2_refcount_t refcount, | 2638 | static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret) |
2846 | int *ret) | ||
2847 | { | 2639 | { |
2848 | struct ea_refcount_el *list; | 2640 | struct ea_refcount_el *list; |
2849 | 2641 | ||
@@ -2864,21 +2656,15 @@ blk_t ea_refcount_intr_next(ext2_refcount_t refcount, | |||
2864 | /* | 2656 | /* |
2865 | * ehandler.c --- handle bad block errors which come up during the | 2657 | * ehandler.c --- handle bad block errors which come up during the |
2866 | * course of an e2fsck session. | 2658 | * 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 | */ | 2659 | */ |
2871 | 2660 | ||
2872 | 2661 | ||
2873 | static const char *operation; | 2662 | static const char *operation; |
2874 | 2663 | ||
2875 | static errcode_t e2fsck_handle_read_error(io_channel channel, | 2664 | static errcode_t |
2876 | unsigned long block, | 2665 | e2fsck_handle_read_error(io_channel channel, unsigned long block, int count, |
2877 | int count, | 2666 | void *data, size_t size EXT2FS_ATTR((unused)), |
2878 | void *data, | 2667 | int actual EXT2FS_ATTR((unused)), errcode_t error) |
2879 | size_t size EXT2FS_ATTR((unused)), | ||
2880 | int actual EXT2FS_ATTR((unused)), | ||
2881 | errcode_t error) | ||
2882 | { | 2668 | { |
2883 | int i; | 2669 | int i; |
2884 | char *p; | 2670 | char *p; |
@@ -2918,13 +2704,10 @@ static errcode_t e2fsck_handle_read_error(io_channel channel, | |||
2918 | return error; | 2704 | return error; |
2919 | } | 2705 | } |
2920 | 2706 | ||
2921 | static errcode_t e2fsck_handle_write_error(io_channel channel, | 2707 | static errcode_t |
2922 | unsigned long block, | 2708 | e2fsck_handle_write_error(io_channel channel, unsigned long block, int count, |
2923 | int count, | 2709 | const void *data, size_t size EXT2FS_ATTR((unused)), |
2924 | const void *data, | 2710 | int actual EXT2FS_ATTR((unused)), errcode_t error) |
2925 | size_t size EXT2FS_ATTR((unused)), | ||
2926 | int actual EXT2FS_ATTR((unused)), | ||
2927 | errcode_t error) | ||
2928 | { | 2711 | { |
2929 | int i; | 2712 | int i; |
2930 | const char *p; | 2713 | const char *p; |
@@ -2962,7 +2745,7 @@ static errcode_t e2fsck_handle_write_error(io_channel channel, | |||
2962 | return error; | 2745 | return error; |
2963 | } | 2746 | } |
2964 | 2747 | ||
2965 | const char *ehandler_operation(const char *op) | 2748 | static inline const char *ehandler_operation(const char *op) |
2966 | { | 2749 | { |
2967 | const char *ret = operation; | 2750 | const char *ret = operation; |
2968 | 2751 | ||
@@ -2970,11 +2753,12 @@ const char *ehandler_operation(const char *op) | |||
2970 | return ret; | 2753 | return ret; |
2971 | } | 2754 | } |
2972 | 2755 | ||
2973 | void ehandler_init(io_channel channel) | 2756 | static void ehandler_init(io_channel channel) |
2974 | { | 2757 | { |
2975 | channel->read_error = e2fsck_handle_read_error; | 2758 | channel->read_error = e2fsck_handle_read_error; |
2976 | channel->write_error = e2fsck_handle_write_error; | 2759 | channel->write_error = e2fsck_handle_write_error; |
2977 | } | 2760 | } |
2761 | |||
2978 | /* | 2762 | /* |
2979 | * journal.c --- code for handling the "ext3" journal | 2763 | * journal.c --- code for handling the "ext3" journal |
2980 | * | 2764 | * |
@@ -3009,7 +2793,7 @@ static int bh_count = 0; | |||
3009 | * to use the recovery.c file virtually unchanged from the kernel, so we | 2793 | * 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. | 2794 | * don't have to do much to keep kernel and user recovery in sync. |
3011 | */ | 2795 | */ |
3012 | int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) | 2796 | static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) |
3013 | { | 2797 | { |
3014 | #ifdef USE_INODE_IO | 2798 | #ifdef USE_INODE_IO |
3015 | *phys = block; | 2799 | *phys = block; |
@@ -3031,7 +2815,7 @@ int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) | |||
3031 | #endif | 2815 | #endif |
3032 | } | 2816 | } |
3033 | 2817 | ||
3034 | struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) | 2818 | static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) |
3035 | { | 2819 | { |
3036 | struct buffer_head *bh; | 2820 | struct buffer_head *bh; |
3037 | 2821 | ||
@@ -3053,7 +2837,7 @@ struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) | |||
3053 | return bh; | 2837 | return bh; |
3054 | } | 2838 | } |
3055 | 2839 | ||
3056 | void sync_blockdev(kdev_t kdev) | 2840 | static void sync_blockdev(kdev_t kdev) |
3057 | { | 2841 | { |
3058 | io_channel io; | 2842 | io_channel io; |
3059 | 2843 | ||
@@ -3065,7 +2849,7 @@ void sync_blockdev(kdev_t kdev) | |||
3065 | io_channel_flush(io); | 2849 | io_channel_flush(io); |
3066 | } | 2850 | } |
3067 | 2851 | ||
3068 | void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) | 2852 | static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) |
3069 | { | 2853 | { |
3070 | int retval; | 2854 | int retval; |
3071 | struct buffer_head *bh; | 2855 | struct buffer_head *bh; |
@@ -3109,17 +2893,17 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) | |||
3109 | } | 2893 | } |
3110 | } | 2894 | } |
3111 | 2895 | ||
3112 | void mark_buffer_dirty(struct buffer_head *bh) | 2896 | static inline void mark_buffer_dirty(struct buffer_head *bh) |
3113 | { | 2897 | { |
3114 | bh->b_dirty = 1; | 2898 | bh->b_dirty = 1; |
3115 | } | 2899 | } |
3116 | 2900 | ||
3117 | static void mark_buffer_clean(struct buffer_head * bh) | 2901 | static inline void mark_buffer_clean(struct buffer_head * bh) |
3118 | { | 2902 | { |
3119 | bh->b_dirty = 0; | 2903 | bh->b_dirty = 0; |
3120 | } | 2904 | } |
3121 | 2905 | ||
3122 | void brelse(struct buffer_head *bh) | 2906 | static void brelse(struct buffer_head *bh) |
3123 | { | 2907 | { |
3124 | if (bh->b_dirty) | 2908 | if (bh->b_dirty) |
3125 | ll_rw_block(WRITE, 1, &bh); | 2909 | ll_rw_block(WRITE, 1, &bh); |
@@ -3128,17 +2912,17 @@ void brelse(struct buffer_head *bh) | |||
3128 | ext2fs_free_mem(&bh); | 2912 | ext2fs_free_mem(&bh); |
3129 | } | 2913 | } |
3130 | 2914 | ||
3131 | int buffer_uptodate(struct buffer_head *bh) | 2915 | static inline int buffer_uptodate(struct buffer_head *bh) |
3132 | { | 2916 | { |
3133 | return bh->b_uptodate; | 2917 | return bh->b_uptodate; |
3134 | } | 2918 | } |
3135 | 2919 | ||
3136 | void mark_buffer_uptodate(struct buffer_head *bh, int val) | 2920 | static inline void mark_buffer_uptodate(struct buffer_head *bh, int val) |
3137 | { | 2921 | { |
3138 | bh->b_uptodate = val; | 2922 | bh->b_uptodate = val; |
3139 | } | 2923 | } |
3140 | 2924 | ||
3141 | void wait_on_buffer(struct buffer_head *bh) | 2925 | static void wait_on_buffer(struct buffer_head *bh) |
3142 | { | 2926 | { |
3143 | if (!bh->b_uptodate) | 2927 | if (!bh->b_uptodate) |
3144 | ll_rw_block(READ, 1, &bh); | 2928 | ll_rw_block(READ, 1, &bh); |
@@ -3608,7 +3392,7 @@ static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, | |||
3608 | * This function makes sure that the superblock fields regarding the | 3392 | * This function makes sure that the superblock fields regarding the |
3609 | * journal are consistent. | 3393 | * journal are consistent. |
3610 | */ | 3394 | */ |
3611 | int e2fsck_check_ext3_journal(e2fsck_t ctx) | 3395 | static int e2fsck_check_ext3_journal(e2fsck_t ctx) |
3612 | { | 3396 | { |
3613 | struct ext2_super_block *sb = ctx->fs->super; | 3397 | struct ext2_super_block *sb = ctx->fs->super; |
3614 | journal_t *journal; | 3398 | journal_t *journal; |
@@ -3759,7 +3543,7 @@ errout: | |||
3759 | return retval; | 3543 | return retval; |
3760 | } | 3544 | } |
3761 | 3545 | ||
3762 | int e2fsck_run_ext3_journal(e2fsck_t ctx) | 3546 | static int e2fsck_run_ext3_journal(e2fsck_t ctx) |
3763 | { | 3547 | { |
3764 | io_manager io_ptr = ctx->fs->io->manager; | 3548 | io_manager io_ptr = ctx->fs->io->manager; |
3765 | int blocksize = ctx->fs->blocksize; | 3549 | int blocksize = ctx->fs->blocksize; |
@@ -3806,7 +3590,7 @@ int e2fsck_run_ext3_journal(e2fsck_t ctx) | |||
3806 | static const char * const journal_names[] = { | 3590 | static const char * const journal_names[] = { |
3807 | ".journal", "journal", ".journal.dat", "journal.dat", 0 }; | 3591 | ".journal", "journal", ".journal.dat", "journal.dat", 0 }; |
3808 | 3592 | ||
3809 | void e2fsck_move_ext3_journal(e2fsck_t ctx) | 3593 | static void e2fsck_move_ext3_journal(e2fsck_t ctx) |
3810 | { | 3594 | { |
3811 | struct ext2_super_block *sb = ctx->fs->super; | 3595 | struct ext2_super_block *sb = ctx->fs->super; |
3812 | struct problem_context pctx; | 3596 | struct problem_context pctx; |
@@ -3927,13 +3711,6 @@ err_out: | |||
3927 | /* | 3711 | /* |
3928 | * message.c --- print e2fsck messages (with compression) | 3712 | * message.c --- print e2fsck messages (with compression) |
3929 | * | 3713 | * |
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 | 3714 | * print_e2fsck_message() prints a message to the user, using |
3938 | * compression techniques and expansions of abbreviations. | 3715 | * compression techniques and expansions of abbreviations. |
3939 | * | 3716 | * |
@@ -4013,7 +3790,7 @@ err_out: | |||
4013 | * abbreviation of the form '@<i>' is expanded by looking up the index | 3790 | * abbreviation of the form '@<i>' is expanded by looking up the index |
4014 | * letter <i> in the table below. | 3791 | * letter <i> in the table below. |
4015 | */ | 3792 | */ |
4016 | static const char *abbrevs[] = { | 3793 | static const char * const abbrevs[] = { |
4017 | N_("aextended attribute"), | 3794 | N_("aextended attribute"), |
4018 | N_("Aerror allocating"), | 3795 | N_("Aerror allocating"), |
4019 | N_("bblock"), | 3796 | N_("bblock"), |
@@ -4049,7 +3826,7 @@ static const char *abbrevs[] = { | |||
4049 | * Give more user friendly names to the "special" inodes. | 3826 | * Give more user friendly names to the "special" inodes. |
4050 | */ | 3827 | */ |
4051 | #define num_special_inodes 11 | 3828 | #define num_special_inodes 11 |
4052 | static const char *special_inode_name[] = | 3829 | static const char * const special_inode_name[] = |
4053 | { | 3830 | { |
4054 | N_("<The NULL inode>"), /* 0 */ | 3831 | N_("<The NULL inode>"), /* 0 */ |
4055 | N_("<The bad blocks inode>"), /* 1 */ | 3832 | N_("<The bad blocks inode>"), /* 1 */ |
@@ -4113,16 +3890,19 @@ static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino) | |||
4113 | } | 3890 | } |
4114 | } | 3891 | } |
4115 | 3892 | ||
3893 | static void print_e2fsck_message(e2fsck_t ctx, const char *msg, | ||
3894 | struct problem_context *pctx, int first); | ||
4116 | /* | 3895 | /* |
4117 | * This function handles the '@' expansion. We allow recursive | 3896 | * This function handles the '@' expansion. We allow recursive |
4118 | * expansion; an @ expression can contain further '@' and '%' | 3897 | * expansion; an @ expression can contain further '@' and '%' |
4119 | * expressions. | 3898 | * expressions. |
4120 | */ | 3899 | */ |
4121 | static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch, | 3900 | static void expand_at_expression(e2fsck_t ctx, char ch, |
4122 | struct problem_context *pctx, | 3901 | struct problem_context *pctx, |
4123 | int *first) | 3902 | int *first) |
4124 | { | 3903 | { |
4125 | const char **cpp, *str; | 3904 | const char * const *cpp; |
3905 | const char *str; | ||
4126 | 3906 | ||
4127 | /* Search for the abbreviation */ | 3907 | /* Search for the abbreviation */ |
4128 | for (cpp = abbrevs; *cpp; cpp++) { | 3908 | for (cpp = abbrevs; *cpp; cpp++) { |
@@ -4143,7 +3923,7 @@ static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch, | |||
4143 | /* | 3923 | /* |
4144 | * This function expands '%IX' expressions | 3924 | * This function expands '%IX' expressions |
4145 | */ | 3925 | */ |
4146 | static _INLINE_ void expand_inode_expression(char ch, | 3926 | static void expand_inode_expression(char ch, |
4147 | struct problem_context *ctx) | 3927 | struct problem_context *ctx) |
4148 | { | 3928 | { |
4149 | struct ext2_inode *inode; | 3929 | struct ext2_inode *inode; |
@@ -4344,7 +4124,8 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, | |||
4344 | } | 4124 | } |
4345 | } | 4125 | } |
4346 | 4126 | ||
4347 | void print_e2fsck_message(e2fsck_t ctx, const char *msg, | 4127 | |
4128 | static void print_e2fsck_message(e2fsck_t ctx, const char *msg, | ||
4348 | struct problem_context *pctx, int first) | 4129 | struct problem_context *pctx, int first) |
4349 | { | 4130 | { |
4350 | ext2_filsys fs = ctx->fs; | 4131 | ext2_filsys fs = ctx->fs; |
@@ -4375,16 +4156,112 @@ void print_e2fsck_message(e2fsck_t ctx, const char *msg, | |||
4375 | first = 0; | 4156 | first = 0; |
4376 | } | 4157 | } |
4377 | } | 4158 | } |
4159 | |||
4160 | |||
4161 | /* | ||
4162 | * region.c --- code which manages allocations within a region. | ||
4163 | */ | ||
4164 | |||
4165 | struct region_el { | ||
4166 | region_addr_t start; | ||
4167 | region_addr_t end; | ||
4168 | struct region_el *next; | ||
4169 | }; | ||
4170 | |||
4171 | struct region_struct { | ||
4172 | region_addr_t min; | ||
4173 | region_addr_t max; | ||
4174 | struct region_el *allocated; | ||
4175 | }; | ||
4176 | |||
4177 | static region_t region_create(region_addr_t min, region_addr_t max) | ||
4178 | { | ||
4179 | region_t region; | ||
4180 | |||
4181 | region = malloc(sizeof(struct region_struct)); | ||
4182 | if (!region) | ||
4183 | return NULL; | ||
4184 | memset(region, 0, sizeof(struct region_struct)); | ||
4185 | region->min = min; | ||
4186 | region->max = max; | ||
4187 | return region; | ||
4188 | } | ||
4189 | |||
4190 | static void region_free(region_t region) | ||
4191 | { | ||
4192 | struct region_el *r, *next; | ||
4193 | |||
4194 | for (r = region->allocated; r; r = next) { | ||
4195 | next = r->next; | ||
4196 | free(r); | ||
4197 | } | ||
4198 | memset(region, 0, sizeof(struct region_struct)); | ||
4199 | free(region); | ||
4200 | } | ||
4201 | |||
4202 | static int region_allocate(region_t region, region_addr_t start, int n) | ||
4203 | { | ||
4204 | struct region_el *r, *new_region, *prev, *next; | ||
4205 | region_addr_t end; | ||
4206 | |||
4207 | end = start+n; | ||
4208 | if ((start < region->min) || (end > region->max)) | ||
4209 | return -1; | ||
4210 | if (n == 0) | ||
4211 | return 1; | ||
4212 | |||
4213 | /* | ||
4214 | * Search through the linked list. If we find that it | ||
4215 | * conflicts witih something that's already allocated, return | ||
4216 | * 1; if we can find an existing region which we can grow, do | ||
4217 | * so. Otherwise, stop when we find the appropriate place | ||
4218 | * insert a new region element into the linked list. | ||
4219 | */ | ||
4220 | for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) { | ||
4221 | if (((start >= r->start) && (start < r->end)) || | ||
4222 | ((end > r->start) && (end <= r->end)) || | ||
4223 | ((start <= r->start) && (end >= r->end))) | ||
4224 | return 1; | ||
4225 | if (end == r->start) { | ||
4226 | r->start = start; | ||
4227 | return 0; | ||
4228 | } | ||
4229 | if (start == r->end) { | ||
4230 | if ((next = r->next)) { | ||
4231 | if (end > next->start) | ||
4232 | return 1; | ||
4233 | if (end == next->start) { | ||
4234 | r->end = next->end; | ||
4235 | r->next = next->next; | ||
4236 | free(next); | ||
4237 | return 0; | ||
4238 | } | ||
4239 | } | ||
4240 | r->end = end; | ||
4241 | return 0; | ||
4242 | } | ||
4243 | if (start < r->start) | ||
4244 | break; | ||
4245 | } | ||
4246 | /* | ||
4247 | * Insert a new region element structure into the linked list | ||
4248 | */ | ||
4249 | new_region = malloc(sizeof(struct region_el)); | ||
4250 | if (!new_region) | ||
4251 | return -1; | ||
4252 | new_region->start = start; | ||
4253 | new_region->end = start + n; | ||
4254 | new_region->next = r; | ||
4255 | if (prev) | ||
4256 | prev->next = new_region; | ||
4257 | else | ||
4258 | region->allocated = new_region; | ||
4259 | return 0; | ||
4260 | } | ||
4261 | |||
4378 | /* | 4262 | /* |
4379 | * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table | 4263 | * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table |
4380 | * | 4264 | * |
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, | 4265 | * Pass 1 of e2fsck iterates over all the inodes in the filesystems, |
4389 | * and applies the following tests to each inode: | 4266 | * and applies the following tests to each inode: |
4390 | * | 4267 | * |
@@ -4478,7 +4355,7 @@ static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE - | |||
4478 | * Free all memory allocated by pass1 in preparation for restarting | 4355 | * Free all memory allocated by pass1 in preparation for restarting |
4479 | * things. | 4356 | * things. |
4480 | */ | 4357 | */ |
4481 | static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused))) | 4358 | static void unwind_pass1(void) |
4482 | { | 4359 | { |
4483 | ext2fs_free_mem(&inodes_to_process); | 4360 | ext2fs_free_mem(&inodes_to_process); |
4484 | inodes_to_process = 0; | 4361 | inodes_to_process = 0; |
@@ -4492,7 +4369,8 @@ static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused))) | |||
4492 | * since they have the same requirement; the i_block fields should be | 4369 | * since they have the same requirement; the i_block fields should be |
4493 | * zero. | 4370 | * zero. |
4494 | */ | 4371 | */ |
4495 | int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) | 4372 | static int |
4373 | e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) | ||
4496 | { | 4374 | { |
4497 | int i; | 4375 | int i; |
4498 | 4376 | ||
@@ -4527,8 +4405,8 @@ int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) | |||
4527 | * Check to make sure a symlink inode is real. Returns 1 if the symlink | 4405 | * Check to make sure a symlink inode is real. Returns 1 if the symlink |
4528 | * checks out, 0 if not. | 4406 | * checks out, 0 if not. |
4529 | */ | 4407 | */ |
4530 | int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, | 4408 | static int |
4531 | char *buf) | 4409 | e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf) |
4532 | { | 4410 | { |
4533 | unsigned int len; | 4411 | unsigned int len; |
4534 | int i; | 4412 | int i; |
@@ -4737,7 +4615,7 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx) | |||
4737 | } | 4615 | } |
4738 | } | 4616 | } |
4739 | 4617 | ||
4740 | void e2fsck_pass1(e2fsck_t ctx) | 4618 | static void e2fsck_pass1(e2fsck_t ctx) |
4741 | { | 4619 | { |
4742 | int i; | 4620 | int i; |
4743 | __u64 max_sizes; | 4621 | __u64 max_sizes; |
@@ -5250,7 +5128,7 @@ void e2fsck_pass1(e2fsck_t ctx) | |||
5250 | * master superblock. | 5128 | * master superblock. |
5251 | */ | 5129 | */ |
5252 | ctx->use_superblock = 0; | 5130 | ctx->use_superblock = 0; |
5253 | unwind_pass1(fs); | 5131 | unwind_pass1(); |
5254 | goto endit; | 5132 | goto endit; |
5255 | } | 5133 | } |
5256 | 5134 | ||
@@ -6480,6 +6358,7 @@ void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool) | |||
6480 | fs->write_inode = 0; | 6358 | fs->write_inode = 0; |
6481 | } | 6359 | } |
6482 | } | 6360 | } |
6361 | |||
6483 | /* | 6362 | /* |
6484 | * pass1b.c --- Pass #1b of e2fsck | 6363 | * pass1b.c --- Pass #1b of e2fsck |
6485 | * | 6364 | * |
@@ -6500,13 +6379,6 @@ void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool) | |||
6500 | * (so that the file gets a fresh copy of the duplicated blocks) or | 6379 | * (so that the file gets a fresh copy of the duplicated blocks) or |
6501 | * simply to delete the file. | 6380 | * simply to delete the file. |
6502 | * | 6381 | * |
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 | */ | 6382 | */ |
6511 | 6383 | ||
6512 | 6384 | ||
@@ -6627,8 +6499,7 @@ static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk, | |||
6627 | /* | 6499 | /* |
6628 | * Free a duplicate inode record | 6500 | * Free a duplicate inode record |
6629 | */ | 6501 | */ |
6630 | static void inode_dnode_free(dnode_t *node, | 6502 | static void inode_dnode_free(dnode_t *node) |
6631 | void *context EXT2FS_ATTR((unused))) | ||
6632 | { | 6503 | { |
6633 | struct dup_inode *di; | 6504 | struct dup_inode *di; |
6634 | struct block_el *p, *next; | 6505 | struct block_el *p, *next; |
@@ -6644,8 +6515,7 @@ static void inode_dnode_free(dnode_t *node, | |||
6644 | /* | 6515 | /* |
6645 | * Free a duplicate block record | 6516 | * Free a duplicate block record |
6646 | */ | 6517 | */ |
6647 | static void block_dnode_free(dnode_t *node, | 6518 | static void block_dnode_free(dnode_t *node) |
6648 | void *context EXT2FS_ATTR((unused))) | ||
6649 | { | 6519 | { |
6650 | struct dup_block *db; | 6520 | struct dup_block *db; |
6651 | struct inode_el *p, *next; | 6521 | struct inode_el *p, *next; |
@@ -6679,8 +6549,8 @@ void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf) | |||
6679 | 6549 | ||
6680 | dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp); | 6550 | dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp); |
6681 | dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp); | 6551 | dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp); |
6682 | dict_set_allocator(&ino_dict, NULL, inode_dnode_free, NULL); | 6552 | dict_set_allocator(&ino_dict, inode_dnode_free); |
6683 | dict_set_allocator(&blk_dict, NULL, block_dnode_free, NULL); | 6553 | dict_set_allocator(&blk_dict, block_dnode_free); |
6684 | 6554 | ||
6685 | pass1b(ctx, block_buf); | 6555 | pass1b(ctx, block_buf); |
6686 | pass1c(ctx, block_buf); | 6556 | pass1c(ctx, block_buf); |
@@ -7275,13 +7145,6 @@ static int check_if_fs_block(e2fsck_t ctx, blk_t test_block) | |||
7275 | /* | 7145 | /* |
7276 | * pass2.c --- check directory structure | 7146 | * pass2.c --- check directory structure |
7277 | * | 7147 | * |
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 | 7148 | * Pass 2 of e2fsck iterates through all active directory inodes, and |
7286 | * applies to following tests to each directory entry in the directory | 7149 | * applies to following tests to each directory entry in the directory |
7287 | * blocks in the inodes: | 7150 | * blocks in the inodes: |
@@ -7324,9 +7187,8 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf); | |||
7324 | static int check_dir_block(ext2_filsys fs, | 7187 | static int check_dir_block(ext2_filsys fs, |
7325 | struct ext2_db_entry *dir_blocks_info, | 7188 | struct ext2_db_entry *dir_blocks_info, |
7326 | void *priv_data); | 7189 | void *priv_data); |
7327 | static int allocate_dir_block(e2fsck_t ctx, | 7190 | static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info, |
7328 | struct ext2_db_entry *dir_blocks_info, | 7191 | struct problem_context *pctx); |
7329 | char *buf, struct problem_context *pctx); | ||
7330 | static int update_dir_block(ext2_filsys fs, | 7192 | static int update_dir_block(ext2_filsys fs, |
7331 | blk_t *block_nr, | 7193 | blk_t *block_nr, |
7332 | e2_blkcnt_t blockcnt, | 7194 | e2_blkcnt_t blockcnt, |
@@ -7345,7 +7207,7 @@ struct check_dir_struct { | |||
7345 | e2fsck_t ctx; | 7207 | e2fsck_t ctx; |
7346 | }; | 7208 | }; |
7347 | 7209 | ||
7348 | void e2fsck_pass2(e2fsck_t ctx) | 7210 | static void e2fsck_pass2(e2fsck_t ctx) |
7349 | { | 7211 | { |
7350 | struct ext2_super_block *sb = ctx->fs->super; | 7212 | struct ext2_super_block *sb = ctx->fs->super; |
7351 | struct problem_context pctx; | 7213 | struct problem_context pctx; |
@@ -7714,7 +7576,6 @@ static int check_dotdot(e2fsck_t ctx, | |||
7714 | */ | 7576 | */ |
7715 | static int check_name(e2fsck_t ctx, | 7577 | static int check_name(e2fsck_t ctx, |
7716 | struct ext2_dir_entry *dirent, | 7578 | struct ext2_dir_entry *dirent, |
7717 | ext2_ino_t dir_ino EXT2FS_ATTR((unused)), | ||
7718 | struct problem_context *pctx) | 7579 | struct problem_context *pctx) |
7719 | { | 7580 | { |
7720 | int i; | 7581 | int i; |
@@ -7738,9 +7599,38 @@ static int check_name(e2fsck_t ctx, | |||
7738 | /* | 7599 | /* |
7739 | * Check the directory filetype (if present) | 7600 | * Check the directory filetype (if present) |
7740 | */ | 7601 | */ |
7602 | |||
7603 | /* | ||
7604 | * Given a mode, return the ext2 file type | ||
7605 | */ | ||
7606 | static int ext2_file_type(unsigned int mode) | ||
7607 | { | ||
7608 | if (LINUX_S_ISREG(mode)) | ||
7609 | return EXT2_FT_REG_FILE; | ||
7610 | |||
7611 | if (LINUX_S_ISDIR(mode)) | ||
7612 | return EXT2_FT_DIR; | ||
7613 | |||
7614 | if (LINUX_S_ISCHR(mode)) | ||
7615 | return EXT2_FT_CHRDEV; | ||
7616 | |||
7617 | if (LINUX_S_ISBLK(mode)) | ||
7618 | return EXT2_FT_BLKDEV; | ||
7619 | |||
7620 | if (LINUX_S_ISLNK(mode)) | ||
7621 | return EXT2_FT_SYMLINK; | ||
7622 | |||
7623 | if (LINUX_S_ISFIFO(mode)) | ||
7624 | return EXT2_FT_FIFO; | ||
7625 | |||
7626 | if (LINUX_S_ISSOCK(mode)) | ||
7627 | return EXT2_FT_SOCK; | ||
7628 | |||
7629 | return 0; | ||
7630 | } | ||
7631 | |||
7741 | static _INLINE_ int check_filetype(e2fsck_t ctx, | 7632 | static _INLINE_ int check_filetype(e2fsck_t ctx, |
7742 | struct ext2_dir_entry *dirent, | 7633 | struct ext2_dir_entry *dirent, |
7743 | ext2_ino_t dir_ino EXT2FS_ATTR((unused)), | ||
7744 | struct problem_context *pctx) | 7634 | struct problem_context *pctx) |
7745 | { | 7635 | { |
7746 | int filetype = dirent->name_len >> 8; | 7636 | int filetype = dirent->name_len >> 8; |
@@ -8006,7 +7896,7 @@ static int check_dir_block(ext2_filsys fs, | |||
8006 | cd->pctx.num = 0; | 7896 | cd->pctx.num = 0; |
8007 | 7897 | ||
8008 | if (db->blk == 0) { | 7898 | if (db->blk == 0) { |
8009 | if (allocate_dir_block(ctx, db, buf, &cd->pctx)) | 7899 | if (allocate_dir_block(ctx, db, &cd->pctx)) |
8010 | return 0; | 7900 | return 0; |
8011 | block_nr = db->blk; | 7901 | block_nr = db->blk; |
8012 | } | 7902 | } |
@@ -8210,10 +8100,10 @@ static int check_dir_block(ext2_filsys fs, | |||
8210 | return DIRENT_ABORT; | 8100 | return DIRENT_ABORT; |
8211 | } | 8101 | } |
8212 | 8102 | ||
8213 | if (check_name(ctx, dirent, ino, &cd->pctx)) | 8103 | if (check_name(ctx, dirent, &cd->pctx)) |
8214 | dir_modified++; | 8104 | dir_modified++; |
8215 | 8105 | ||
8216 | if (check_filetype(ctx, dirent, ino, &cd->pctx)) | 8106 | if (check_filetype(ctx, dirent, &cd->pctx)) |
8217 | dir_modified++; | 8107 | dir_modified++; |
8218 | 8108 | ||
8219 | #ifdef ENABLE_HTREE | 8109 | #ifdef ENABLE_HTREE |
@@ -8326,8 +8216,7 @@ abort_free_dict: | |||
8326 | * This function is called to deallocate a block, and is an interator | 8216 | * This function is called to deallocate a block, and is an interator |
8327 | * functioned called by deallocate inode via ext2fs_iterate_block(). | 8217 | * functioned called by deallocate inode via ext2fs_iterate_block(). |
8328 | */ | 8218 | */ |
8329 | static int deallocate_inode_block(ext2_filsys fs, | 8219 | static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr, |
8330 | blk_t *block_nr, | ||
8331 | e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), | 8220 | e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), |
8332 | blk_t ref_block EXT2FS_ATTR((unused)), | 8221 | blk_t ref_block EXT2FS_ATTR((unused)), |
8333 | int ref_offset EXT2FS_ATTR((unused)), | 8222 | int ref_offset EXT2FS_ATTR((unused)), |
@@ -8575,9 +8464,7 @@ static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, | |||
8575 | * a "hole" in it, or if a directory has a illegal block number | 8464 | * a "hole" in it, or if a directory has a illegal block number |
8576 | * that was zeroed out and now needs to be replaced. | 8465 | * that was zeroed out and now needs to be replaced. |
8577 | */ | 8466 | */ |
8578 | static int allocate_dir_block(e2fsck_t ctx, | 8467 | static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db, |
8579 | struct ext2_db_entry *db, | ||
8580 | char *buf EXT2FS_ATTR((unused)), | ||
8581 | struct problem_context *pctx) | 8468 | struct problem_context *pctx) |
8582 | { | 8469 | { |
8583 | ext2_filsys fs = ctx->fs; | 8470 | ext2_filsys fs = ctx->fs; |
@@ -8673,16 +8560,10 @@ static int update_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)), | |||
8673 | } | 8560 | } |
8674 | return 0; | 8561 | return 0; |
8675 | } | 8562 | } |
8563 | |||
8676 | /* | 8564 | /* |
8677 | * pass3.c -- pass #3 of e2fsck: Check for directory connectivity | 8565 | * pass3.c -- pass #3 of e2fsck: Check for directory connectivity |
8678 | * | 8566 | * |
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 | 8567 | * Pass #3 assures that all directories are connected to the |
8687 | * filesystem tree, using the following algorithm: | 8568 | * filesystem tree, using the following algorithm: |
8688 | * | 8569 | * |
@@ -8714,10 +8595,10 @@ static int check_directory(e2fsck_t ctx, struct dir_info *dir, | |||
8714 | struct problem_context *pctx); | 8595 | struct problem_context *pctx); |
8715 | static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent); | 8596 | static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent); |
8716 | 8597 | ||
8717 | static ext2fs_inode_bitmap inode_loop_detect = 0; | 8598 | static ext2fs_inode_bitmap inode_loop_detect; |
8718 | static ext2fs_inode_bitmap inode_done_map = 0; | 8599 | static ext2fs_inode_bitmap inode_done_map; |
8719 | 8600 | ||
8720 | void e2fsck_pass3(e2fsck_t ctx) | 8601 | static void e2fsck_pass3(e2fsck_t ctx) |
8721 | { | 8602 | { |
8722 | ext2_filsys fs = ctx->fs; | 8603 | ext2_filsys fs = ctx->fs; |
8723 | int i; | 8604 | int i; |
@@ -9473,13 +9354,6 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, | |||
9473 | /* | 9354 | /* |
9474 | * pass4.c -- pass #4 of e2fsck: Check reference counts | 9355 | * pass4.c -- pass #4 of e2fsck: Check reference counts |
9475 | * | 9356 | * |
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: | 9357 | * Pass 4 frees the following data structures: |
9484 | * - A bitmap of which inodes are in bad blocks. (inode_bb_map) | 9358 | * - A bitmap of which inodes are in bad blocks. (inode_bb_map) |
9485 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) | 9359 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) |
@@ -9548,7 +9422,7 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i) | |||
9548 | } | 9422 | } |
9549 | 9423 | ||
9550 | 9424 | ||
9551 | void e2fsck_pass4(e2fsck_t ctx) | 9425 | static void e2fsck_pass4(e2fsck_t ctx) |
9552 | { | 9426 | { |
9553 | ext2_filsys fs = ctx->fs; | 9427 | ext2_filsys fs = ctx->fs; |
9554 | ext2_ino_t i; | 9428 | ext2_ino_t i; |
@@ -9647,75 +9521,8 @@ void e2fsck_pass4(e2fsck_t ctx) | |||
9647 | 9521 | ||
9648 | /* | 9522 | /* |
9649 | * pass5.c --- check block and inode bitmaps against on-disk bitmaps | 9523 | * 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 | */ | 9524 | */ |
9659 | 9525 | ||
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) | 9526 | #define NO_BLK ((blk_t) -1) |
9720 | 9527 | ||
9721 | static void print_bitmap_problem(e2fsck_t ctx, int problem, | 9528 | static void print_bitmap_problem(e2fsck_t ctx, int problem, |
@@ -10187,17 +9994,62 @@ static void check_block_end(e2fsck_t ctx) | |||
10187 | } | 9994 | } |
10188 | } | 9995 | } |
10189 | 9996 | ||
9997 | static void e2fsck_pass5(e2fsck_t ctx) | ||
9998 | { | ||
9999 | #ifdef RESOURCE_TRACK | ||
10000 | struct resource_track rtrack; | ||
10001 | #endif | ||
10002 | struct problem_context pctx; | ||
10003 | |||
10004 | #ifdef MTRACE | ||
10005 | mtrace_print("Pass 5"); | ||
10006 | #endif | ||
10007 | |||
10008 | #ifdef RESOURCE_TRACK | ||
10009 | init_resource_track(&rtrack); | ||
10010 | #endif | ||
10011 | |||
10012 | clear_problem_context(&pctx); | ||
10013 | |||
10014 | if (!(ctx->options & E2F_OPT_PREEN)) | ||
10015 | fix_problem(ctx, PR_5_PASS_HEADER, &pctx); | ||
10016 | |||
10017 | if (ctx->progress) | ||
10018 | if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2)) | ||
10019 | return; | ||
10020 | |||
10021 | e2fsck_read_bitmaps(ctx); | ||
10022 | |||
10023 | check_block_bitmaps(ctx); | ||
10024 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
10025 | return; | ||
10026 | check_inode_bitmaps(ctx); | ||
10027 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
10028 | return; | ||
10029 | check_inode_end(ctx); | ||
10030 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
10031 | return; | ||
10032 | check_block_end(ctx); | ||
10033 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
10034 | return; | ||
10035 | |||
10036 | ext2fs_free_inode_bitmap(ctx->inode_used_map); | ||
10037 | ctx->inode_used_map = 0; | ||
10038 | ext2fs_free_inode_bitmap(ctx->inode_dir_map); | ||
10039 | ctx->inode_dir_map = 0; | ||
10040 | ext2fs_free_block_bitmap(ctx->block_found_map); | ||
10041 | ctx->block_found_map = 0; | ||
10190 | 10042 | ||
10043 | #ifdef RESOURCE_TRACK | ||
10044 | if (ctx->options & E2F_OPT_TIME2) { | ||
10045 | e2fsck_clear_progbar(ctx); | ||
10046 | print_resource_track(_("Pass 5"), &rtrack); | ||
10047 | } | ||
10048 | #endif | ||
10049 | } | ||
10191 | 10050 | ||
10192 | /* | 10051 | /* |
10193 | * problem.c --- report filesystem problems to the user | 10052 | * 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 | */ | 10053 | */ |
10202 | 10054 | ||
10203 | #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */ | 10055 | #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */ |
@@ -10258,7 +10110,7 @@ struct latch_descr { | |||
10258 | * These are the prompts which are used to ask the user if they want | 10110 | * These are the prompts which are used to ask the user if they want |
10259 | * to fix a problem. | 10111 | * to fix a problem. |
10260 | */ | 10112 | */ |
10261 | static const char *prompt[] = { | 10113 | static const char * const prompt[] = { |
10262 | N_("(no prompt)"), /* 0 */ | 10114 | N_("(no prompt)"), /* 0 */ |
10263 | N_("Fix"), /* 1 */ | 10115 | N_("Fix"), /* 1 */ |
10264 | N_("Clear"), /* 2 */ | 10116 | N_("Clear"), /* 2 */ |
@@ -10286,7 +10138,7 @@ static const char *prompt[] = { | |||
10286 | * These messages are printed when we are preen mode and we will be | 10138 | * These messages are printed when we are preen mode and we will be |
10287 | * automatically fixing the problem. | 10139 | * automatically fixing the problem. |
10288 | */ | 10140 | */ |
10289 | static const char *preen_msg[] = { | 10141 | static const char * const preen_msg[] = { |
10290 | N_("(NONE)"), /* 0 */ | 10142 | N_("(NONE)"), /* 0 */ |
10291 | N_("FIXED"), /* 1 */ | 10143 | N_("FIXED"), /* 1 */ |
10292 | N_("CLEARED"), /* 2 */ | 10144 | N_("CLEARED"), /* 2 */ |
@@ -11854,19 +11706,11 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) | |||
11854 | 11706 | ||
11855 | return answer; | 11707 | return answer; |
11856 | } | 11708 | } |
11709 | |||
11857 | /* | 11710 | /* |
11858 | * linux/fs/recovery.c | 11711 | * linux/fs/recovery.c |
11859 | * | 11712 | * |
11860 | * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 | 11713 | * 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 | */ | 11714 | */ |
11871 | 11715 | ||
11872 | /* | 11716 | /* |
@@ -11889,87 +11733,6 @@ static int do_one_pass(journal_t *journal, | |||
11889 | static int scan_revoke_records(journal_t *, struct buffer_head *, | 11733 | static int scan_revoke_records(journal_t *, struct buffer_head *, |
11890 | tid_t, struct recovery_info *); | 11734 | tid_t, struct recovery_info *); |
11891 | 11735 | ||
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 | /* | 11736 | /* |
11974 | * Read a block from the journal | 11737 | * Read a block from the journal |
11975 | */ | 11738 | */ |
@@ -11993,7 +11756,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal, | |||
11993 | return err; | 11756 | return err; |
11994 | } | 11757 | } |
11995 | 11758 | ||
11996 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); | 11759 | bh = getblk(journal->j_dev, blocknr, journal->j_blocksize); |
11997 | if (!bh) | 11760 | if (!bh) |
11998 | return -ENOMEM; | 11761 | return -ENOMEM; |
11999 | 11762 | ||
@@ -12260,7 +12023,7 @@ static int do_one_pass(journal_t *journal, | |||
12260 | 12023 | ||
12261 | /* Find a buffer for the new | 12024 | /* Find a buffer for the new |
12262 | * data being restored */ | 12025 | * data being restored */ |
12263 | nbh = __getblk(journal->j_fs_dev, | 12026 | nbh = getblk(journal->j_fs_dev, |
12264 | blocknr, | 12027 | blocknr, |
12265 | journal->j_blocksize); | 12028 | journal->j_blocksize); |
12266 | if (nbh == NULL) { | 12029 | if (nbh == NULL) { |
@@ -12282,7 +12045,7 @@ static int do_one_pass(journal_t *journal, | |||
12282 | } | 12045 | } |
12283 | 12046 | ||
12284 | BUFFER_TRACE(nbh, "marking dirty"); | 12047 | BUFFER_TRACE(nbh, "marking dirty"); |
12285 | set_buffer_uptodate(nbh); | 12048 | mark_buffer_uptodate(nbh, 1); |
12286 | mark_buffer_dirty(nbh); | 12049 | mark_buffer_dirty(nbh); |
12287 | BUFFER_TRACE(nbh, "marking uptodate"); | 12050 | BUFFER_TRACE(nbh, "marking uptodate"); |
12288 | ++info->nr_replays; | 12051 | ++info->nr_replays; |
@@ -12388,124 +12151,11 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, | |||
12388 | } | 12151 | } |
12389 | return 0; | 12152 | return 0; |
12390 | } | 12153 | } |
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 | 12154 | ||
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 | 12155 | ||
12499 | /* | 12156 | /* |
12500 | * rehash.c --- rebuild hash tree directories | 12157 | * rehash.c --- rebuild hash tree directories |
12501 | * | 12158 | * |
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 | 12159 | * This algorithm is designed for simplicity of implementation and to |
12510 | * pack the directory as much as possible. It however requires twice | 12160 | * pack the directory as much as possible. It however requires twice |
12511 | * as much memory as the size of the directory. The maximum size | 12161 | * as much memory as the size of the directory. The maximum size |
@@ -13146,7 +12796,7 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs, | |||
13146 | return 0; | 12796 | return 0; |
13147 | } | 12797 | } |
13148 | 12798 | ||
13149 | errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino) | 12799 | static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino) |
13150 | { | 12800 | { |
13151 | ext2_filsys fs = ctx->fs; | 12801 | ext2_filsys fs = ctx->fs; |
13152 | errcode_t retval; | 12802 | errcode_t retval; |
@@ -13330,17 +12980,10 @@ void e2fsck_rehash_directories(e2fsck_t ctx) | |||
13330 | } | 12980 | } |
13331 | #endif | 12981 | #endif |
13332 | } | 12982 | } |
12983 | |||
13333 | /* | 12984 | /* |
13334 | * linux/fs/revoke.c | 12985 | * linux/fs/revoke.c |
13335 | * | 12986 | * |
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; | 12987 | * Journal revoke routines for the generic filesystem journaling code; |
13345 | * part of the ext2fs journaling system. | 12988 | * part of the ext2fs journaling system. |
13346 | * | 12989 | * |
@@ -13415,13 +13058,6 @@ struct jbd_revoke_table_s | |||
13415 | }; | 13058 | }; |
13416 | 13059 | ||
13417 | 13060 | ||
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 */ | 13061 | /* Utility functions to maintain the revoke table */ |
13426 | 13062 | ||
13427 | /* Borrowed from buffer.c: this is a tried and tested block hash function */ | 13063 | /* Borrowed from buffer.c: this is a tried and tested block hash function */ |
@@ -13441,9 +13077,6 @@ static int insert_revoke_hash(journal_t *journal, unsigned long blocknr, | |||
13441 | struct list_head *hash_list; | 13077 | struct list_head *hash_list; |
13442 | struct jbd_revoke_record_s *record; | 13078 | struct jbd_revoke_record_s *record; |
13443 | 13079 | ||
13444 | #ifdef __KERNEL__ | ||
13445 | repeat: | ||
13446 | #endif | ||
13447 | record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS); | 13080 | record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS); |
13448 | if (!record) | 13081 | if (!record) |
13449 | goto oom; | 13082 | goto oom; |
@@ -13455,16 +13088,7 @@ repeat: | |||
13455 | return 0; | 13088 | return 0; |
13456 | 13089 | ||
13457 | oom: | 13090 | 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; | 13091 | return -ENOMEM; |
13467 | #endif | ||
13468 | } | 13092 | } |
13469 | 13093 | ||
13470 | /* Find a revoke record in the journal's hash table. */ | 13094 | /* Find a revoke record in the journal's hash table. */ |
@@ -13488,17 +13112,13 @@ static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal, | |||
13488 | 13112 | ||
13489 | int journal_init_revoke_caches(void) | 13113 | int journal_init_revoke_caches(void) |
13490 | { | 13114 | { |
13491 | revoke_record_cache = kmem_cache_create("revoke_record", | 13115 | revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s)); |
13492 | sizeof(struct jbd_revoke_record_s), | ||
13493 | 0, SLAB_HWCACHE_ALIGN, NULL, NULL); | ||
13494 | if (revoke_record_cache == 0) | 13116 | if (revoke_record_cache == 0) |
13495 | return -ENOMEM; | 13117 | return -ENOMEM; |
13496 | 13118 | ||
13497 | revoke_table_cache = kmem_cache_create("revoke_table", | 13119 | revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s)); |
13498 | sizeof(struct jbd_revoke_table_s), | ||
13499 | 0, 0, NULL, NULL); | ||
13500 | if (revoke_table_cache == 0) { | 13120 | if (revoke_table_cache == 0) { |
13501 | kmem_cache_destroy(revoke_record_cache); | 13121 | do_cache_destroy(revoke_record_cache); |
13502 | revoke_record_cache = NULL; | 13122 | revoke_record_cache = NULL; |
13503 | return -ENOMEM; | 13123 | return -ENOMEM; |
13504 | } | 13124 | } |
@@ -13507,9 +13127,9 @@ int journal_init_revoke_caches(void) | |||
13507 | 13127 | ||
13508 | void journal_destroy_revoke_caches(void) | 13128 | void journal_destroy_revoke_caches(void) |
13509 | { | 13129 | { |
13510 | kmem_cache_destroy(revoke_record_cache); | 13130 | do_cache_destroy(revoke_record_cache); |
13511 | revoke_record_cache = 0; | 13131 | revoke_record_cache = 0; |
13512 | kmem_cache_destroy(revoke_table_cache); | 13132 | do_cache_destroy(revoke_table_cache); |
13513 | revoke_table_cache = 0; | 13133 | revoke_table_cache = 0; |
13514 | } | 13134 | } |
13515 | 13135 | ||
@@ -13536,10 +13156,9 @@ int journal_init_revoke(journal_t *journal, int hash_size) | |||
13536 | shift++; | 13156 | shift++; |
13537 | journal->j_revoke->hash_shift = shift; | 13157 | journal->j_revoke->hash_shift = shift; |
13538 | 13158 | ||
13539 | journal->j_revoke->hash_table = | 13159 | journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head)); |
13540 | kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); | ||
13541 | if (!journal->j_revoke->hash_table) { | 13160 | if (!journal->j_revoke->hash_table) { |
13542 | kmem_cache_free(revoke_table_cache, journal->j_revoke); | 13161 | free(journal->j_revoke); |
13543 | journal->j_revoke = NULL; | 13162 | journal->j_revoke = NULL; |
13544 | return -ENOMEM; | 13163 | return -ENOMEM; |
13545 | } | 13164 | } |
@@ -13567,311 +13186,11 @@ void journal_destroy_revoke(journal_t *journal) | |||
13567 | J_ASSERT (list_empty(hash_list)); | 13186 | J_ASSERT (list_empty(hash_list)); |
13568 | } | 13187 | } |
13569 | 13188 | ||
13570 | kfree(table->hash_table); | 13189 | free(table->hash_table); |
13571 | kmem_cache_free(revoke_table_cache, table); | 13190 | free(table); |
13572 | journal->j_revoke = NULL; | 13191 | journal->j_revoke = NULL; |
13573 | } | 13192 | } |
13574 | 13193 | ||
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 | /* | 13194 | /* |
13876 | * Revoke support for recovery. | 13195 | * Revoke support for recovery. |
13877 | * | 13196 | * |
@@ -13894,8 +13213,7 @@ static void flush_descriptor(journal_t *journal, | |||
13894 | * single block. | 13213 | * single block. |
13895 | */ | 13214 | */ |
13896 | 13215 | ||
13897 | int journal_set_revoke(journal_t *journal, | 13216 | int journal_set_revoke(journal_t *journal, unsigned long blocknr, |
13898 | unsigned long blocknr, | ||
13899 | tid_t sequence) | 13217 | tid_t sequence) |
13900 | { | 13218 | { |
13901 | struct jbd_revoke_record_s *record; | 13219 | struct jbd_revoke_record_s *record; |
@@ -13918,8 +13236,7 @@ int journal_set_revoke(journal_t *journal, | |||
13918 | * ones, but later transactions still need replayed. | 13236 | * ones, but later transactions still need replayed. |
13919 | */ | 13237 | */ |
13920 | 13238 | ||
13921 | int journal_test_revoke(journal_t *journal, | 13239 | int journal_test_revoke(journal_t *journal, unsigned long blocknr, |
13922 | unsigned long blocknr, | ||
13923 | tid_t sequence) | 13240 | tid_t sequence) |
13924 | { | 13241 | { |
13925 | struct jbd_revoke_record_s *record; | 13242 | struct jbd_revoke_record_s *record; |
@@ -13951,20 +13268,13 @@ void journal_clear_revoke(journal_t *journal) | |||
13951 | while (!list_empty(hash_list)) { | 13268 | while (!list_empty(hash_list)) { |
13952 | record = (struct jbd_revoke_record_s*) hash_list->next; | 13269 | record = (struct jbd_revoke_record_s*) hash_list->next; |
13953 | list_del(&record->hash); | 13270 | list_del(&record->hash); |
13954 | kmem_cache_free(revoke_record_cache, record); | 13271 | free(record); |
13955 | } | 13272 | } |
13956 | } | 13273 | } |
13957 | } | 13274 | } |
13958 | 13275 | ||
13959 | /* | 13276 | /* |
13960 | * e2fsck.c - superblock checks | 13277 | * 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 | */ | 13278 | */ |
13969 | 13279 | ||
13970 | #define MIN_CHECK 1 | 13280 | #define MIN_CHECK 1 |
@@ -13991,7 +13301,7 @@ static void check_super_value(e2fsck_t ctx, const char *descr, | |||
13991 | * e2fsck code.. | 13301 | * e2fsck code.. |
13992 | */ | 13302 | */ |
13993 | #ifndef EXT2_SPECIAL_DEVICE_SIZE | 13303 | #ifndef EXT2_SPECIAL_DEVICE_SIZE |
13994 | errcode_t e2fsck_get_device_size(e2fsck_t ctx) | 13304 | static errcode_t e2fsck_get_device_size(e2fsck_t ctx) |
13995 | { | 13305 | { |
13996 | return (ext2fs_get_device_size(ctx->filesystem_name, | 13306 | return (ext2fs_get_device_size(ctx->filesystem_name, |
13997 | EXT2_BLOCK_SIZE(ctx->fs->super), | 13307 | EXT2_BLOCK_SIZE(ctx->fs->super), |
@@ -14014,8 +13324,7 @@ struct process_block_struct { | |||
14014 | errcode_t errcode; | 13324 | errcode_t errcode; |
14015 | }; | 13325 | }; |
14016 | 13326 | ||
14017 | static int release_inode_block(ext2_filsys fs, | 13327 | static int release_inode_block(ext2_filsys fs, blk_t *block_nr, |
14018 | blk_t *block_nr, | ||
14019 | e2_blkcnt_t blockcnt, | 13328 | e2_blkcnt_t blockcnt, |
14020 | blk_t ref_blk EXT2FS_ATTR((unused)), | 13329 | blk_t ref_blk EXT2FS_ATTR((unused)), |
14021 | int ref_offset EXT2FS_ATTR((unused)), | 13330 | int ref_offset EXT2FS_ATTR((unused)), |
@@ -14384,7 +13693,7 @@ cleanup: | |||
14384 | 13693 | ||
14385 | } | 13694 | } |
14386 | 13695 | ||
14387 | void check_super_block(e2fsck_t ctx) | 13696 | static void check_super_block(e2fsck_t ctx) |
14388 | { | 13697 | { |
14389 | ext2_filsys fs = ctx->fs; | 13698 | ext2_filsys fs = ctx->fs; |
14390 | blk_t first_block, last_block; | 13699 | blk_t first_block, last_block; |
@@ -14659,16 +13968,9 @@ void check_super_block(e2fsck_t ctx) | |||
14659 | e2fsck_move_ext3_journal(ctx); | 13968 | e2fsck_move_ext3_journal(ctx); |
14660 | return; | 13969 | return; |
14661 | } | 13970 | } |
13971 | |||
14662 | /* | 13972 | /* |
14663 | * swapfs.c --- byte-swap an ext2 filesystem | 13973 | * 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 | */ | 13974 | */ |
14673 | 13975 | ||
14674 | #ifdef ENABLE_SWAPFS | 13976 | #ifdef ENABLE_SWAPFS |
@@ -14866,7 +14168,7 @@ static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap) | |||
14866 | 14168 | ||
14867 | 14169 | ||
14868 | #ifdef ENABLE_SWAPFS | 14170 | #ifdef ENABLE_SWAPFS |
14869 | void swap_filesys(e2fsck_t ctx) | 14171 | static void swap_filesys(e2fsck_t ctx) |
14870 | { | 14172 | { |
14871 | ext2_filsys fs = ctx->fs; | 14173 | ext2_filsys fs = ctx->fs; |
14872 | #ifdef RESOURCE_TRACK | 14174 | #ifdef RESOURCE_TRACK |
@@ -14924,15 +14226,9 @@ void swap_filesys(e2fsck_t ctx) | |||
14924 | #endif /* ENABLE_SWAPFS */ | 14226 | #endif /* ENABLE_SWAPFS */ |
14925 | 14227 | ||
14926 | #endif | 14228 | #endif |
14229 | |||
14927 | /* | 14230 | /* |
14928 | * util.c --- miscellaneous utilities | 14231 | * 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 | */ | 14232 | */ |
14937 | 14233 | ||
14938 | #ifdef HAVE_CONIO_H | 14234 | #ifdef HAVE_CONIO_H |
@@ -14981,8 +14277,7 @@ void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, | |||
14981 | return ret; | 14277 | return ret; |
14982 | } | 14278 | } |
14983 | 14279 | ||
14984 | char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)), | 14280 | static char *string_copy(const char *str, int len) |
14985 | const char *str, int len) | ||
14986 | { | 14281 | { |
14987 | char *ret; | 14282 | char *ret; |
14988 | 14283 | ||
@@ -15020,12 +14315,12 @@ static int read_a_char(void) | |||
15020 | } | 14315 | } |
15021 | #endif | 14316 | #endif |
15022 | 14317 | ||
15023 | int ask_yn(const char * string, int def) | 14318 | static int ask_yn(const char * string, int def) |
15024 | { | 14319 | { |
15025 | int c; | 14320 | int c; |
15026 | const char *defstr; | 14321 | const char *defstr; |
15027 | const char *short_yes = _("yY"); | 14322 | static const char short_yes[] = "yY"; |
15028 | const char *short_no = _("nN"); | 14323 | static const char short_no[] = "nN"; |
15029 | 14324 | ||
15030 | #ifdef HAVE_TERMIOS_H | 14325 | #ifdef HAVE_TERMIOS_H |
15031 | struct termios termios, tmp; | 14326 | struct termios termios, tmp; |
@@ -15039,11 +14334,11 @@ int ask_yn(const char * string, int def) | |||
15039 | #endif | 14334 | #endif |
15040 | 14335 | ||
15041 | if (def == 1) | 14336 | if (def == 1) |
15042 | defstr = _(_("<y>")); | 14337 | defstr = "<y>"; |
15043 | else if (def == 0) | 14338 | else if (def == 0) |
15044 | defstr = _(_("<n>")); | 14339 | defstr = "<n>"; |
15045 | else | 14340 | else |
15046 | defstr = _(" (y/n)"); | 14341 | defstr = " (y/n)"; |
15047 | printf("%s%s? ", string, defstr); | 14342 | printf("%s%s? ", string, defstr); |
15048 | while (1) { | 14343 | while (1) { |
15049 | fflush (stdout); | 14344 | fflush (stdout); |
@@ -15073,9 +14368,9 @@ int ask_yn(const char * string, int def) | |||
15073 | break; | 14368 | break; |
15074 | } | 14369 | } |
15075 | if (def) | 14370 | if (def) |
15076 | puts(_("yes\n")); | 14371 | puts("yes\n"); |
15077 | else | 14372 | else |
15078 | puts (_("no\n")); | 14373 | puts ("no\n"); |
15079 | #ifdef HAVE_TERMIOS_H | 14374 | #ifdef HAVE_TERMIOS_H |
15080 | tcsetattr (0, TCSANOW, &termios); | 14375 | tcsetattr (0, TCSANOW, &termios); |
15081 | #endif | 14376 | #endif |
@@ -15122,7 +14417,7 @@ void e2fsck_read_bitmaps(e2fsck_t ctx) | |||
15122 | } | 14417 | } |
15123 | } | 14418 | } |
15124 | 14419 | ||
15125 | void e2fsck_write_bitmaps(e2fsck_t ctx) | 14420 | static void e2fsck_write_bitmaps(e2fsck_t ctx) |
15126 | { | 14421 | { |
15127 | ext2_filsys fs = ctx->fs; | 14422 | ext2_filsys fs = ctx->fs; |
15128 | errcode_t retval; | 14423 | errcode_t retval; |
@@ -15361,47 +14656,50 @@ cleanup: | |||
15361 | return (ret_sb); | 14656 | return (ret_sb); |
15362 | } | 14657 | } |
15363 | 14658 | ||
14659 | |||
15364 | /* | 14660 | /* |
15365 | * Given a mode, return the ext2 file type | 14661 | * This function runs through the e2fsck passes and calls them all, |
14662 | * returning restart, abort, or cancel as necessary... | ||
15366 | */ | 14663 | */ |
15367 | int ext2_file_type(unsigned int mode) | 14664 | typedef void (*pass_t)(e2fsck_t ctx); |
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 | 14665 | ||
15375 | if (LINUX_S_ISCHR(mode)) | 14666 | static const pass_t e2fsck_passes[] = { |
15376 | return EXT2_FT_CHRDEV; | 14667 | e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4, |
14668 | e2fsck_pass5, 0 }; | ||
15377 | 14669 | ||
15378 | if (LINUX_S_ISBLK(mode)) | 14670 | #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART) |
15379 | return EXT2_FT_BLKDEV; | ||
15380 | 14671 | ||
15381 | if (LINUX_S_ISLNK(mode)) | 14672 | static int e2fsck_run(e2fsck_t ctx) |
15382 | return EXT2_FT_SYMLINK; | 14673 | { |
14674 | int i; | ||
14675 | pass_t e2fsck_pass; | ||
15383 | 14676 | ||
15384 | if (LINUX_S_ISFIFO(mode)) | 14677 | if (setjmp(ctx->abort_loc)) { |
15385 | return EXT2_FT_FIFO; | 14678 | ctx->flags &= ~E2F_FLAG_SETJMP_OK; |
14679 | return (ctx->flags & E2F_FLAG_RUN_RETURN); | ||
14680 | } | ||
14681 | ctx->flags |= E2F_FLAG_SETJMP_OK; | ||
15386 | 14682 | ||
15387 | if (LINUX_S_ISSOCK(mode)) | 14683 | for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { |
15388 | return EXT2_FT_SOCK; | 14684 | if (ctx->flags & E2F_FLAG_RUN_RETURN) |
14685 | break; | ||
14686 | e2fsck_pass(ctx); | ||
14687 | if (ctx->progress) | ||
14688 | (void) (ctx->progress)(ctx, 0, 0, 0); | ||
14689 | } | ||
14690 | ctx->flags &= ~E2F_FLAG_SETJMP_OK; | ||
15389 | 14691 | ||
14692 | if (ctx->flags & E2F_FLAG_RUN_RETURN) | ||
14693 | return (ctx->flags & E2F_FLAG_RUN_RETURN); | ||
15390 | return 0; | 14694 | return 0; |
15391 | } | 14695 | } |
14696 | |||
14697 | |||
15392 | /* | 14698 | /* |
15393 | * unix.c - The unix-specific code for e2fsck | 14699 | * 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 | */ | 14700 | */ |
15402 | 14701 | ||
15403 | 14702 | ||
15404 | |||
15405 | /* Command line options */ | 14703 | /* Command line options */ |
15406 | static int swapfs; | 14704 | static int swapfs; |
15407 | #ifdef ENABLE_SWAPFS | 14705 | #ifdef ENABLE_SWAPFS |
@@ -15448,6 +14746,8 @@ static void usage(e2fsck_t ctx) | |||
15448 | } | 14746 | } |
15449 | #endif | 14747 | #endif |
15450 | 14748 | ||
14749 | #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural) | ||
14750 | |||
15451 | static void show_stats(e2fsck_t ctx) | 14751 | static void show_stats(e2fsck_t ctx) |
15452 | { | 14752 | { |
15453 | ext2_filsys fs = ctx->fs; | 14753 | ext2_filsys fs = ctx->fs; |
@@ -15476,45 +14776,27 @@ static void show_stats(e2fsck_t ctx) | |||
15476 | blocks_used, blocks); | 14776 | blocks_used, blocks); |
15477 | return; | 14777 | return; |
15478 | } | 14778 | } |
15479 | printf (P_("\n%8d inode used (%d%%)\n", "\n%8d inodes used (%d%%)\n", | 14779 | printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used), |
15480 | inodes_used), inodes_used, 100 * inodes_used / inodes); | 14780 | 100 * inodes_used / inodes); |
15481 | printf (P_("%8d non-contiguous inode (%0d.%d%%)\n", | 14781 | printf ("%8d non-contiguous inode%s (%0d.%d%%)\n", |
15482 | "%8d non-contiguous inodes (%0d.%d%%)\n", | 14782 | P_E2("", "s", ctx->fs_fragmented), |
15483 | ctx->fs_fragmented), | 14783 | frag_percent / 10, frag_percent % 10); |
15484 | ctx->fs_fragmented, frag_percent / 10, frag_percent % 10); | ||
15485 | printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"), | 14784 | 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); | 14785 | 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", | 14786 | printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used), |
15488 | blocks_used), | 14787 | (int) ((long long) 100 * blocks_used / blocks)); |
15489 | blocks_used, (int) ((long long) 100 * blocks_used / blocks)); | 14788 | printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count)); |
15490 | printf (P_("%8d bad block\n", "%8d bad blocks\n", | 14789 | printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files)); |
15491 | ctx->fs_badblocks_count), ctx->fs_badblocks_count); | 14790 | printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count)); |
15492 | printf (P_("%8d large file\n", "%8d large files\n", | 14791 | printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count)); |
15493 | ctx->large_files), ctx->large_files); | 14792 | printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count)); |
15494 | printf (P_("\n%8d regular file\n", "\n%8d regular files\n", | 14793 | printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count)); |
15495 | ctx->fs_regular_count), ctx->fs_regular_count); | 14794 | printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count)); |
15496 | printf (P_("%8d directory\n", "%8d directories\n", | 14795 | printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links)); |
15497 | ctx->fs_directory_count), ctx->fs_directory_count); | 14796 | printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count)); |
15498 | printf (P_("%8d character device file\n", | 14797 | printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count)); |
15499 | "%8d character device files\n", ctx->fs_chardev_count), | 14798 | printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count)); |
15500 | ctx->fs_chardev_count); | 14799 | printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links)); |
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 | } | 14800 | } |
15519 | 14801 | ||
15520 | static void check_mount(e2fsck_t ctx) | 14802 | static void check_mount(e2fsck_t ctx) |
@@ -15677,12 +14959,13 @@ struct percent_tbl { | |||
15677 | int max_pass; | 14959 | int max_pass; |
15678 | int table[32]; | 14960 | int table[32]; |
15679 | }; | 14961 | }; |
15680 | static struct percent_tbl e2fsck_tbl = { | 14962 | static const struct percent_tbl e2fsck_tbl = { |
15681 | 5, { 0, 70, 90, 92, 95, 100 } | 14963 | 5, { 0, 70, 90, 92, 95, 100 } |
15682 | }; | 14964 | }; |
14965 | |||
15683 | static char bar[128], spaces[128]; | 14966 | static char bar[128], spaces[128]; |
15684 | 14967 | ||
15685 | static float calc_percent(struct percent_tbl *tbl, int pass, int curr, | 14968 | static float calc_percent(const struct percent_tbl *tbl, int pass, int curr, |
15686 | int max) | 14969 | int max) |
15687 | { | 14970 | { |
15688 | float percent; | 14971 | float percent; |
@@ -15854,7 +15137,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) | |||
15854 | int ea_ver; | 15137 | int ea_ver; |
15855 | int extended_usage = 0; | 15138 | int extended_usage = 0; |
15856 | 15139 | ||
15857 | buf = string_copy(ctx, opts, 0); | 15140 | buf = string_copy(opts, 0); |
15858 | for (token = buf; token && *token; token = next) { | 15141 | for (token = buf; token && *token; token = next) { |
15859 | p = strchr(token, ','); | 15142 | p = strchr(token, ','); |
15860 | next = 0; | 15143 | next = 0; |
@@ -15885,12 +15168,12 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) | |||
15885 | extended_usage++; | 15168 | extended_usage++; |
15886 | } | 15169 | } |
15887 | if (extended_usage) { | 15170 | if (extended_usage) { |
15888 | fprintf(stderr, _("Extended options are separated by commas, " | 15171 | bb_error_msg_and_die( |
15172 | "Extended options are separated by commas, " | ||
15889 | "and may take an argument which\n" | 15173 | "and may take an argument which\n" |
15890 | "is set off by an equals ('=') sign. " | 15174 | "is set off by an equals ('=') sign. " |
15891 | "Valid raid options are:\n" | 15175 | "Valid raid options are:\n" |
15892 | "\tea_ver=<ea_version (1 or 2)\n\n")); | 15176 | "\tea_ver=<ea_version (1 or 2)\n\n"); |
15893 | exit(1); | ||
15894 | } | 15177 | } |
15895 | } | 15178 | } |
15896 | 15179 | ||
@@ -16003,7 +15286,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
16003 | ctx->inode_buffer_blocks = atoi(optarg); | 15286 | ctx->inode_buffer_blocks = atoi(optarg); |
16004 | break; | 15287 | break; |
16005 | case 'j': | 15288 | case 'j': |
16006 | ctx->journal_name = string_copy(ctx, optarg, 0); | 15289 | ctx->journal_name = string_copy(optarg, 0); |
16007 | break; | 15290 | break; |
16008 | case 'P': | 15291 | case 'P': |
16009 | ctx->process_inode_size = atoi(optarg); | 15292 | ctx->process_inode_size = atoi(optarg); |
@@ -16011,7 +15294,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
16011 | case 'L': | 15294 | case 'L': |
16012 | replace_bad_blocks++; | 15295 | replace_bad_blocks++; |
16013 | case 'l': | 15296 | case 'l': |
16014 | bad_blocks_file = string_copy(ctx, optarg, 0); | 15297 | bad_blocks_file = string_copy(optarg, 0); |
16015 | break; | 15298 | break; |
16016 | case 'd': | 15299 | case 'd': |
16017 | ctx->options |= E2F_OPT_DEBUG; | 15300 | ctx->options |= E2F_OPT_DEBUG; |
@@ -16145,12 +15428,12 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
16145 | return 0; | 15428 | return 0; |
16146 | } | 15429 | } |
16147 | 15430 | ||
16148 | static const char *my_ver_string = E2FSPROGS_VERSION; | 15431 | static const char my_ver_string[] = E2FSPROGS_VERSION; |
16149 | static const char *my_ver_date = E2FSPROGS_DATE; | 15432 | static const char my_ver_date[] = E2FSPROGS_DATE; |
16150 | 15433 | ||
16151 | int e2fsck_main (int argc, char *argv[]) | 15434 | int e2fsck_main (int argc, char *argv[]) |
16152 | { | 15435 | { |
16153 | errcode_t retval = 0; | 15436 | errcode_t retval; |
16154 | int exit_value = FSCK_OK; | 15437 | int exit_value = FSCK_OK; |
16155 | ext2_filsys fs = 0; | 15438 | ext2_filsys fs = 0; |
16156 | io_manager io_ptr; | 15439 | io_manager io_ptr; |
@@ -16302,7 +15585,7 @@ restart: | |||
16302 | */ | 15585 | */ |
16303 | if (ctx->device_name == 0 && | 15586 | if (ctx->device_name == 0 && |
16304 | (sb->s_volume_name[0] != 0)) { | 15587 | (sb->s_volume_name[0] != 0)) { |
16305 | ctx->device_name = string_copy(ctx, sb->s_volume_name, | 15588 | ctx->device_name = string_copy(sb->s_volume_name, |
16306 | sizeof(sb->s_volume_name)); | 15589 | sizeof(sb->s_volume_name)); |
16307 | } | 15590 | } |
16308 | if (ctx->device_name == 0) | 15591 | if (ctx->device_name == 0) |