2
* Copyright (c) International Business Machines Corp., 2000
2
* Copyright (C) International Business Machines Corp., 2000-2004
4
4
* This program is free software; you can redistribute it and/or modify
5
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
6
* the Free Software Foundation; either version 2 of the License, or
7
7
* (at your option) any later version.
9
9
* This program is distributed in the hope that it will be useful,
10
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12
12
* the GNU General Public License for more details.
14
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
15
* along with this program; if not, write to the Free Software
16
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
* MODULE_NAME: fsckwsp.c
20
* COMPONENT_NAME: jfs utilities
24
* blkall_decrement_owners
25
* blkall_increment_owners
29
* directory_buffers_alloc
30
* directory_buffers_release
35
* establish_agg_workspace
37
* establish_fs_workspace
38
* establish_io_buffers
39
* establish_wsp_block_map_ctl
53
* release_inode_extension
54
* release_logredo_allocs
55
* temp_inode_buf_alloc
56
* temp_inode_buf_release
67
* dupall_extract_blkrec
70
* dupall_insert_blkrec
71
* establish_wsp_block_map
73
* extent_record_dupchk
77
* inorec_agg_search_insert
79
* inorec_fs_search_insert
87
* defines and includes common among the xfsck modules
18
/* defines and includes common among the fsck.jfs modules */
89
19
#include "xfsckint.h"
91
21
#include <unistd.h>
95
extern uint32_t type_jfs;
96
extern void ujfs_swap_fsck_blk_map_page( fsck_blk_map_page_t * );
97
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
99
* buffer for endian swapping structures
101
* buffer used when needed in individual routines
103
extern char *swap_buf_ptr;
106
25
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
196
retcode_t alloc_wsp_extent ( reg_idx_t, int );
198
retcode_t dupall_extract_blkrec ( dupall_blkrec_ptr, dupall_blkrec_tkn );
200
retcode_t dupall_find_blkrec ( fsblkidx_t, dupall_blkrec_ptr *,
201
dupall_blkrec_tkn * );
203
retcode_t dupall_get_blkrec ( dupall_blkrec_ptr * );
205
retcode_t dupall_insert_blkrec ( fsblkidx_t );
207
retcode_t establish_wsp_block_map ( void );
209
retcode_t extent_1stref_chk ( fsblkidx_t, fsblkidx_t, int8_t, int8_t,
210
fsck_msg_info_ptr, fsck_inode_recptr );
212
retcode_t extent_record_dupchk ( fsblkidx_t, fsblkidx_t, int8_t, int8_t, int8_t,
213
fsck_msg_info_ptr, fsck_inode_recptr );
215
retcode_t fsblk_count_avail( fsck_bitmap_ptr, int32_t*, int32_t*, int32_t, int32_t * );
217
retcode_t fsblk_next_avail( fsck_bitmap_ptr, int32_t, int32_t, int32_t *,
220
retcode_t inorec_agg_search( uint32_t, fsck_inode_recptr * );
222
retcode_t inorec_agg_search_insert( uint32_t, fsck_inode_recptr * );
224
retcode_t inorec_fs_search( uint32_t, fsck_inode_recptr * );
226
retcode_t inorec_fs_search_insert( uint32_t, fsck_inode_recptr * );
228
void locate_inode( uint32_t, int32_t *, int32_t *, int32_t * );
230
retcode_t treeStack_get_elem ( treeStack_ptr * );
232
retcode_t treeStack_rel_elem ( treeStack_ptr );
90
int alloc_wsp_extent(uint32_t, int);
92
void dupall_extract_blkrec(struct dupall_blkrec *);
94
struct dupall_blkrec *dupall_find_blkrec(int64_t, int64_t);
96
struct dupall_blkrec *dupall_get_blkrec(void);
98
int dupall_insert_blkrec(int64_t, int64_t, struct dupall_blkrec **);
100
int establish_wsp_block_map(void);
102
int extent_1stref_chk(int64_t, int64_t, int8_t, int8_t,
103
struct fsck_ino_msg_info *, struct fsck_inode_record *);
105
int extent_record_dupchk(int64_t, int64_t, int8_t, int8_t, int8_t,
106
struct fsck_ino_msg_info *,
107
struct fsck_inode_record *);
109
int fsblk_count_avail(uint32_t *, int32_t *, int32_t *, int32_t, int32_t *);
111
int fsblk_next_avail(uint32_t *, int32_t, int32_t, int32_t *, int32_t *, int *);
113
int inorec_agg_search(uint32_t, struct fsck_inode_record **);
115
int inorec_agg_search_insert(uint32_t, struct fsck_inode_record **);
117
int inorec_fs_search(uint32_t, struct fsck_inode_record **);
119
int inorec_fs_search_insert(uint32_t, struct fsck_inode_record **);
121
void locate_inode(uint32_t, int32_t *, int32_t *, int32_t *);
123
int treeStack_get_elem(struct treeStack_record **);
125
int treeStack_rel_elem(struct treeStack_record *);
236
128
* The following are used for reporting storage related errors
285
180
* will return the address of the dynamic storage
286
181
* allocated for the caller
291
184
* success: FSCK_OK
292
185
* failure: something else
294
retcode_t alloc_wrksp ( reg_idx_t length,
297
void **addr_wrksp_ptr )
187
int alloc_wrksp(uint32_t length, int dynstg_object, int for_logredo,
188
void **addr_wrksp_ptr)
299
retcode_t awsp_rc = FSCK_OK;
300
char *wsp_ptr = NULL;
301
wsp_ext_rec_ptr this_fer;
302
reg_idx_t bytes_avail;
303
reg_idx_t min_length;
305
*addr_wrksp_ptr = NULL; /* initialize return value */
306
min_length = ((length + 7) / 8) * 8; /* round up to an 8 byte boundary */
308
while ( (wsp_ptr == NULL) && (awsp_rc == FSCK_OK) ) {
309
this_fer = agg_recptr->wsp_extent_list;
311
while ( (this_fer != NULL) &&
313
(awsp_rc == FSCK_OK) ) {
314
if ( (for_logredo) && !(this_fer->for_logredo) ) {
316
* requestor is logredo and
317
* fer describes an allocation not for logredo
319
this_fer = this_fer->next;
320
} else { /* this fer describes an eligible allocation */
321
bytes_avail = this_fer->extent_length - this_fer->last_byte_used;
322
if ( bytes_avail >= min_length ) { /* there's enough here */
323
wsp_ptr = this_fer->extent_addr + this_fer->last_byte_used + 1;
324
this_fer->last_byte_used += min_length;
325
} else { /* try the next fer */
326
this_fer = this_fer->next;
327
} /* end else try the next fer */
328
} /* end else this fer describes an eligible allocation */
331
if ( (awsp_rc == FSCK_OK) && (wsp_ptr == NULL) ) {
333
* nothing fatal but we didn't find the
336
awsp_rc = alloc_wsp_extent( min_length, for_logredo ); /*
337
* will allocate some number of memory segments
338
* and put the fer describing it on the beginning
341
} /* end nothing fatal but we didn't find the storage yet */
344
if ( awsp_rc == FSCK_OK ) { /* we allocated virtual storage */
346
* now initialize the storage
348
memset( (void *) wsp_ptr, 0, length );
350
*addr_wrksp_ptr = (void *) wsp_ptr; /* set the return value */
351
} /* end we allocated virtual storage */
354
} /* end alloc_wrksp */
190
int awsp_rc = FSCK_OK;
191
char *wsp_ptr = NULL;
192
struct wsp_ext_rec *this_fer;
193
uint32_t bytes_avail;
196
*addr_wrksp_ptr = NULL;
197
/* round up to an 8 byte boundary */
198
min_length = ((length + 7) / 8) * 8;
200
while ((wsp_ptr == NULL) && (awsp_rc == FSCK_OK)) {
201
this_fer = agg_recptr->wsp_extent_list;
203
while ((this_fer != NULL) && (wsp_ptr == NULL)
204
&& (awsp_rc == FSCK_OK)) {
205
if ((for_logredo) && !(this_fer->for_logredo)) {
207
* requestor is logredo and
208
* fer describes an allocation not for logredo
210
this_fer = this_fer->next;
212
/* this fer describes an eligible allocation */
214
this_fer->extent_length -
215
this_fer->last_byte_used;
216
if (bytes_avail >= min_length) {
217
/* there's enough here */
219
this_fer->extent_addr +
220
this_fer->last_byte_used + 1;
221
this_fer->last_byte_used += min_length;
223
/* try the next fer */
224
this_fer = this_fer->next;
229
if ((awsp_rc == FSCK_OK) && (wsp_ptr == NULL)) {
231
* nothing fatal but we didn't find the
235
* will allocate some number of memory segments
236
* and put the fer describing it on the beginning
239
awsp_rc = alloc_wsp_extent(min_length, for_logredo);
243
if (awsp_rc == FSCK_OK) {
244
/* we allocated virtual storage */
246
* now initialize the storage
248
memset((void *) wsp_ptr, 0, length);
250
/* set the return value */
251
*addr_wrksp_ptr = (void *) wsp_ptr;
357
256
/****************************************************************************
358
257
* NAME: alloc_wsp_extent
366
265
* minimum_length - input - minimum number of bytes of contiguous storage
372
269
* success: FSCK_OK
373
270
* failure: something else
375
retcode_t alloc_wsp_extent ( reg_idx_t minimum_length,
272
int alloc_wsp_extent(uint32_t minimum_length, int for_logredo)
378
retcode_t awe_rc = FSCK_OK;
379
wsp_ext_rec_ptr new_fer;
380
int32_t extent_length = MEMSEGSIZE;
381
char *extent_addr = NULL;
382
int8_t from_high_memory = 0;
385
* the user has specified the minimum needed. We must allocate
386
* at least 16 more than that because we're going to use 16 bytes
387
* at the beginning to keep track of it.
389
while ( extent_length < (minimum_length + 16) ) {
390
extent_length += MEMSEGSIZE;
393
wsp_dynstg_object = dynstg_iobufs;
394
wsp_dynstg_action = dynstg_allocation;
396
extent_addr = (char *) malloc(extent_length);
398
if ( extent_addr == NULL ) { /* allocation failure */
399
awe_rc = FSCK_FAILED_DYNSTG_EXHAUST4;
400
if ( ! for_logredo ) {
401
sprintf( message_parm_0, "%d", wsp_dynstg_action );
402
msgprms[0] = message_parm_0;
404
sprintf( message_parm_1, "%d", dynstg_wspext );
405
msgprms[1] = message_parm_1;
407
fsck_send_msg( fsck_EXHDYNSTG, 0, 2 );
408
} /* end not for logredo */
409
} else { /* got the dynamic storage */
411
* use the first 16 bytes of it to keep track of it
413
new_fer = (wsp_ext_rec_ptr) extent_addr;
414
new_fer->extent_length = extent_length;
415
new_fer->for_logredo = for_logredo;
416
new_fer->from_high_memory = from_high_memory;
417
new_fer->extent_addr = extent_addr;
418
new_fer->last_byte_used = sizeof(fsck_extent_record) - 1;
420
new_fer->next = agg_recptr->wsp_extent_list;
421
agg_recptr->wsp_extent_list = new_fer;
422
} /* end else got the dynamic storage */
425
} /* end alloc_wsp_extent */
274
int awe_rc = FSCK_OK;
275
struct wsp_ext_rec *new_fer;
276
int32_t extent_length = MEMSEGSIZE;
277
char *extent_addr = NULL;
278
int8_t from_high_memory = 0;
281
* the user has specified the minimum needed. We must allocate
282
* at least 16 more than that because we're going to use 16 bytes
283
* at the beginning to keep track of it.
285
while (extent_length < (minimum_length + 16)) {
286
extent_length += MEMSEGSIZE;
289
wsp_dynstg_object = dynstg_iobufs;
290
wsp_dynstg_action = dynstg_allocation;
292
extent_addr = (char *) malloc(extent_length);
294
if (extent_addr == NULL) {
295
/* allocation failure */
296
awe_rc = FSCK_FAILED_DYNSTG_EXHAUST4;
298
fsck_send_msg(fsck_EXHDYNSTG, wsp_dynstg_action,
302
/* got the dynamic storage */
304
* use the first 16 bytes of it to keep track of it
306
new_fer = (struct wsp_ext_rec *) extent_addr;
307
new_fer->extent_length = extent_length;
308
new_fer->for_logredo = for_logredo;
309
new_fer->from_high_memory = from_high_memory;
310
new_fer->extent_addr = extent_addr;
311
new_fer->last_byte_used = sizeof (struct wsp_ext_rec) - 1;
313
new_fer->next = agg_recptr->wsp_extent_list;
314
agg_recptr->wsp_extent_list = new_fer;
428
319
/****************************************************************************
429
* NAME: blkall_decrement_owners
320
* NAME: blkall_mark_free
431
* FUNCTION: Adjust the fsck workspace to show one less owner for the
322
* FUNCTION: Adjust the fsck workspace to show the indicated blocks are no
435
* blk_num - input - ordinal number of the filesystem block whose owner
436
* count is to be adjusted.
326
* first_block - input - ordinal number of the first filesystem block
327
* whose owner count is to be adjusted.
328
* last_block - input - ordinal number of the last filesystem block
329
* whose owner count is to be adjusted.
441
332
* success: FSCK_OK
442
333
* failure: something else
336
* This could be written to be more efficient, but it's a big
337
* improvement over how it used to be.
444
retcode_t blkall_decrement_owners ( fsblkidx_t blk_num )
339
int blkall_mark_free(int64_t first_block, int64_t last_block)
446
retcode_t ddo_rc = FSCK_OK;
447
dupall_blkrec_ptr this_blkrec;
448
dupall_blkrec_tkn this_blktkn;
450
reg_idx_t word_offset;
451
fsck_dword_bitmask_t bit_mask;
452
blk_pageptr this_page;
453
fsck_bitmap_ptr this_word;
456
* if the given block number is a multiply-allocated block,
457
* decrement its count of inode owners.
459
ddo_rc = dupall_find_blkrec( blk_num, &this_blkrec, &this_blktkn );
460
if ( this_blkrec != NULL ) { /* block is multiply-allocated */
461
this_blkrec->owner_count--;
463
if ( this_blkrec->owner_count == 1 ) { /* now only singly-allocated */
464
if ( !(this_blkrec->first_ref_resolved) ) {
465
agg_recptr->unresolved_1stref_count--;
467
agg_recptr->dup_block_count--;
468
ddo_rc = dupall_extract_blkrec( this_blkrec, this_blktkn ); /* take
469
* the block off the list of multiply-allocated
472
} /* end now only singly-allocated */
473
} else { /* the block is not multiply-allocated */
474
ddo_rc = blkmap_find_bit( blk_num, &page_num, &word_offset, &bit_mask);
475
ddo_rc = blkmap_get_page( page_num, &this_page );
476
if ( ddo_rc == FSCK_OK ) { /* got the page */
477
this_word = (fsck_bitmap_ptr) ((char *) this_page + word_offset);
478
(*this_word) &= ~bit_mask; /*
479
* mark it not allocated at all
481
ddo_rc = blkmap_put_page( page_num ); /* write it to workspace */
482
} /* end got the page */
483
} /* end the block is not multiply-allocated */
486
} /* end blkall_decrement_owners() */
342
int ddo_rc = FSCK_OK;
344
int64_t last_page_num = -1;
345
uint32_t word_offset;
347
struct fsck_blk_map_page *this_page;
350
for (blk_num = first_block; blk_num <= last_block; blk_num++) {
351
blkmap_find_bit(blk_num, &page_num, &word_offset, &bit_mask);
352
if (page_num != last_page_num) {
353
if (last_page_num != -1)
354
blkmap_put_page(last_page_num);
355
ddo_rc = blkmap_get_page(page_num, &this_page);
358
last_page_num = page_num;
360
this_word = (uint32_t *) ((char *) this_page + word_offset);
361
/* mark it not allocated */
362
(*this_word) &= ~bit_mask;
365
if (last_page_num != -1)
366
blkmap_put_page(last_page_num);
489
371
/****************************************************************************
490
372
* NAME: blkall_increment_owners
493
375
* indicated block.
496
* blk_num - input - ordinal number of the filesystem block whose owner
497
* count is to be adjusted.
378
* first_block - input - ordinal number of the first filesystem block
379
* whose owner count is to be adjusted.
380
* last_block - input - ordinal number of the first filesystem block
381
* whose owner count is to be adjusted.
382
* msg_info_ptr - input - information needed to issue messages for this
383
* extent. If NULL, no messages will be issued
503
* failure: something else
386
* success: 0, or 1 if multiply-allocated blocks found
387
* failure: something less than 0
505
retcode_t blkall_increment_owners ( fsblkidx_t blk_num )
389
int blkall_increment_owners(int64_t first_block,
391
struct fsck_ino_msg_info *msg_info_ptr)
507
retcode_t dio_rc = FSCK_OK;
508
dupall_blkrec_ptr this_blkrec;
509
dupall_blkrec_tkn this_blktkn;
511
reg_idx_t word_offset;
512
fsck_dword_bitmask_t bit_mask;
513
blk_pageptr this_page;
514
fsck_bitmap_ptr this_word;
517
dio_rc = blkmap_find_bit( blk_num, &page_num, &word_offset, &bit_mask );
518
dio_rc = blkmap_get_page( page_num, &this_page );
520
if ( dio_rc == FSCK_OK ) { /* got the page */
521
this_word = (fsck_bitmap_ptr) ((char *) this_page + word_offset);
523
if ( ((*this_word) & bit_mask) != bit_mask ) {
527
(*this_word) |= bit_mask; /* mark it allocated */
528
dio_rc = blkmap_put_page( page_num ); /* write it to workspace */
529
if ( dio_rc != FSCK_OK ) {
530
dio_rc = FSCK_FAILED_WRITE_FBLKMP;
531
} /* end failure here is fatal but return code is in the ... */
532
} else { /* already allocated */
534
dio_rc = dupall_find_blkrec( blk_num, &this_blkrec, &this_blktkn );
536
if ( this_blkrec != NULL ) { /* block is already multiply-allocated */
537
this_blkrec->owner_count++; /* increment owners */
538
} else { /* else this is the 2nd owner */
539
dio_rc = dupall_insert_blkrec( blk_num );
540
agg_recptr->dup_block_count++;
541
agg_recptr->unresolved_1stref_count++;
542
} /* end else this is the 2nd owner */
543
} /* end else already allocated */
544
} /* end got the page */
546
if ( dio_rc == FSCK_OK ) {
551
} /* end blkall_increment_owners() */
396
int64_t last_page_num = -1;
397
uint32_t word_offset;
399
struct fsck_blk_map_page *this_page;
402
int64_t first_in_dup_range = 0;
403
int32_t size_of_dup_range = 0;
405
for (blk_num = first_block; blk_num <= last_block; blk_num++) {
406
blkmap_find_bit(blk_num, &page_num, &word_offset, &bit_mask);
407
if (page_num != last_page_num) {
408
if (last_page_num != -1)
409
blkmap_put_page(last_page_num);
410
dio_rc = blkmap_get_page(page_num, &this_page);
413
last_page_num = page_num;
415
this_word = (uint32_t *) ((char *) this_page + word_offset);
417
if (((*this_word) & bit_mask) != bit_mask) {
421
/* mark it allocated */
422
(*this_word) |= bit_mask;
424
/* Record previously found duplicate range */
425
if (size_of_dup_range) {
427
fsck_send_msg(fsck_DUPBLKREF,
429
(long long) first_in_dup_range,
430
fsck_ref_msg(msg_info_ptr->msg_inotyp),
431
fsck_ref_msg(msg_info_ptr->msg_inopfx),
432
msg_info_ptr->msg_inonum);
433
dio_rc = dupall_insert_blkrec(
436
size_of_dup_range - 1,
440
agg_recptr->dup_block_count++;
441
agg_recptr->unresolved_1stref_count++;
442
size_of_dup_range = 0;
443
first_in_dup_range = 0;
447
/* already allocated */
448
if (!size_of_dup_range++)
449
first_in_dup_range = blk_num;
453
if (last_page_num != -1)
454
blkmap_put_page(last_page_num);
456
/* Record duplicate range */
457
if (size_of_dup_range) {
459
fsck_send_msg(fsck_DUPBLKREF, size_of_dup_range,
460
(long long) first_in_dup_range,
461
fsck_ref_msg(msg_info_ptr->msg_inotyp),
462
fsck_ref_msg(msg_info_ptr->msg_inopfx),
463
msg_info_ptr->msg_inonum);
464
dio_rc = dupall_insert_blkrec(first_in_dup_range,
465
first_in_dup_range + size_of_dup_range - 1,
469
agg_recptr->dup_block_count++;
470
agg_recptr->unresolved_1stref_count++;
554
477
/****************************************************************************
555
* NAME: blkall_ref_check
478
* NAME: blkall_split_blkrec
557
* FUNCTION: Determine whether the given block is multiply-allocated and, if
558
* so, whether the first reference to it is unresolved. (In this
559
* case, the current reference must be the first reference.)
480
* FUNCTION: Split the current duplicate block record
562
* blk_num - input - ordinal number of the filesystem block to be
564
* ref_resolved - input - pointer to a variable in which the results of the
565
* query are returned. If the current reference is
566
* the first reference to a multiply-allocated block,
567
* -1 is returned. Otherwise, 0 is returned.
483
* blkrec - input - duplicate block record to be split
484
* first_block - input - first block of range whose intersection with
485
* blkrec causes the split
486
* last_block - input - last block of range whose intersection with
487
* blkrec causes the split
572
489
* success: FSCK_OK
573
490
* failure: something else
575
retcode_t blkall_ref_check ( fsblkidx_t blk_num,
492
int blkall_split_blkrec(struct dupall_blkrec *blkrec,
578
retcode_t brc_rc = FSCK_OK;
579
dupall_blkrec_ptr this_blkrec;
580
dupall_blkrec_tkn this_blktkn;
583
* if the given block number is a multiply-allocated block with
584
* an unresolved first reference, this must be that first reference
586
brc_rc = dupall_find_blkrec( blk_num, &this_blkrec, &this_blktkn );
588
if ( (brc_rc == FSCK_OK) && (this_blkrec != NULL) ) {
590
* block is multiply-allocated
592
if ( this_blkrec->first_ref_resolved == 0 ) {
594
* haven't seen the first ref yet
596
this_blkrec->first_ref_resolved = 1;
597
agg_recptr->unresolved_1stref_count--;
599
} else { /* we have already resolved the first ref for this block */
601
} /* end else we have already resolved the first ref ... */
602
} else { /* block is not multiply-allocated */
604
} /* end else block is not multiply-allocated */
607
} /* end blkall_ref_check () */
496
int bsb_rc = FSCK_OK;
497
struct dupall_blkrec *new_blkrec;
500
if (blkrec->first_blk < first_block) {
501
temp = blkrec->last_blk;
502
blkrec->last_blk = first_block - 1;
503
bsb_rc = dupall_insert_blkrec(first_block, temp, &new_blkrec);
506
new_blkrec->first_ref_resolved = blkrec->first_ref_resolved;
507
new_blkrec->owner_count = blkrec->owner_count;
508
agg_recptr->dup_block_count++;
509
if (!new_blkrec->first_ref_resolved)
510
agg_recptr->unresolved_1stref_count++;
515
if (blkrec->last_blk > last_block) {
516
temp = blkrec->last_blk;
517
blkrec->last_blk = last_block;
518
bsb_rc = dupall_insert_blkrec(first_block, temp, &new_blkrec);
521
new_blkrec->first_ref_resolved = blkrec->first_ref_resolved;
522
new_blkrec->owner_count = blkrec->owner_count;
523
agg_recptr->dup_block_count++;
524
if (!new_blkrec->first_ref_resolved)
525
agg_recptr->unresolved_1stref_count++;
610
531
/****************************************************************************
611
532
* NAME: dire_buffer_alloc
618
539
* the address of the allocated buffer (or
619
540
* NULL if no buffer could be allocated)
624
543
* success: FSCK_OK
625
544
* failure: something else
627
retcode_t dire_buffer_alloc ( dtpage_t **addr_dnode_ptr )
546
int dire_buffer_alloc(dtpage_t ** addr_dnode_ptr)
629
retcode_t rba_rc = FSCK_OK;
630
reg_idx_t bufrec_length, bytes_available;
631
recon_bufrec_ptr bufrec_ptr;
633
if ( agg_recptr->recon_buf_stack != NULL ) { /* stack not empty */
634
bufrec_ptr = agg_recptr->recon_buf_stack;
635
agg_recptr->recon_buf_stack = bufrec_ptr->stack_next;
637
bufrec_ptr->stack_next = NULL;
638
bufrec_ptr->dnode_blkoff = 0;
639
bufrec_ptr->dnode_byteoff = 0;
640
*addr_dnode_ptr = &(bufrec_ptr->dnode_buf);
641
} else { /* the stack is empty */
642
bufrec_length = sizeof( struct recon_buf_record );
643
bytes_available = agg_recptr->recon_buf_extent->extent_length -
644
agg_recptr->recon_buf_extent->last_byte_used;
646
if ( bytes_available < bufrec_length ) {
647
/* we've used up a whole
648
* extent of dynamic storage -- something
649
* strange is going on
651
*addr_dnode_ptr = NULL;
652
rba_rc = FSCK_INSUFDSTG4RECON;
653
} else { /* there is enough dynamic storage for another one */
654
bufrec_ptr = (recon_bufrec_ptr)
655
(agg_recptr->recon_buf_extent->extent_addr +
656
agg_recptr->recon_buf_extent->last_byte_used + 1);
657
agg_recptr->recon_buf_extent->last_byte_used += bufrec_length;
659
* now initialize the record
661
wsp_dynstg_object = dynstg_recondnodebuf;
662
wsp_dynstg_action = dynstg_initialization;
663
memset( (void *) bufrec_ptr, 0, bufrec_length );
664
*addr_dnode_ptr = &(bufrec_ptr->dnode_buf);
665
} /* end else there is enough dynamic storage for another one */
666
} /* end else the stack is empty */
669
} /* end dire_buffer_alloc */
548
int rba_rc = FSCK_OK;
549
uint32_t bufrec_length, bytes_available;
550
struct recon_buf_record *bufrec_ptr;
552
if (agg_recptr->recon_buf_stack != NULL) {
553
/* stack not empty */
554
bufrec_ptr = agg_recptr->recon_buf_stack;
555
agg_recptr->recon_buf_stack = bufrec_ptr->stack_next;
557
bufrec_ptr->stack_next = NULL;
558
bufrec_ptr->dnode_blkoff = 0;
559
bufrec_ptr->dnode_byteoff = 0;
560
*addr_dnode_ptr = &(bufrec_ptr->dnode_buf);
562
/* the stack is empty */
563
bufrec_length = sizeof (struct recon_buf_record);
564
bytes_available = agg_recptr->recon_buf_extent->extent_length -
565
agg_recptr->recon_buf_extent->last_byte_used;
567
if (bytes_available < bufrec_length) {
568
/* we've used up a whole
569
* extent of dynamic storage -- something
570
* strange is going on
572
*addr_dnode_ptr = NULL;
573
rba_rc = FSCK_INSUFDSTG4RECON;
575
/* there is enough dynamic storage for another one */
576
bufrec_ptr = (struct recon_buf_record *)
577
(agg_recptr->recon_buf_extent->extent_addr +
578
agg_recptr->recon_buf_extent->last_byte_used + 1);
579
agg_recptr->recon_buf_extent->last_byte_used +=
582
* now initialize the record
584
wsp_dynstg_object = dynstg_recondnodebuf;
585
wsp_dynstg_action = dynstg_initialization;
586
memset((void *) bufrec_ptr, 0, bufrec_length);
587
*addr_dnode_ptr = &(bufrec_ptr->dnode_buf);
672
593
/****************************************************************************
673
594
* NAME: dire_buffer_release
949
847
* allocation list.
952
* block_number - input - ordinal number of the filesystem block to match
953
* block_recptr - input - pointer to a variable in which to return the
954
* address of the record found. If no record is
955
* found, NULL is returned.
956
* block_rectkn - input - pointer to a variable in which to return a token
957
* if a record is found. If no record is found,
850
* first_block - input - ordinal number of the first filesystem block
851
* last_block - input - ordinal number of the last filesystem block
960
853
* NOTES: The duplicate allocation list is described in the aggregate record,
961
854
* field: dup_alloc_lst
963
* The token actually contains the address of the list record which
964
* points to the record found (or NULL if the record is at the
965
* beginning of the list). This is a required input to certain other
966
* routines which operate on the duplicate allocation list.
970
* failure: something else
857
* success: record found
972
retcode_t dupall_find_blkrec ( fsblkidx_t block_number,
973
dupall_blkrec_ptr *block_recptr,
974
dupall_blkrec_tkn *block_rectkn )
860
struct dupall_blkrec *dupall_find_blkrec(int64_t first_block,
976
retcode_t dfb_rc = FSCK_OK;
977
dupall_blkrec_ptr prev_blkrec, this_blkrec;
981
this_blkrec = agg_recptr->dup_alloc_lst;
983
if ( this_blkrec == NULL ) { /* empty list */
985
} else { /* list of multiply-allocated blocks is not empty */
987
while ( !dfb_done ) {
988
if ( this_blkrec->blk_number == block_number ) { /* found match */
990
} else if ( this_blkrec->blk_number > block_number ) {
997
} else if ( this_blkrec->next == NULL ) { /* end of list */
1001
} else { /* try the next one */
1002
prev_blkrec = this_blkrec;
1003
this_blkrec = this_blkrec->next;
1004
} /* end else try the next one */
1006
} /* end else list of multiply-allocated blocks is not empty */
1008
*block_recptr = this_blkrec;
1009
*block_rectkn = prev_blkrec;
1012
} /* end dupall_find_blkrec() */
863
struct dupall_blkrec *this_blkrec;
865
for (this_blkrec = agg_recptr->dup_alloc_lst;
866
this_blkrec && this_blkrec->first_blk <= last_block;
867
this_blkrec = this_blkrec->next) {
868
if (this_blkrec->last_blk >= first_block)
1015
874
/****************************************************************************
1016
875
* NAME: dupall_get_blkrec
1022
* addr_blkrec_ptr - input - pointer to a variable in which the address
1023
* of the new record will be returned.
1029
* failure: something else
884
* success: address of record
1031
retcode_t dupall_get_blkrec ( dupall_blkrec_ptr *addr_blkrec_ptr )
887
struct dupall_blkrec *dupall_get_blkrec(void)
1033
retcode_t dgb_rc = FSCK_OK;
1034
int I_am_logredo = 0;
1036
if ( agg_recptr->free_dupall_blkrec != NULL ) { /* free list isn't empty */
1037
*addr_blkrec_ptr = agg_recptr->free_dupall_blkrec;
1038
agg_recptr->free_dupall_blkrec = agg_recptr->free_dupall_blkrec->next;
1039
} else { /* else the free list is empty */
1040
dgb_rc = alloc_wrksp( dupall_blkrec_length, dynstg_dupall_blkrec,
1041
I_am_logredo, (void **) addr_blkrec_ptr );
1042
} /* end else the free list is empty */
1045
} /* end dupall_get_blkrec */
889
struct dupall_blkrec *addr_blkrec_ptr;
890
int dgb_rc = FSCK_OK;
892
if (agg_recptr->free_dupall_blkrec != NULL) {
893
/* free list isn't empty */
894
addr_blkrec_ptr = agg_recptr->free_dupall_blkrec;
895
agg_recptr->free_dupall_blkrec = addr_blkrec_ptr->next;
897
/* else the free list is empty */
898
dgb_rc = alloc_wrksp(dupall_blkrec_length, dynstg_dupall_blkrec,
899
0, (void **) &addr_blkrec_ptr);
901
if (dgb_rc == FSCK_OK)
902
return addr_blkrec_ptr;
1048
907
/*****************************************************************************
1049
908
* NAME: dupall_insert_blkrec
1051
* FUNCTION: Allocate a duplicate allocation record for the given block and
1052
* insert it into the sorted, singly-linked list of duplicate
910
* FUNCTION: Allocate a duplicate allocation record for the given blocks and
911
* insert it into the sorted, doubly-linked list of duplicate
1053
912
* allocation records.
1056
* block_num - input - the block number for which the record is to be
915
* first_block - input - the first block number for which the record is
917
* last_block - input - the last block number for which the record is
1059
920
* NOTES: The duplicate allocation list is described in the aggregate record,
1060
921
* field: dup_alloc_lst
1063
924
* success: FSCK_OK
1064
925
* failure: something else
1066
retcode_t dupall_insert_blkrec ( fsblkidx_t block_num )
927
int dupall_insert_blkrec(int64_t first_block, int64_t last_block,
928
struct dupall_blkrec **blkrec)
1068
retcode_t dib_rc = FSCK_OK;
1069
dupall_blkrec_ptr new_blkrec, prev_blkrec, this_blkrec;
1072
dib_rc = dupall_get_blkrec( &new_blkrec );
1074
if ( dib_rc == FSCK_OK ) { /* got a block record */
1075
new_blkrec->blk_number = block_num;
1076
new_blkrec->owner_count = 2;
1078
if ( agg_recptr->dup_alloc_lst == NULL ) { /* list now empty */
1079
new_blkrec->next = NULL;
1080
agg_recptr->dup_alloc_lst = new_blkrec;
1081
} else { /* list not empty */
1082
if ( agg_recptr->dup_alloc_lst->blk_number > block_num ) {
1086
new_blkrec->next = agg_recptr->dup_alloc_lst;
1087
agg_recptr->dup_alloc_lst = new_blkrec;
1088
} else { /* doesn't go at the front */
1089
prev_blkrec = agg_recptr->dup_alloc_lst;
1090
this_blkrec = agg_recptr->dup_alloc_lst->next;
1091
while ( !dib_done ) {
1092
if ( this_blkrec == NULL ) { /* goes at the end */
1093
new_blkrec->next = NULL;
1094
prev_blkrec->next = new_blkrec;
1096
} else if ( this_blkrec->blk_number > block_num ) {
1098
* goes in front of this one
1100
new_blkrec->next = this_blkrec;
1101
prev_blkrec->next = new_blkrec;
1103
} else { /* try the next one */
1104
prev_blkrec = this_blkrec;
1105
this_blkrec = this_blkrec->next;
1106
} /* end try the next one */
1108
} /* end else doesn't go at the front */
1109
} /* end list not empty */
1110
} /* end got a block record */
1113
} /* end dupall_insert_blkrec() */
930
struct dupall_blkrec *new_blkrec;
931
struct dupall_blkrec *prev_blkrec;
932
struct dupall_blkrec *this_blkrec;
935
new_blkrec = dupall_get_blkrec();
937
if (new_blkrec == NULL)
938
return FSCK_FAILED_DYNSTG_EXHAUST1;
941
*blkrec = new_blkrec;
943
/* got a block record */
944
new_blkrec->first_blk = first_block;
945
new_blkrec->last_blk = last_block;
946
new_blkrec->owner_count = 2;
948
if (agg_recptr->dup_alloc_lst == NULL) {
950
new_blkrec->next = NULL;
951
new_blkrec->prev = NULL;
952
agg_recptr->dup_alloc_lst = new_blkrec;
958
if (agg_recptr->dup_alloc_lst->first_blk > first_block) {
962
new_blkrec->next = agg_recptr->dup_alloc_lst;
963
new_blkrec->prev = NULL;
964
agg_recptr->dup_alloc_lst = new_blkrec;
969
/* doesn't go at the front */
970
prev_blkrec = agg_recptr->dup_alloc_lst;
971
this_blkrec = agg_recptr->dup_alloc_lst->next;
973
if (this_blkrec == NULL) {
974
/* goes at the end */
975
new_blkrec->next = NULL;
976
new_blkrec->prev = prev_blkrec;
977
prev_blkrec->next = new_blkrec;
979
} else if (this_blkrec->first_blk > first_block) {
981
* goes in front of this one
983
new_blkrec->next = this_blkrec;
984
new_blkrec->prev = prev_blkrec;
985
prev_blkrec->next = new_blkrec;
986
this_blkrec->prev = new_blkrec;
989
/* try the next one */
990
prev_blkrec = this_blkrec;
991
this_blkrec = this_blkrec->next;
1116
997
/****************************************************************************
1117
998
* NAME: establish_agg_workspace
1127
1008
* success: FSCK_OK
1128
1009
* failure: something else
1130
retcode_t establish_agg_workspace ( )
1011
int establish_agg_workspace()
1132
retcode_t eaw_rc = FSCK_OK;
1133
reg_idx_t mapsize_bytes;
1134
int I_am_logredo = 0;
1137
* establish the fsck workspace block map
1139
eaw_rc = establish_wsp_block_map( );
1141
if ( eaw_rc == FSCK_OK ) { /* block map has been established */
1142
agg_recptr->agg_imap.num_iags = 1;
1143
agg_recptr->agg_imap.bkd_inodes = INOSPEREXT;
1144
agg_recptr->agg_imap.unused_bkd_inodes = INOSPEREXT - 4;
1145
agg_recptr->inode_count = INOSPEREXT; /* in release 1 there is always
1146
* exactly one extent of inodes allocated
1150
* now establish the fsck aggregate imap workspace
1152
mapsize_bytes = agg_recptr->agg_imap.num_iags *
1153
sizeof(struct fsck_iag_record);
1154
eaw_rc = alloc_wrksp( mapsize_bytes, dynstg_agg_iagtbl,
1156
(void **) &(agg_recptr->agg_imap.iag_tbl) );
1157
if ( eaw_rc == FSCK_OK ) { /* AIM workspace established */
1159
* now establish the fsck aggregate inode table workspace
1161
* (since there is always exactly one inode extent, we don't
1162
* bother with an IAG table of pointers to extent address tables
1163
* or with an extent address table of pointers to inode record
1166
eaw_rc = alloc_wrksp( inode_tbl_length, dynstg_ait_inotbl,
1168
(void **) &(agg_recptr->AIT_ext0_tbl) );
1169
memcpy( (void *) &(agg_recptr->AIT_ext0_tbl->eyecatcher),
1170
(void *) "InodeTbl", 8 );
1171
} /* end AIM workspace established */
1172
} /* end block map has been established */
1175
} /* end establish_agg_workspace */
1013
int eaw_rc = FSCK_OK;
1014
uint32_t mapsize_bytes;
1015
int I_am_logredo = 0;
1018
* establish the fsck workspace block map
1020
eaw_rc = establish_wsp_block_map();
1022
if (eaw_rc == FSCK_OK) {
1023
/* block map has been established */
1024
agg_recptr->agg_imap.num_iags = 1;
1025
agg_recptr->agg_imap.bkd_inodes = INOSPEREXT;
1026
agg_recptr->agg_imap.unused_bkd_inodes = INOSPEREXT - 4;
1027
/* in release 1 there is always
1028
* exactly one extent of inodes allocated
1031
agg_recptr->inode_count = INOSPEREXT;
1033
* now establish the fsck aggregate imap workspace
1036
agg_recptr->agg_imap.num_iags *
1037
sizeof (struct fsck_iag_record);
1039
alloc_wrksp(mapsize_bytes, dynstg_agg_iagtbl, I_am_logredo,
1040
(void **) &(agg_recptr->agg_imap.iag_tbl));
1041
if (eaw_rc == FSCK_OK) {
1042
/* AIM workspace established */
1044
* now establish the fsck aggregate inode table workspace
1046
* (since there is always exactly one inode extent, we don't
1047
* bother with an IAG table of pointers to extent address tables
1048
* or with an extent address table of pointers to inode record
1052
alloc_wrksp(inode_tbl_length, dynstg_ait_inotbl,
1054
(void **) &(agg_recptr->AIT_ext0_tbl));
1055
memcpy((void *) &(agg_recptr->AIT_ext0_tbl->eyecatcher),
1056
(void *) "InodeTbl", 8);
1178
1062
/****************************************************************************
1179
1063
* NAME: establish_ea_iobuf
1222
1105
* success: FSCK_OK
1223
1106
* failure: something else
1225
retcode_t establish_fs_workspace ( )
1108
int establish_fs_workspace()
1227
retcode_t efsw_rc = FSCK_OK;
1228
reg_idx_t mapsize_bytes;
1229
reg_idx_t buffer_size;
1230
int aggregate_inode, which_ait = 0;
1233
int I_am_logredo = 0;
1235
inoext_tblptr inoexttbl;
1239
* allocate a buffer in which path names can be constructed
1241
buffer_size = (JFS_PATH_MAX + 2) * sizeof( char );
1242
efsw_rc = alloc_wrksp( buffer_size, dynstg_fsit_map,
1244
(void **) &(agg_recptr->path_buffer) );
1246
if ( efsw_rc == FSCK_OK ) { /* got it */
1247
agg_recptr->path_buffer_length = buffer_size;
1249
* Figure out how many IAGs have been allocated for the fileset.
1250
* (Note that in release 1 there is always exactly 1 fileset in the
1253
* At this point the aggregate inode describing the fileset has been
1254
* validated. The data described by that inode is 1 page of control
1255
* information plus some number of IAGs. di_size is the number of
1256
* bytes allocated for that data.
1258
if ( agg_recptr->primary_ait_4part2 ) {
1259
which_ait = fsck_primary;
1260
efsw_rc = ait_special_read_ext1( fsck_primary );
1261
if ( efsw_rc != FSCK_OK ) { /* read failed */
1262
report_readait_error( efsw_rc,
1263
FSCK_FAILED_CANTREADAITEXTC,
1265
efsw_rc = FSCK_FAILED_CANTREADAITEXTC;
1266
} /* end read failed */
1268
which_ait = fsck_secondary;
1269
efsw_rc = ait_special_read_ext1( fsck_secondary );
1270
if ( efsw_rc != FSCK_OK ) { /* read failed */
1271
report_readait_error( efsw_rc,
1272
FSCK_FAILED_CANTREADAITEXTD,
1274
efsw_rc = FSCK_FAILED_CANTREADAITEXTD;
1275
} /* end read failed */
1279
if ( efsw_rc == FSCK_OK ) { /* got the first AIT extent */
1280
aggregate_inode = -1;
1281
inoidx = FILESYSTEM_I;
1282
efsw_rc = inode_get( aggregate_inode, which_ait, inoidx, &inoptr );
1284
if ( efsw_rc == FSCK_OK ) { /* got the fileset IT inode */
1285
agg_recptr->fset_imap.num_iags = (inoptr->di_size/SIZE_OF_MAP_PAGE) - 1;
1286
agg_recptr->fset_inode_count = agg_recptr->fset_imap.num_iags * INOSPERIAG; /*
1287
* a high estimate of the inodes
1288
* allocated for the fileset
1291
* now establish the fsck fileset imap workspace
1293
if (efsw_rc == FSCK_OK ) { /* inode map established */
1294
mapsize_bytes = agg_recptr->fset_imap.num_iags *
1295
sizeof(struct fsck_iag_record);
1296
efsw_rc = alloc_wrksp( mapsize_bytes, dynstg_agg_iagtbl,
1298
(void **) &(agg_recptr->fset_imap.iag_tbl) );
1299
if ( efsw_rc == FSCK_OK ) { /* inode map workspace allocated */
1301
* now establish the fsck fileset imap workspace
1303
* We start out knowing that IAG 0, extent 0 is allocated and
1304
* has an inode in use. We'll allocate enough to cover that.
1307
agg_recptr->fset_imap.num_iags * sizeof(inoext_tblptr);
1308
efsw_rc = alloc_wrksp( mapsize_bytes, dynstg_fsit_iagtbl,
1309
I_am_logredo, (void **) &IAGtbl );
1310
if ( efsw_rc == FSCK_OK ) { /* we got the IAG table */
1311
memcpy( (void *) &(IAGtbl->eyecatcher), (void *) "FSAITIAG", 8 );
1312
agg_recptr->FSIT_IAG_tbl = IAGtbl;
1314
efsw_rc = alloc_wrksp( inode_ext_tbl_length, dynstg_fsit_inoexttbl,
1315
I_am_logredo, (void **) &inoexttbl );
1316
if ( efsw_rc == FSCK_OK ) { /* we got the inode extent table */
1317
memcpy( (void *) &(inoexttbl->eyecatcher), (void *) "FSAITEXT", 8 );
1318
IAGtbl->inoext_tbl[0] = inoexttbl;
1319
efsw_rc = alloc_wrksp( inode_tbl_length, dynstg_fsit_inotbl,
1320
I_am_logredo, (void **) &inotbl );
1321
if ( efsw_rc == FSCK_OK ) { /* we got the inode table */
1322
memcpy( (void *) &(inotbl->eyecatcher), (void *) "FSAITINO", 8 );
1323
inoexttbl->inotbl[0] = inotbl;
1324
} /* end we got the inode table */
1325
} /* end we got the inode extent table */
1326
} /* end we got the IAG table */
1327
} /* end inode map workspace allocated */
1328
} /* end inode map established */
1329
} /* end got the fileset IT inode */
1330
} /* end got the first AIT extent */
1333
} /* end establish_fs_workspace */
1110
int efsw_rc = FSCK_OK;
1111
uint32_t mapsize_bytes;
1112
uint32_t buffer_size;
1113
int aggregate_inode, which_ait = 0;
1115
struct dinode *inoptr;
1116
int I_am_logredo = 0;
1117
struct IAG_tbl_t *IAGtbl;
1118
struct inode_ext_tbl_t *inoexttbl;
1119
struct inode_tbl_t *inotbl;
1122
* allocate a buffer in which path names can be constructed
1124
buffer_size = (JFS_PATH_MAX + 2) * sizeof (char);
1125
efsw_rc = alloc_wrksp(buffer_size, dynstg_fsit_map,
1127
(void **) &(agg_recptr->path_buffer));
1129
if (efsw_rc == FSCK_OK) {
1131
agg_recptr->path_buffer_length = buffer_size;
1133
* Figure out how many IAGs have been allocated for the fileset.
1134
* (Note that in release 1 there is always exactly 1 fileset in the
1137
* At this point the aggregate inode describing the fileset has been
1138
* validated. The data described by that inode is 1 page of control
1139
* information plus some number of IAGs. di_size is the number of
1140
* bytes allocated for that data.
1142
if (agg_recptr->primary_ait_4part2) {
1143
which_ait = fsck_primary;
1144
efsw_rc = ait_special_read_ext1(fsck_primary);
1145
if (efsw_rc != FSCK_OK) {
1147
report_readait_error(efsw_rc,
1148
FSCK_FAILED_CANTREADAITEXTC,
1150
efsw_rc = FSCK_FAILED_CANTREADAITEXTC;
1153
which_ait = fsck_secondary;
1154
efsw_rc = ait_special_read_ext1(fsck_secondary);
1155
if (efsw_rc != FSCK_OK) {
1157
report_readait_error(efsw_rc,
1158
FSCK_FAILED_CANTREADAITEXTD,
1160
efsw_rc = FSCK_FAILED_CANTREADAITEXTD;
1164
if (efsw_rc != FSCK_OK)
1167
/* got the first AIT extent */
1168
aggregate_inode = -1;
1169
inoidx = FILESYSTEM_I;
1170
efsw_rc = inode_get(aggregate_inode, which_ait, inoidx, &inoptr);
1172
if (efsw_rc != FSCK_OK)
1175
/* got the fileset IT inode */
1176
agg_recptr->fset_imap.num_iags =
1177
(inoptr->di_size / SIZE_OF_MAP_PAGE) - 1;
1179
* a high estimate of the inodes
1180
* allocated for the fileset
1182
agg_recptr->fset_inode_count =
1183
agg_recptr->fset_imap.num_iags * INOSPERIAG;
1185
* now establish the fsck fileset imap workspace
1187
if (efsw_rc != FSCK_OK)
1190
/* inode map established */
1191
mapsize_bytes = agg_recptr->fset_imap.num_iags *
1192
sizeof (struct fsck_iag_record);
1193
efsw_rc = alloc_wrksp(mapsize_bytes, dynstg_agg_iagtbl, I_am_logredo,
1194
(void **) &(agg_recptr->fset_imap.iag_tbl));
1195
if (efsw_rc != FSCK_OK)
1198
/* inode map workspace allocated */
1200
* now establish the fsck fileset imap workspace
1202
* We start out knowing that IAG 0, extent 0 is allocated and
1203
* has an inode in use. We'll allocate enough to cover that.
1205
mapsize_bytes = 8 + agg_recptr->fset_imap.num_iags *
1206
sizeof (struct inode_ext_tbl_t *);
1207
efsw_rc = alloc_wrksp(mapsize_bytes, dynstg_fsit_iagtbl,
1208
I_am_logredo, (void **) &IAGtbl);
1209
if (efsw_rc != FSCK_OK)
1212
/* we got the IAG table */
1213
memcpy((void *)&(IAGtbl->eyecatcher), (void *) "FSAITIAG", 8);
1214
agg_recptr->FSIT_IAG_tbl = IAGtbl;
1215
efsw_rc = alloc_wrksp(inode_ext_tbl_length, dynstg_fsit_inoexttbl,
1216
I_am_logredo, (void **) &inoexttbl);
1217
if (efsw_rc != FSCK_OK)
1220
/* we got the inode extent table */
1221
memcpy((void *)&(inoexttbl->eyecatcher), (void *)"FSAITEXT", 8);
1222
IAGtbl->inoext_tbl[0] = inoexttbl;
1223
efsw_rc = alloc_wrksp(inode_tbl_length, dynstg_fsit_inotbl,
1224
I_am_logredo, (void **) &inotbl);
1225
if (efsw_rc == FSCK_OK) {
1226
/* we got the inode table */
1227
memcpy((void *)&(inotbl->eyecatcher), (void *)"FSAITINO", 8);
1228
inoexttbl->inotbl[0] = inotbl;
1336
1235
/****************************************************************************
1337
1236
* NAME: establish_io_buffers
1346
1245
* success: FSCK_OK
1347
1246
* failure: something else
1349
retcode_t establish_io_buffers ( )
1248
int establish_io_buffers()
1351
retcode_t eiob_rc = FSCK_OK;
1352
int I_am_logredo = 0;
1354
eiob_rc = alloc_wrksp( IAG_IO_BUFSIZE, dynstg_iobufs,
1356
(void **) &(agg_recptr->iag_buf_ptr) );
1357
if ( eiob_rc == FSCK_OK ) { /* successful IAG allocation */
1358
agg_recptr->iag_buf_length = sizeof(iag_t);
1359
agg_recptr->iag_buf_data_len = 0;
1360
agg_recptr->iag_agg_offset = 0;
1361
agg_recptr->iag_buf_write = 0;
1362
agg_recptr->bmapdm_buf_ptr = agg_recptr->iag_buf_ptr;
1363
agg_recptr->bmapdm_buf_length = IAG_IO_BUFSIZE;
1364
agg_recptr->bmapdm_buf_data_len = 0;
1365
agg_recptr->bmapdm_agg_offset = 0;
1366
agg_recptr->bmapdm_buf_write = 0;
1367
} /* end successful IAG allocation */
1369
if ( eiob_rc == FSCK_OK ) { /* successful IAG allocation */
1370
eiob_rc = alloc_wrksp( INODE_IO_BUFSIZE, dynstg_iobufs,
1372
(void **) &(agg_recptr->ino_buf_ptr) );
1373
} /* end successful ea buffer allocation */
1375
if ( eiob_rc == FSCK_OK ) { /* successful inode allocation */
1376
agg_recptr->ino_buf_length = INODE_IO_BUFSIZE;
1377
agg_recptr->ino_buf_data_len = 0;
1378
agg_recptr->ino_buf_agg_offset = 0;
1379
agg_recptr->ino_buf_write = 0;
1381
eiob_rc = alloc_wrksp( NODE_IO_BUFSIZE, dynstg_iobufs,
1383
(void **) &(agg_recptr->node_buf_ptr) );
1384
} /* end successful inode allocation */
1386
if ( eiob_rc == FSCK_OK ) { /* successful node allocation */
1387
agg_recptr->node_buf_length = NODE_IO_BUFSIZE;
1388
agg_recptr->node_buf_data_len = 0;
1389
agg_recptr->node_agg_offset = 0;
1390
agg_recptr->node_buf_write = 0;
1392
eiob_rc = alloc_wrksp( MAPLEAF_IO_BUFSIZE, dynstg_iobufs,
1394
(void **) &(agg_recptr->mapleaf_buf_ptr) );
1395
} /* end successful node allocation */
1397
if ( eiob_rc == FSCK_OK ) { /* successful mapleaf allocation */
1398
agg_recptr->mapleaf_buf_length = MAPLEAF_IO_BUFSIZE;
1399
agg_recptr->mapleaf_buf_data_len = 0;
1400
agg_recptr->mapleaf_agg_offset = 0;
1401
agg_recptr->mapleaf_buf_write = 0;
1403
eiob_rc = alloc_wrksp( MAPCTL_IO_BUFSIZE, dynstg_iobufs,
1405
(void **) &(agg_recptr->mapctl_buf_ptr) );
1406
} /* end successful mapleaf allocation */
1408
if ( eiob_rc == FSCK_OK ) { /* successful map control allocation */
1409
agg_recptr->mapctl_buf_length = MAPCTL_IO_BUFSIZE;
1410
agg_recptr->mapctl_buf_data_len = 0;
1411
agg_recptr->mapctl_agg_offset = 0;
1412
agg_recptr->mapctl_buf_write = 0;
1413
eiob_rc = alloc_wrksp( BMAPLV_IO_BUFSIZE, dynstg_iobufs,
1415
(void **) &(agg_recptr->bmaplv_buf_ptr) );
1416
} /* end successful map control allocation */
1418
if ( eiob_rc == FSCK_OK ) { /* successful map level allocation */
1419
agg_recptr->bmaplv_buf_length = BMAPLV_IO_BUFSIZE;
1420
agg_recptr->bmaplv_buf_data_len = 0;
1421
agg_recptr->bmaplv_agg_offset = 0;
1422
agg_recptr->bmaplv_buf_write = 0;
1423
} /* successful map level allocation */
1426
} /* end establish_io_buffers ( ) */
1250
int eiob_rc = FSCK_OK;
1251
int I_am_logredo = 0;
1253
eiob_rc = alloc_wrksp(IAG_IO_BUFSIZE, dynstg_iobufs,
1255
(void **) &(agg_recptr->iag_buf_ptr));
1256
if (eiob_rc == FSCK_OK) {
1257
/* successful IAG allocation */
1258
agg_recptr->iag_buf_length = sizeof (struct iag);
1259
agg_recptr->iag_buf_data_len = 0;
1260
agg_recptr->iag_agg_offset = 0;
1261
agg_recptr->iag_buf_write = 0;
1262
agg_recptr->bmapdm_buf_ptr = agg_recptr->iag_buf_ptr;
1263
agg_recptr->bmapdm_buf_length = IAG_IO_BUFSIZE;
1264
agg_recptr->bmapdm_buf_data_len = 0;
1265
agg_recptr->bmapdm_agg_offset = 0;
1266
agg_recptr->bmapdm_buf_write = 0;
1268
if (eiob_rc == FSCK_OK) {
1269
/* successful IAG allocation */
1270
eiob_rc = alloc_wrksp(INODE_IO_BUFSIZE, dynstg_iobufs,
1272
(void **) &(agg_recptr->ino_buf_ptr));
1274
if (eiob_rc == FSCK_OK) {
1275
/* successful inode allocation */
1276
agg_recptr->ino_buf_length = INODE_IO_BUFSIZE;
1277
agg_recptr->ino_buf_data_len = 0;
1278
agg_recptr->ino_buf_agg_offset = 0;
1279
agg_recptr->ino_buf_write = 0;
1281
eiob_rc = alloc_wrksp(NODE_IO_BUFSIZE, dynstg_iobufs,
1283
(void **) &(agg_recptr->node_buf_ptr));
1285
if (eiob_rc == FSCK_OK) {
1286
/* successful node allocation */
1287
agg_recptr->node_buf_length = NODE_IO_BUFSIZE;
1288
agg_recptr->node_buf_data_len = 0;
1289
agg_recptr->node_agg_offset = 0;
1290
agg_recptr->node_buf_write = 0;
1292
eiob_rc = alloc_wrksp(NODE_IO_BUFSIZE, dynstg_iobufs,
1294
(void **) &(agg_recptr->dnode_buf_ptr));
1296
if (eiob_rc == FSCK_OK) {
1297
/* successful dnode allocation */
1298
agg_recptr->dnode_buf_length = NODE_IO_BUFSIZE;
1299
agg_recptr->dnode_buf_data_len = 0;
1300
agg_recptr->dnode_agg_offset = 0;
1301
agg_recptr->dnode_buf_write = 0;
1303
eiob_rc = alloc_wrksp(MAPLEAF_IO_BUFSIZE, dynstg_iobufs,
1305
(void **) &(agg_recptr->mapleaf_buf_ptr));
1307
if (eiob_rc == FSCK_OK) {
1308
/* successful mapleaf allocation */
1309
agg_recptr->mapleaf_buf_length = MAPLEAF_IO_BUFSIZE;
1310
agg_recptr->mapleaf_buf_data_len = 0;
1311
agg_recptr->mapleaf_agg_offset = 0;
1312
agg_recptr->mapleaf_buf_write = 0;
1314
eiob_rc = alloc_wrksp(MAPCTL_IO_BUFSIZE, dynstg_iobufs,
1316
(void **) &(agg_recptr->mapctl_buf_ptr));
1318
if (eiob_rc == FSCK_OK) {
1319
/* successful map control allocation */
1320
agg_recptr->mapctl_buf_length = MAPCTL_IO_BUFSIZE;
1321
agg_recptr->mapctl_buf_data_len = 0;
1322
agg_recptr->mapctl_agg_offset = 0;
1323
agg_recptr->mapctl_buf_write = 0;
1324
eiob_rc = alloc_wrksp(BMAPLV_IO_BUFSIZE, dynstg_iobufs,
1326
(void **) &(agg_recptr->bmaplv_buf_ptr));
1328
if (eiob_rc == FSCK_OK) {
1329
/* successful map level allocation */
1330
agg_recptr->bmaplv_buf_length = BMAPLV_IO_BUFSIZE;
1331
agg_recptr->bmaplv_buf_data_len = 0;
1332
agg_recptr->bmaplv_agg_offset = 0;
1333
agg_recptr->bmaplv_buf_write = 0;
1429
1338
/****************************************************************************
1430
1339
* NAME: establish_wsp_block_map
1448
1357
* success: FSCK_OK
1449
1358
* failure: something else
1451
retcode_t establish_wsp_block_map ( )
1360
int establish_wsp_block_map()
1453
retcode_t ewbm_rc = FSCK_OK;
1454
int32_t blkmap_size_bytes;
1455
int32_t blkmap_size_in_pages;
1457
fsblkidx_t this_device_offset;
1459
int I_am_logredo = 0;
1461
ewbm_rc = establish_wsp_block_map_ctl();
1463
if ( ewbm_rc == FSCK_OK ) { /* allocated and initialized blk map ctl page */
1464
blkmap_size_bytes = agg_recptr->ondev_wsp_byte_length;
1465
agg_recptr->blkmp_pagecount = blkmap_size_bytes / BYTESPERPAGE;
1466
agg_recptr->blkmp_agg_offset = agg_recptr->ondev_wsp_byte_offset +
1468
* whether or not we actually write
1469
* to the on-disk fsck workspace,
1470
* this buffer represents it logically.
1472
agg_recptr->blkmp_blkmp_offset = 0;
1473
agg_recptr->blkmp_buf_data_len = 0;
1474
agg_recptr->blkmp_buf_write = 0;
1475
agg_recptr->blkmp_blkmp_offset = 0;
1476
agg_recptr->blkmp_buf_data_len = 0;
1477
agg_recptr->blkmp_buf_write = 0;
1479
if ( agg_recptr->processing_readonly ) { /* can't touch the aggregate */
1480
ewbm_rc = alloc_wrksp( blkmap_size_bytes, dynstg_blkmap,
1482
(void **) &(agg_recptr->blkmp_buf_ptr) );
1483
if ( ewbm_rc == FSCK_OK ) { /* allocated and initialized block map */
1484
wsp_dynstg_object = 0;
1485
wsp_dynstg_action = 0;
1486
agg_recptr->blkmp_buf_length = blkmap_size_bytes;
1487
agg_recptr->blkmp_buf_data_len = agg_recptr->blkmp_buf_length;
1488
} /* end allocated and initialized block map */
1489
} else { /* use storage reserved for fsck in the aggregate */
1490
ewbm_rc = alloc_wrksp( BLKMP_IO_BUFSIZE, dynstg_blkmap_buf,
1492
(void **) &(agg_recptr->blkmp_buf_ptr) );
1493
if ( ewbm_rc == FSCK_OK ) { /* allocated and initialized block map */
1494
agg_recptr->blkmp_buf_length = BLKMP_IO_BUFSIZE;
1495
agg_recptr->blkmp_buf_data_len = agg_recptr->blkmp_buf_length;
1496
ewbm_rc = blkmap_put_ctl_page( agg_recptr->blkmp_ctlptr );
1497
if ( ewbm_rc == FSCK_OK ) { /* successful write to Block Map Control Page */
1498
blkmap_size_in_pages = blkmap_size_bytes / BYTESPERPAGE; /* this
1499
* is guaranteed (by mkfs) to be an even
1503
((idx < blkmap_size_in_pages) && (ewbm_rc == FSCK_OK) );
1504
idx++ ) { /* for each map page (after the control page) */
1506
this_device_offset = agg_recptr->ondev_wsp_byte_offset +
1509
/* swap if on big endian machine */
1510
if (type_jfs & JFS_SWAP_BYTES) {
1511
memcpy( swap_buf_ptr, agg_recptr->blkmp_buf_ptr, BYTESPERPAGE);
1512
ujfs_swap_fsck_blk_map_page( (fsck_blk_map_page_t *) swap_buf_ptr );
1513
ewbm_rc = ujfs_rw_diskblocks( Dev_IOPort,
1518
* write the initialized buffer page to
1519
* the map page on disk
1523
ewbm_rc = ujfs_rw_diskblocks( Dev_IOPort,
1526
(void *) agg_recptr->blkmp_buf_ptr,
1528
* write the initialized buffer page to
1529
* the map page on disk
1532
if ( ewbm_rc != FSCK_OK ) { /* I/O failure */
1536
msgprms[0] = message_parm_0;
1537
msgprmidx[0] = fsck_metadata;
1538
msgprms[1] = Vol_Label;
1540
sprintf( message_parm_2, "%d", 1 );
1541
msgprms[2] = message_parm_2;
1543
fsck_send_msg( fsck_URCVWRT, 0, 3 );
1545
* message to debugger
1547
sprintf( message_parm_0, "%d", ewbm_rc );
1548
msgprms[0] = message_parm_0;
1550
msgprms[1] = msgprms[0];
1551
msgprmidx[1] = msgprmidx[0];
1552
sprintf( message_parm_2, "%d", fsck_WRITE );
1553
msgprms[2] = message_parm_2;
1555
sprintf( message_parm_3, "%lld", (long long)this_device_offset );
1556
msgprms[3] = message_parm_3;
1558
sprintf( message_parm_4, "%d", BYTESPERPAGE );
1559
msgprms[4] = message_parm_4;
1561
sprintf( message_parm_5, "%d", -1 );
1562
msgprms[5] = message_parm_5;
1564
fsck_send_msg( fsck_ERRONWSP, 0, 6 );
1565
} /* end I/O failure */
1566
} /* end for each map page */
1567
} /* end successful write to Block Map Control Page */
1568
} /* end allocated and initialized block map */
1569
} /* end else use storage reserved for fsck in the aggregate */
1570
} /* end allocated and initialized blk map ctl page */
1573
} /* end establish_wsp_block_map ( ) */
1362
int ewbm_rc = FSCK_OK;
1363
int32_t blkmap_size_bytes;
1364
int32_t blkmap_size_in_pages;
1366
int64_t this_device_offset;
1368
int I_am_logredo = 0;
1370
ewbm_rc = establish_wsp_block_map_ctl();
1372
if (ewbm_rc != FSCK_OK)
1375
/* allocated and initialized blk map ctl page */
1376
blkmap_size_bytes = agg_recptr->ondev_wsp_byte_length;
1377
agg_recptr->blkmp_pagecount = blkmap_size_bytes / BYTESPERPAGE;
1379
* whether or not we actually write to the on-disk
1380
* fsck workspace, this buffer represents it logically.
1382
agg_recptr->blkmp_agg_offset =
1383
agg_recptr->ondev_wsp_byte_offset + BYTESPERPAGE;
1384
agg_recptr->blkmp_blkmp_offset = 0;
1385
agg_recptr->blkmp_buf_data_len = 0;
1386
agg_recptr->blkmp_buf_write = 0;
1387
agg_recptr->blkmp_blkmp_offset = 0;
1388
agg_recptr->blkmp_buf_data_len = 0;
1389
agg_recptr->blkmp_buf_write = 0;
1391
if (agg_recptr->processing_readonly) {
1392
/* can't touch the aggregate */
1393
ewbm_rc = alloc_wrksp(blkmap_size_bytes, dynstg_blkmap,
1395
(void **) &(agg_recptr->blkmp_buf_ptr));
1396
if (ewbm_rc == FSCK_OK) {
1397
/* allocated and initialized block map */
1398
wsp_dynstg_object = 0;
1399
wsp_dynstg_action = 0;
1400
agg_recptr->blkmp_buf_length = blkmap_size_bytes;
1401
agg_recptr->blkmp_buf_data_len =
1402
agg_recptr->blkmp_buf_length;
1406
/* use storage reserved for fsck in the aggregate */
1407
ewbm_rc = alloc_wrksp(BLKMP_IO_BUFSIZE, dynstg_blkmap_buf, I_am_logredo,
1408
(void **) &(agg_recptr->blkmp_buf_ptr));
1409
if (ewbm_rc != FSCK_OK)
1412
/* allocated and initialized block map */
1413
agg_recptr->blkmp_buf_length = BLKMP_IO_BUFSIZE;
1414
agg_recptr->blkmp_buf_data_len = agg_recptr->blkmp_buf_length;
1415
ewbm_rc = blkmap_put_ctl_page(agg_recptr->blkmp_ctlptr);
1416
if (ewbm_rc != FSCK_OK)
1419
/* successful write to Block Map Control Page */
1420
/* this is guaranteed (by mkfs) to be an even number */
1421
blkmap_size_in_pages = blkmap_size_bytes / BYTESPERPAGE;
1422
/* Swap to little-endian */
1423
ujfs_swap_fsck_blk_map_page(agg_recptr->blkmp_buf_ptr);
1424
for (idx = 1; ((idx < blkmap_size_in_pages) &&
1425
(ewbm_rc == FSCK_OK)); idx++) {
1426
/* for each map page (after the control page) */
1427
this_device_offset = agg_recptr->ondev_wsp_byte_offset +
1428
(idx * BYTESPERPAGE);
1430
* write the initialized buffer page to
1431
* the map page on disk
1433
ewbm_rc = ujfs_rw_diskblocks(Dev_IOPort, this_device_offset,
1435
(void *) agg_recptr->blkmp_buf_ptr, PUT);
1436
if (ewbm_rc != FSCK_OK) {
1441
fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),
1444
* message to debugger
1446
fsck_send_msg(fsck_ERRONWSP, ewbm_rc, ewbm_rc, fsck_WRITE,
1447
(long long)this_device_offset,
1451
/* Swap back to cpu-endian */
1452
ujfs_swap_fsck_blk_map_page(agg_recptr->blkmp_buf_ptr);
1576
1458
/****************************************************************************
1577
1459
* NAME: establish_wsp_block_map_ctl
1596
1478
* success: FSCK_OK
1597
1479
* failure: something else
1599
retcode_t establish_wsp_block_map_ctl ( )
1481
int establish_wsp_block_map_ctl()
1601
retcode_t ewbmc_rc = FSCK_OK;
1602
time_t Current_Time;
1603
fsblkidx_t this_device_offset = 0;
1604
int I_am_logredo = 0;
1606
ewbmc_rc = alloc_wrksp( sizeof(fsck_blk_map_hdr_t), dynstg_blkmap_hdr,
1608
(void **) &(agg_recptr->blkmp_ctlptr) );
1610
if ( ewbmc_rc == FSCK_OK ) { /* allocated and initialized blk map ctl page */
1611
strncpy( agg_recptr->blkmp_ctlptr->hdr.eyecatcher, fbmh_eyecatcher_string,
1612
strlen(fbmh_eyecatcher_string)); /* fill eyecatcher */
1613
agg_recptr->blkmp_ctlptr->hdr.super_buff_addr = (char *) sb_ptr;
1614
agg_recptr->blkmp_ctlptr->hdr.agg_record_addr = (char *) agg_recptr;
1615
agg_recptr->blkmp_ctlptr->hdr.bmap_record_addr = (char *) bmap_recptr;
1616
agg_recptr->blkmp_ctlptr->hdr.fscklog_full = agg_recptr->fscklog_full;
1617
agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_allocated =
1618
agg_recptr->fscklog_buf_allocated;
1619
agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_alloc_err =
1620
agg_recptr->fscklog_buf_alloc_err;
1621
agg_recptr->blkmp_ctlptr->hdr.fscklog_agg_offset =
1622
agg_recptr->ondev_fscklog_byte_offset;
1624
Current_Time = time(NULL);
1625
fsck_DateTime = localtime( &Current_Time );
1626
if ( fsck_DateTime->tm_year > 2000 ) {
1627
sprintf( &(agg_recptr->blkmp_ctlptr->hdr.start_time[0]), "%d/%d/%d%d.%d.%d",
1628
fsck_DateTime->tm_mon + 1, fsck_DateTime->tm_mday, ((fsck_DateTime->tm_year + 1900)%2000),
1629
fsck_DateTime->tm_hour, fsck_DateTime->tm_min, fsck_DateTime->tm_sec );
1631
sprintf( &(agg_recptr->blkmp_ctlptr->hdr.start_time[0]), "%d/%d/%d%d.%d.%d",
1632
fsck_DateTime->tm_mon + 1, fsck_DateTime->tm_mday, ((fsck_DateTime->tm_year + 1900)%1900),
1633
fsck_DateTime->tm_hour, fsck_DateTime->tm_min, fsck_DateTime->tm_sec );
1636
if ( !(agg_recptr->processing_readonly) ) {
1638
* use storage reserved for fsck in the
1641
ewbmc_rc = blkmap_put_ctl_page( agg_recptr->blkmp_ctlptr );
1642
if ( ewbmc_rc != FSCK_OK ) { /* I/O failure */
1646
msgprms[0] = message_parm_0;
1647
msgprmidx[0] = fsck_metadata;
1648
msgprms[1] = Vol_Label;
1650
sprintf( message_parm_2, "%d", 1 );
1651
msgprms[2] = message_parm_2;
1653
fsck_send_msg( fsck_URCVWRT, 0, 3 );
1655
* message to debugger
1657
sprintf( message_parm_0, "%d", ewbmc_rc );
1658
msgprms[0] = message_parm_0;
1660
msgprms[1] = msgprms[0];
1661
msgprmidx[1] = msgprmidx[0];
1662
sprintf( message_parm_2, "%d", fsck_WRITE );
1663
msgprms[2] = message_parm_2;
1665
sprintf( message_parm_3, "%lld", (long long)this_device_offset );
1666
msgprms[3] = message_parm_3;
1668
sprintf( message_parm_4, "%d", BYTESPERPAGE );
1669
msgprms[4] = message_parm_4;
1671
sprintf( message_parm_5, "%d", -1 );
1672
msgprms[5] = message_parm_5;
1674
fsck_send_msg( fsck_ERRONWSP, 0, 6 );
1675
} /* end I/O failure */
1676
} /* end else use storage reserved for fsck in the aggregate */
1677
} /* end allocated and initialized blk map ctl page */
1680
} /* end establish_wsp_block_map_ctl ( ) */
1483
int ewbmc_rc = FSCK_OK;
1484
time_t Current_Time;
1485
int64_t this_device_offset = 0;
1486
int I_am_logredo = 0;
1489
alloc_wrksp(sizeof (struct fsck_blk_map_hdr), dynstg_blkmap_hdr,
1490
I_am_logredo, (void **) &(agg_recptr->blkmp_ctlptr));
1492
if (ewbmc_rc == FSCK_OK) {
1493
/* allocated and initialized blk map ctl page */
1494
/* fill eyecatcher */
1495
strncpy(agg_recptr->blkmp_ctlptr->hdr.eyecatcher,
1496
fbmh_eyecatcher_string, strlen(fbmh_eyecatcher_string));
1497
agg_recptr->blkmp_ctlptr->hdr.super_buff_addr = (char *) sb_ptr;
1498
agg_recptr->blkmp_ctlptr->hdr.agg_record_addr =
1499
(char *) agg_recptr;
1500
agg_recptr->blkmp_ctlptr->hdr.bmap_record_addr =
1501
(char *) bmap_recptr;
1502
agg_recptr->blkmp_ctlptr->hdr.fscklog_full =
1503
agg_recptr->fscklog_full;
1504
agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_allocated =
1505
agg_recptr->fscklog_buf_allocated;
1506
agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_alloc_err =
1507
agg_recptr->fscklog_buf_alloc_err;
1508
agg_recptr->blkmp_ctlptr->hdr.fscklog_agg_offset =
1509
agg_recptr->ondev_fscklog_byte_offset;
1511
Current_Time = time(NULL);
1512
fsck_DateTime = localtime(&Current_Time);
1513
sprintf(&(agg_recptr->blkmp_ctlptr->hdr.start_time[0]),
1514
"%d/%d/%d %d:%02d:%02d", fsck_DateTime->tm_mon + 1,
1515
fsck_DateTime->tm_mday,
1516
(fsck_DateTime->tm_year + 1900),
1517
fsck_DateTime->tm_hour, fsck_DateTime->tm_min,
1518
fsck_DateTime->tm_sec);
1520
if (!(agg_recptr->processing_readonly)) {
1522
* use storage reserved for fsck in the
1526
blkmap_put_ctl_page(agg_recptr->blkmp_ctlptr);
1527
if (ewbmc_rc != FSCK_OK) {
1532
fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),
1535
* message to debugger
1537
fsck_send_msg(fsck_ERRONWSP, ewbmc_rc, ewbmc_rc, fsck_WRITE,
1538
(long long) this_device_offset,
1683
1546
/*****************************************************************************
1684
1547
* NAME: extent_1stref_chk
1699
1562
* ino_recptr - input - pointer to the fsck inode record describing the
1700
1563
* inode to which this extent is allocated
1702
* NOTES: As fsck scans the inodes sequentially, recording the blocks allocated,
1703
* it doesn't know a particular block is multiply-allocated until the
1704
* second reference is detected. At that time the first reference to the
1705
* block is unresolved since no list of owners is built (only a count of
1706
* owners, in which a 1 in the bit map represents a count of 1).
1565
* NOTES: As fsck scans the inodes sequentially, recording the blocks
1566
* allocated, it doesn't know a particular block is multiply-allocated
1567
* until the second reference is detected. At that time the first
1568
* reference to the block is unresolved since no list of owners is
1569
* built (only a count of owners, in which a 1 in the bit map
1570
* represents a count of 1).
1708
* After all inodes have been scanned and their block allocations recorded,
1709
* if any multiply-allocated blocks have been detected, the inodes are
1710
* scanned sequentially again until all first references to
1711
* multiply-allocated blocks are resolved. This routine is invoked during
1572
* After all inodes have been scanned and their block allocations
1573
* recorded, if any multiply-allocated blocks have been detected, the
1574
* inodes are scanned sequentially again until all first references to
1575
* multiply-allocated blocks are resolved. This routine is invoked
1576
* during that rescan.
1715
1579
* success: FSCK_OK
1716
1580
* failure: something else
1718
retcode_t extent_1stref_chk ( fsblkidx_t first_block,
1719
fsblkidx_t last_block,
1722
fsck_msg_info_ptr msg_info_ptr,
1723
fsck_inode_recptr ino_recptr )
1582
int extent_1stref_chk(int64_t first_block,
1586
struct fsck_ino_msg_info *msg_info_ptr,
1587
struct fsck_inode_record *ino_recptr)
1725
retcode_t eq_rc = FSCK_OK;
1727
fsblkidx_t first_in_dup_range = 0;
1728
reg_idx_t size_of_dup_range = 0;
1730
int dups_detected = 0;
1732
for ( blkidx = first_block;
1733
((blkidx <= last_block) &&
1734
(eq_rc == FSCK_OK) &&
1735
(agg_recptr->unresolved_1stref_count > 0));
1737
eq_rc = blkall_ref_check( blkidx, &is_dup ); /* see if this contains the first
1738
* reference to some multiply-allocated
1741
if ( eq_rc == FSCK_OK ) {
1742
if ( is_dup ) { /* a block that's already allocated */
1743
if ( size_of_dup_range == 0 ) { /* this is a new range */
1745
first_in_dup_range = blkidx;
1746
size_of_dup_range = 1;
1747
} else { /* else not a new range */
1748
size_of_dup_range++;
1749
} /* end else not a new range */
1750
} else { /* it's not already allocated */
1751
if ( size_of_dup_range > 0 ) { /* just finished a range */
1752
sprintf( message_parm_0, "%d", size_of_dup_range );
1753
msgprms[0] = message_parm_0;
1755
sprintf( message_parm_1, "%lld", (long long)first_in_dup_range );
1756
msgprms[1] = message_parm_1;
1758
msgprms[2] = message_parm_2;
1759
msgprmidx[2] = msg_info_ptr->msg_inotyp;
1760
msgprms[3] = message_parm_3;
1761
msgprmidx[3] = msg_info_ptr->msg_inopfx;
1762
sprintf( message_parm_4, "%d", msg_info_ptr->msg_inonum );
1763
msgprms[4] = message_parm_4;
1765
fsck_send_msg( fsck_DUPBLKREF, 0, 5 );
1766
size_of_dup_range = 0;
1767
} /* end just finished a range */
1768
} /* end else it's not already allocated */
1771
if ( (eq_rc == FSCK_OK) && (size_of_dup_range > 0) ) {
1773
* last block(s) finished a range
1775
sprintf( message_parm_0, "%d", size_of_dup_range );
1776
msgprms[0] = message_parm_0;
1778
sprintf( message_parm_1, "%lld", (long long)first_in_dup_range );
1779
msgprms[1] = message_parm_1;
1781
msgprms[2] = message_parm_2;
1782
msgprmidx[2] = msg_info_ptr->msg_inotyp;
1783
msgprms[3] = message_parm_3;
1784
msgprmidx[3] = msg_info_ptr->msg_inopfx;
1785
sprintf( message_parm_4, "%d", msg_info_ptr->msg_inonum );
1786
msgprms[4] = message_parm_4;
1788
fsck_send_msg( fsck_DUPBLKREF, 0, 5 );
1789
size_of_dup_range = 0;
1790
} /* end last block(s) finished a range */
1792
if ( eq_rc == FSCK_OK ) { /* nothing fatal yet */
1793
if ( dups_detected ) { /* claims at least 1 multiply allocated block */
1794
ino_recptr->involved_in_dups = 1;
1795
msgprms[0] = message_parm_0;
1796
msgprmidx[0] = msg_info_ptr->msg_inopfx;
1797
sprintf( message_parm_1, "%d", msg_info_ptr->msg_inonum );
1798
msgprms[1] = message_parm_1;
1800
fsck_send_msg( fsck_DUPBLKREFS, 0, 2 );
1801
if ( !(inode_is_metadata(ino_recptr)) ) { /* not a metadata inode */
1802
if ( is_EA ) { /* an extended attributes extent */
1803
ino_recptr->clr_ea_fld = 1;
1804
agg_recptr->corrections_needed = 1;
1805
} else if ( is_ACL ) { /* an Access Control List */
1806
ino_recptr->clr_acl_fld = 1;
1807
agg_recptr->corrections_needed = 1;
1808
} else { /* internal node or data */
1809
ino_recptr->selected_to_rls = 1;
1810
agg_recptr->corrections_needed = 1;
1811
} /* end not an extended attributes extent */
1812
} /* end else this is not a metadata inode */
1813
} /* end claims at least 1 multiply allocated block */
1814
} /* end nothing fatal yet */
1817
} /* end of extent_1stref_chk () */
1820
/*****************************************************************************
1821
* NAME: extent_record
1589
int eq_rc = FSCK_OK;
1591
int64_t first_in_dup_range = 0;
1592
uint32_t size_of_dup_range = 0;
1594
int dups_detected = 0;
1595
struct dupall_blkrec *blkrec;
1597
while (agg_recptr->unresolved_1stref_count) {
1598
blkrec = dupall_find_blkrec(first_block, last_block);
1601
if (blkrec->first_ref_resolved) {
1602
if (blkrec->last_blk <= last_block) {
1603
first_block = blkrec->last_blk + 1;
1609
* If the record goes outside this extent, we need to split
1610
* it, since we are only interested in the intersection of
1611
* the record and this extent
1613
if ((blkrec->first_blk < first_block) ||
1614
(blkrec->last_blk > last_block)) {
1615
eq_rc = blkall_split_blkrec(blkrec, first_block,
1620
* Check if the split caused the current record to
1621
* precede the extent we are processing
1623
if (blkrec->first_blk < first_block)
1627
blkrec->first_ref_resolved = 1;
1628
agg_recptr->unresolved_1stref_count--;
1632
blkrec->last_blk - blkrec->first_blk + 1;
1633
fsck_send_msg(fsck_DUPBLKREF, size_of_dup_range,
1634
(long long) blkrec->first_blk,
1635
fsck_ref_msg(msg_info_ptr->msg_inotyp),
1636
fsck_ref_msg(msg_info_ptr->msg_inopfx),
1637
msg_info_ptr->msg_inonum);
1641
if (dups_detected && msg_info_ptr) {
1642
ino_recptr->involved_in_dups = 1;
1643
fsck_send_msg(fsck_DUPBLKREFS,
1644
fsck_ref_msg(msg_info_ptr->msg_inopfx),
1645
msg_info_ptr->msg_inonum);
1646
if (!(inode_is_metadata(ino_recptr))) {
1647
agg_recptr->corrections_needed = 1;
1649
ino_recptr->clr_ea_fld = 1;
1651
ino_recptr->clr_acl_fld = 1;
1653
ino_recptr->selected_to_rls = 1;
1659
/****************************************************************************
1660
* NAME: blkall_ref_check
1823
* FUNCTION: Record that each of the blocks in the given extent is allocated
1662
* FUNCTION: Determine whether the given blocks are multiply-allocated and, if
1663
* so, whether the first reference to it is unresolved. (In this
1664
* case, the current reference must be the first reference.)
1827
* first_block - input - ordinal number of the first block in the extent
1829
* last_block - input - ordinal number of the last block in the extent
1832
* NOTES: Under certain special circumstances, it is necessary to record that
1833
* each block in some extent are allocated, and IT IS ALREADY KNOWN
1834
* that the extent is valid and that the blocks are not multiply
1835
* allocated. (Rather, that no duplicate references to the blocks
1836
* have yet been detected and the block map currently indicates them
1837
* to be unallocated.)
1839
* This function could be accomplished using routine extent_record_dupchk
1840
* but, for performance reasons, this streamlined routine exists to
1841
* minimize processing time.
1843
* To be precise, before this routine is invoked for an extent,
1844
* o routine extent_record_dupchk was invoked for the extent, then
1845
* extent_unrecord was invoked for the extent.
1847
* OR o after all block allocations were recorded in the fsck workspace
1848
* block map, and then the block map was adjusted as needed for
1849
* inode repairs, the block map was scanned to find an extent
1850
* of available blocks. This routine is then called to record
1851
* the allocation of those blocks.
1853
* OR o possibly some other path which accomplishes the same effect.
1854
* (I.e., this may not be an exhaustive list)
1667
* first_block - input - ordinal number of the first filesystem block to
1669
* last_block - input - ordinal number of the last filesystem block to
1857
1673
* success: FSCK_OK
1858
1674
* failure: something else
1860
retcode_t extent_record ( fsblkidx_t first_block,
1861
fsblkidx_t last_block )
1676
int blkall_ref_check(int64_t first_block, int64_t last_block)
1863
retcode_t er_rc = FSCK_OK;
1866
for ( blkidx = first_block;
1867
(blkidx <= last_block) && (er_rc >= FSCK_OK);
1869
er_rc = blkall_increment_owners( blkidx );
1873
} /* end of extent_record () */
1678
return extent_1stref_chk(first_block, last_block, 0, 0, 0, 0);
1876
1681
/*****************************************************************************
1877
1682
* NAME: extent_record_dupchk
1891
1696
* is_EA - input - !0 => the extent contains an inode's EA
1892
1697
* 0 => the extent contains something else
1893
* msg_info_ptr - input - pointer to a data area containing information
1894
* needed to issue messages for this extent
1698
* msg_info_ptr - input - information needed to issue messages for this
1699
* extent. If NULL, no messages will be issued
1895
1700
* ino_recptr - input - pointer to the fsck inode record describing the
1896
1701
* inode to which this extent is allocated
1902
* failure: something else
1904
retcode_t extent_record_dupchk ( fsblkidx_t first_block,
1905
fsblkidx_t last_block,
1909
fsck_msg_info_ptr msg_info_ptr,
1910
fsck_inode_recptr ino_recptr )
1912
retcode_t erd_rc = FSCK_OK;
1913
fsblkidx_t block_idx;
1915
int dups_detected = 0;
1916
fsblkidx_t first_in_dup_range = 0;
1917
reg_idx_t size_of_dup_range = 0;
1919
if ( range_adj ) { /* the xad described an invalid range */
1920
msgprms[0] = message_parm_0;
1921
msgprmidx[0] = msg_info_ptr->msg_dxdtyp;
1922
msgprms[1] = message_parm_1;
1923
msgprmidx[1] = msg_info_ptr->msg_inotyp;
1924
msgprms[2] = message_parm_2;
1925
msgprmidx[2] = msg_info_ptr->msg_inopfx;
1926
sprintf( message_parm_3, "%d", msg_info_ptr->msg_inonum );
1927
msgprms[3] = message_parm_3;
1929
fsck_send_msg( fsck_BADBLKNO, 0, 4 );
1930
} /* end the xad described an invalid range */
1931
for ( block_idx = first_block;
1932
((block_idx <= last_block) && (erd_rc >= FSCK_OK));
1933
block_idx++ ) { /* for each block */
1934
erd_rc = blkall_increment_owners( block_idx );
1935
if ( erd_rc >= 0 ) {
1939
if ( is_a_dup ) { /* it's a block that's already allocated */
1940
if ( size_of_dup_range == 0 ) { /* this is a new range */
1942
first_in_dup_range = block_idx;
1943
size_of_dup_range = 1;
1944
} else { /* else not a new range */
1945
size_of_dup_range++;
1946
} /* end else not a new range */
1947
} else { /* it's not already allocated */
1948
if ( size_of_dup_range > 0 ) { /* just finished a range */
1949
sprintf( message_parm_0, "%d", size_of_dup_range );
1950
msgprms[0] = message_parm_0;
1952
sprintf( message_parm_1, "%lld", (long long)first_in_dup_range );
1953
msgprms[1] = message_parm_1;
1955
msgprms[2] = message_parm_2;
1956
msgprmidx[2] = msg_info_ptr->msg_inotyp;
1957
msgprms[3] = message_parm_3;
1958
msgprmidx[3] = msg_info_ptr->msg_inopfx;
1959
sprintf( message_parm_4, "%d", msg_info_ptr->msg_inonum );
1960
msgprms[4] = message_parm_4;
1962
fsck_send_msg( fsck_DUPBLKREF, 0, 5 );
1963
size_of_dup_range = 0;
1964
} /* end just finished a range */
1965
} /* end else it's not already allocated */
1966
} /* end for block_idx */
1967
if ( (erd_rc == FSCK_OK) && (size_of_dup_range > 0) ) {
1969
* last block(s) finished a range
1971
sprintf( message_parm_0, "%d", size_of_dup_range );
1972
msgprms[0] = message_parm_0;
1974
sprintf( message_parm_1, "%lld", (long long)first_in_dup_range );
1975
msgprms[1] = message_parm_1;
1977
msgprms[2] = message_parm_2;
1978
msgprmidx[2] = msg_info_ptr->msg_inotyp;
1979
msgprms[3] = message_parm_3;
1980
msgprmidx[3] = msg_info_ptr->msg_inopfx;
1981
sprintf( message_parm_4, "%d", msg_info_ptr->msg_inonum );
1982
msgprms[4] = message_parm_4;
1984
fsck_send_msg( fsck_DUPBLKREF, 0, 5 );
1985
size_of_dup_range = 0;
1986
} /* end last block(s) finished a range */
1987
if ( erd_rc == FSCK_OK ) { /* nothing fatal yet */
1988
if ( dups_detected ) { /* claims at least 1 multiply allocated block */
1989
ino_recptr->involved_in_dups = 1;
1990
msgprms[0] = message_parm_0;
1991
msgprmidx[0] = msg_info_ptr->msg_inopfx;
1992
sprintf( message_parm_1, "%d", msg_info_ptr->msg_inonum );
1993
msgprms[1] = message_parm_1;
1995
fsck_send_msg( fsck_DUPBLKREFS, 0, 2 );
1996
if ( !(inode_is_metadata(ino_recptr)) ) { /* not a metadata inode */
1997
if ( is_EA ) { /* an extended attributes extent */
1998
ino_recptr->clr_ea_fld = 1;
1999
agg_recptr->corrections_needed = 1;
2000
} else if ( is_ACL ) { /* an extended attributes extent */
2001
ino_recptr->clr_acl_fld = 1;
2002
agg_recptr->corrections_needed = 1;
2003
} else { /* internal node or data */
2004
ino_recptr->selected_to_rls = 1;
2005
agg_recptr->corrections_needed = 1;
2006
} /* end not an extended attributes extent */
2007
} /* end else this is not a metadata inode */
2008
} /* end claims at least 1 multiply allocated block */
2009
} /* end nothing fatal yet */
2012
} /* end of extent_record_dupchk () */
1705
* failure: something else
1707
int extent_record_dupchk(int64_t first_block,
1712
struct fsck_ino_msg_info *msg_info_ptr,
1713
struct fsck_inode_record *ino_recptr)
1715
int erd_rc = FSCK_OK;
1716
int dups_detected = 0;
1717
struct dupall_blkrec *this_blkrec;
1720
/* the xad described an invalid range */
1721
fsck_send_msg(fsck_BADBLKNO,
1722
fsck_ref_msg(msg_info_ptr->msg_dxdtyp),
1723
fsck_ref_msg(msg_info_ptr->msg_inotyp),
1724
fsck_ref_msg(msg_info_ptr->msg_inopfx),
1725
msg_info_ptr->msg_inonum);
1729
* Look for duplicate blocks already detected for this extent
1731
while (first_block <= last_block) {
1732
this_blkrec = dupall_find_blkrec(first_block, last_block);
1737
* If this record goes beyond the extent, we need to split it.
1739
if ((this_blkrec->first_blk < first_block) ||
1740
(this_blkrec->last_blk > last_block)) {
1741
erd_rc = blkall_split_blkrec(this_blkrec, first_block,
1746
* Check if the split caused the current record to
1747
* precede the extent we are processing
1749
if (this_blkrec->first_blk < first_block)
1754
* Take care of the blocks preceding this record (if any)
1756
if (first_block < this_blkrec->first_blk) {
1757
erd_rc = blkall_increment_owners(first_block,
1758
this_blkrec->first_blk - 1,
1766
this_blkrec->owner_count++;
1767
first_block = this_blkrec->last_blk + 1;
1771
* Take care of any remaining blocks
1773
if (first_block <= last_block) {
1774
erd_rc = blkall_increment_owners(first_block, last_block,
1781
if (dups_detected && msg_info_ptr) {
1782
/* claims at least 1 multiply allocated block */
1783
ino_recptr->involved_in_dups = 1;
1784
fsck_send_msg(fsck_DUPBLKREFS,
1785
fsck_ref_msg(msg_info_ptr->msg_inopfx),
1786
msg_info_ptr->msg_inonum);
1787
if (!(inode_is_metadata(ino_recptr))) {
1788
agg_recptr->corrections_needed = 1;
1790
ino_recptr->clr_ea_fld = 1;
1792
ino_recptr->clr_acl_fld = 1;
1794
ino_recptr->selected_to_rls = 1;
1800
/*****************************************************************************
1801
* NAME: extent_record
1803
* FUNCTION: Record that each of the blocks in the given extent is allocated
1807
* first_block - input - ordinal number of the first block in the extent
1809
* last_block - input - ordinal number of the last block in the extent
1812
* NOTES: Originally, this was intended to be a streamlined version of
1813
* extent_record_dupchk, called only when the extent was known to
1814
* not be multilply allocated. However, it really wasn't any more
1815
* efficient, so its simpler to just call extent_record_dupchk here.
1819
* failure: something else
1821
int extent_record(int64_t first_block, int64_t last_block)
1823
return extent_record_dupchk(first_block, last_block, 0, 0, 0, 0, 0);
2015
1826
/*****************************************************************************
2016
1827
* NAME: extent_unrecord
2033
1844
* this streamlined routine exists to minimize processing time.
2035
1846
* Examples of these circumstances include:
2036
* o Storage allocated for an inode's EA is valid, but the B+Tree
2037
* rooted in the inode is structurally corrupt. Then the portions
2038
* of the tree which were recorded before the corruption was detected
2039
* were backed out using routines which include validation code, and
2040
* finally this routine is called to 'unrecord' the storage allocated
2043
* o The B+Tree rooted in an inode was verified structurally correct,
2044
* but the di_nblocks in the inode was found to be inconsistent with
2045
* the tree. In this case we assume the tree to be corrupt and
2046
* back it out of the fsck workspace block map immediately. This
2047
* routine would be used for that purpose since the tree has already
2048
* been verified structurally correct.
2050
* o An inode has been found to be valid, but claims ownership of at
2051
* least one block claimed by another inode. At least one of the
2052
* inodes is actually damaged. The user has given permission to
2053
* delete this inode, and so we need to decrement the number of
2054
* owners for each block allocated to this inode. This routine
2055
* would be used for that purpose since the tree has already been
2056
* verified structurally correct.
1847
* o Storage allocated for an inode's EA is valid, but the B+Tree
1848
* rooted in the inode is structurally corrupt. Then the portions
1849
* of the tree which were recorded before the corruption was detected
1850
* were backed out using routines which include validation code, and
1851
* finally this routine is called to 'unrecord' the storage allocated
1854
* o The B+Tree rooted in an inode was verified structurally correct,
1855
* but the di_nblocks in the inode was found to be inconsistent with
1856
* the tree. In this case we assume the tree to be corrupt and
1857
* back it out of the fsck workspace block map immediately. This
1858
* routine would be used for that purpose since the tree has already
1859
* been verified structurally correct.
1861
* o An inode has been found to be valid, but claims ownership of at
1862
* least one block claimed by another inode. At least one of the
1863
* inodes is actually damaged. The user has given permission to
1864
* delete this inode, and so we need to decrement the number of
1865
* owners for each block allocated to this inode. This routine
1866
* would be used for that purpose since the tree has already been
1867
* verified structurally correct.
2060
1871
* success: FSCK_OK
2061
1872
* failure: something else
2063
retcode_t extent_unrecord ( fsblkidx_t first_block,
2064
fsblkidx_t last_block )
1874
int extent_unrecord(int64_t first_block, int64_t last_block)
2066
retcode_t eu_rc = FSCK_OK;
2069
for ( blkidx = first_block;
2070
(blkidx <= last_block) && (eu_rc >= FSCK_OK);
2072
eu_rc = blkall_decrement_owners( blkidx );
2076
} /* end of extent_unrecord () */
1876
int eu_rc = FSCK_OK;
1877
struct dupall_blkrec *this_blkrec;
1879
while (first_block <= last_block) {
1880
this_blkrec = dupall_find_blkrec(first_block, last_block);
1885
* If this record goes beyond the extent, we need to split it.
1887
if ((this_blkrec->first_blk < first_block) ||
1888
(this_blkrec->last_blk > last_block)) {
1889
eu_rc = blkall_split_blkrec(this_blkrec, first_block,
1894
* Check if the split caused the current record to
1895
* precede the extent we are processing
1897
if (this_blkrec->first_blk < first_block)
1902
* Take care of the blocks preceding this record (if any)
1904
if (first_block < this_blkrec->first_blk) {
1905
eu_rc = blkall_mark_free(first_block,
1906
this_blkrec->first_blk - 1);
1911
this_blkrec->owner_count--;
1912
if (this_blkrec->owner_count == 1) {
1913
/* No longer a duplicate */
1914
if (!this_blkrec->first_ref_resolved)
1915
agg_recptr->unresolved_1stref_count--;
1916
agg_recptr->dup_block_count--;
1918
dupall_extract_blkrec(this_blkrec);
1920
first_block = this_blkrec->last_blk + 1;
1924
* Take care of any remaining blocks
1926
if (first_block <= last_block)
1927
eu_rc = blkall_mark_free(first_block, last_block);
2079
1932
/****************************************************************************
2080
1933
* NAME: fsblk_count_avail
2259
2105
* success: FSCK_OK
2260
2106
* failure: something else
2262
retcode_t fsck_alloc_fsblks ( int32_t blocks_wanted,
2263
fsblkidx_t *blocks )
2108
int fsck_alloc_fsblks(int32_t blocks_wanted, int64_t * blocks)
2265
retcode_t fafsb_rc = FSCK_OK;
2266
mappgidx_t wsp_pagenum = 0;
2267
blk_pageptr wsp_page = NULL;
2268
int32_t this_word = 0, this_bit = 0;
2269
int32_t found_word = -1, found_bit = -1;
2271
int32_t blocks_found = 0;
2272
fsck_bitmap_ptr wsp_bits;
2276
while ( (wsp_pagenum < agg_recptr->blkmp_pagecount) &&
2277
(blocks_found != blocks_wanted) &&
2278
(fafsb_rc == FSCK_OK) ) {
2279
fafsb_rc = blkmap_get_page( wsp_pagenum, &wsp_page );
2280
if ( fafsb_rc == FSCK_OK ) { /* got a page */
2281
wsp_bits = (fsck_bitmap_ptr) wsp_page;
2286
fafsb_rc = fsblk_next_avail( wsp_bits, this_word, this_bit,
2287
&found_word, &found_bit, &found_a_block );
2288
while ( (found_a_block) &&
2289
(fafsb_rc == FSCK_OK) &&
2290
(blocks_found != blocks_wanted) ) {
2291
this_word = found_word;
2292
this_bit = found_bit;
2295
fafsb_rc = fsblk_count_avail( wsp_bits, &found_word, &found_bit,
2296
blocks_wanted, &blocks_found );
2297
if ( fafsb_rc == FSCK_OK ) { /* nothing bizarre happened */
2298
if ( blocks_found == blocks_wanted ) { /* success! */
2299
*blocks = (wsp_pagenum << log2BITSPERPAGE) +
2300
(this_word << log2BITSPERDWORD) +
2302
} else { /* nothing useful yet */
2303
this_word = found_word; /* word containing 1st 1 after the zeroes */
2304
this_bit = found_bit; /* bit postion in that word */
2306
fafsb_rc = fsblk_next_avail( wsp_bits, this_word, this_bit,
2307
&found_word, &found_bit,
2309
} /* end else nothing useful yet */
2310
} /* end nothing bizarre happened */
2312
if ( (fafsb_rc == FSCK_OK) && (!found_a_block) ) { /* no avail block found */
2313
wsp_pagenum++; /* maybe in the next page */
2314
} /* end no avail block found */
2315
} /* end got a page */
2318
if ( fafsb_rc == FSCK_OK ) { /* nothing fatal along the way */
2319
if ( (*blocks) == 0 ) { /* didn't find the blocks */
2320
fafsb_rc = FSCK_BLKSNOTAVAILABLE;
2321
sprintf( message_parm_0, "%d", blocks_wanted );
2322
msgprms[0] = message_parm_0;
2324
fsck_send_msg( fsck_EXHFILSYSSTG, 0, 1 );
2325
} else if ( (*blocks) > agg_recptr->highest_valid_fset_datablk ) {
2327
* the first available blocks were in the work area
2330
fafsb_rc = FSCK_BLKSNOTAVAILABLE;
2331
sprintf( message_parm_0, "%d", blocks_wanted );
2332
msgprms[0] = message_parm_0;
2334
fsck_send_msg( fsck_EXHFILSYSSTG, 0, 1 );
2335
} else { /* we found the requested blocks */
2336
fafsb_rc = extent_record( *blocks, (*blocks + blocks_wanted - 1) ); /*
2337
* allocate these blocks for the caller
2338
* by marking them 'in use' in the fsck
2339
* workspace block map
2341
} /* end else we found the requested blocks */
2342
} /* end nothing fatal along the way */
2345
} /* end fsck_alloc_fsblks */
2110
int fafsb_rc = FSCK_OK;
2111
int64_t wsp_pagenum = 0;
2112
struct fsck_blk_map_page *wsp_page = NULL;
2113
int32_t this_word = 0, this_bit = 0;
2114
int32_t found_word = -1, found_bit = -1;
2116
int32_t blocks_found = 0;
2121
while ((wsp_pagenum < agg_recptr->blkmp_pagecount) &&
2122
(blocks_found != blocks_wanted) && (fafsb_rc == FSCK_OK)) {
2123
fafsb_rc = blkmap_get_page(wsp_pagenum, &wsp_page);
2124
if (fafsb_rc == FSCK_OK) {
2126
wsp_bits = (uint32_t *) wsp_page;
2132
fsblk_next_avail(wsp_bits, this_word, this_bit,
2133
&found_word, &found_bit,
2135
while ((found_a_block) && (fafsb_rc == FSCK_OK)
2136
&& (blocks_found != blocks_wanted)) {
2137
this_word = found_word;
2138
this_bit = found_bit;
2142
fsblk_count_avail(wsp_bits, &found_word,
2143
&found_bit, blocks_wanted,
2145
if (fafsb_rc == FSCK_OK) {
2146
/* nothing bizarre happened */
2147
if (blocks_found == blocks_wanted) {
2156
/* word containing 1st 1 after the zeroes */
2157
this_word = found_word;
2158
/* bit postion in that word */
2159
this_bit = found_bit;
2162
fsblk_next_avail(wsp_bits,
2171
if ((fafsb_rc == FSCK_OK) && (!found_a_block)) {
2172
/* no avail block found */
2173
/* maybe in the next page */
2179
if (fafsb_rc == FSCK_OK) {
2180
/* nothing fatal along the way */
2181
if ((*blocks) == 0) {
2182
/* didn't find the blocks */
2183
fafsb_rc = FSCK_BLKSNOTAVAILABLE;
2184
fsck_send_msg(fsck_EXHFILSYSSTG, blocks_wanted);
2185
} else if ((*blocks) > agg_recptr->highest_valid_fset_datablk) {
2187
* the first available blocks were in the work area
2190
fafsb_rc = FSCK_BLKSNOTAVAILABLE;
2191
fsck_send_msg(fsck_EXHFILSYSSTG, blocks_wanted);
2193
/* we found the requested blocks */
2195
* allocate these blocks for the caller
2196
* by marking them 'in use' in the fsck
2197
* workspace block map
2200
extent_record(*blocks,
2201
(*blocks + blocks_wanted - 1));
2348
2207
/****************************************************************************
2349
2208
* NAME: fsck_dealloc_fsblks
2449
2305
* success: FSCK_OK
2451
retcode_t fscklog_init ( )
2453
retcode_t fli_rc = FSCK_OK;
2454
agg_byteidx_t log_bytes_left;
2455
struct fsck_blk_map_page *tmpbuf_addr = NULL;
2456
struct fsck_blk_map_page *tmp_buf_ptr;
2457
reg_idx_t tmp_buf_data_len;
2458
agg_byteidx_t tmp_agg_offset;
2459
agg_byteidx_t tmp_log_offset;
2461
if ( agg_recptr->processing_readwrite ) { /* have write access */
2463
* this is safe because we do it before calling logredo
2465
tmpbuf_addr = (struct fsck_blk_map_page *) malloc(FSCKLOG_BUFSIZE);
2467
if ( tmpbuf_addr == NULL ) { /* didn't get the space */
2468
fsck_send_msg( fsck_CANTINITSVCLOG, 0, 0 ); /* log this fact so
2469
* that any residual messages will be ignored
2471
} else { /* temp buffer allocated */
2472
agg_recptr->initializing_fscklog = 1;
2473
memset( (void *) tmpbuf_addr, 0, FSCKLOG_BUFSIZE );
2475
* save the current fscklog values
2477
tmp_buf_ptr = agg_recptr->fscklog_buf_ptr;
2478
tmp_buf_data_len = agg_recptr->fscklog_buf_data_len;
2479
tmp_agg_offset = agg_recptr->fscklog_agg_offset;
2480
tmp_log_offset = agg_recptr->fscklog_log_offset;
2482
* store values to describe the temp buffer
2484
agg_recptr->fscklog_buf_ptr = tmpbuf_addr;
2485
agg_recptr->fscklog_buf_data_len = FSCKLOG_BUFSIZE;
2487
log_bytes_left = (agg_recptr->ondev_fscklog_byte_length / 2) -
2488
agg_recptr->fscklog_log_offset;
2489
while ( log_bytes_left >= agg_recptr->fscklog_buf_length ) {
2490
fscklog_put_buffer();
2491
log_bytes_left = (agg_recptr->ondev_fscklog_byte_length / 2) -
2492
agg_recptr->fscklog_log_offset;
2495
free( (void *) tmpbuf_addr );
2497
* restore the actual fscklog values
2499
agg_recptr->fscklog_buf_ptr = tmp_buf_ptr;
2500
agg_recptr->fscklog_buf_data_len = tmp_buf_data_len;
2501
agg_recptr->fscklog_agg_offset = tmp_agg_offset;
2502
agg_recptr->fscklog_log_offset = tmp_log_offset;
2504
agg_recptr->initializing_fscklog = 0;
2505
} /* end else temp buffer allocated */
2506
} /* end have write access */
2509
} /* end fscklog_init */
2309
int fli_rc = FSCK_OK;
2310
int64_t log_bytes_left;
2311
struct fsck_blk_map_page *tmpbuf_addr = NULL;
2312
struct fsck_blk_map_page *tmp_buf_ptr;
2313
uint32_t tmp_buf_data_len;
2314
int64_t tmp_agg_offset;
2315
int64_t tmp_log_offset;
2317
if (agg_recptr->processing_readwrite) {
2318
/* have write access */
2320
* this is safe because we do it before calling logredo
2323
(struct fsck_blk_map_page *) malloc(FSCKLOG_BUFSIZE);
2325
if (tmpbuf_addr == NULL) {
2326
/* didn't get the space */
2327
/* log this fact so that any residual messages will be ignored */
2328
fsck_send_msg(fsck_CANTINITSVCLOG);
2330
/* temp buffer allocated */
2331
agg_recptr->initializing_fscklog = 1;
2332
memset((void *) tmpbuf_addr, 0, FSCKLOG_BUFSIZE);
2334
* save the current fscklog values
2336
tmp_buf_ptr = agg_recptr->fscklog_buf_ptr;
2337
tmp_buf_data_len = agg_recptr->fscklog_buf_data_len;
2338
tmp_agg_offset = agg_recptr->fscklog_agg_offset;
2339
tmp_log_offset = agg_recptr->fscklog_log_offset;
2341
* store values to describe the temp buffer
2343
agg_recptr->fscklog_buf_ptr = tmpbuf_addr;
2344
agg_recptr->fscklog_buf_data_len = FSCKLOG_BUFSIZE;
2347
(agg_recptr->ondev_fscklog_byte_length / 2) -
2348
agg_recptr->fscklog_log_offset;
2349
while (log_bytes_left >= agg_recptr->fscklog_buf_length) {
2350
fscklog_put_buffer();
2352
(agg_recptr->ondev_fscklog_byte_length /
2353
2) - agg_recptr->fscklog_log_offset;
2356
free((void *) tmpbuf_addr);
2358
* restore the actual fscklog values
2360
agg_recptr->fscklog_buf_ptr = tmp_buf_ptr;
2361
agg_recptr->fscklog_buf_data_len = tmp_buf_data_len;
2362
agg_recptr->fscklog_agg_offset = tmp_agg_offset;
2363
agg_recptr->fscklog_log_offset = tmp_log_offset;
2365
agg_recptr->initializing_fscklog = 0;
2512
2371
/****************************************************************************
2513
2372
* NAME: fscklog_start
2682
2543
* success: FSCK_OK
2683
2544
* failure: something else
2685
retcode_t get_inorecptr_first ( int is_aggregate,
2687
fsck_inode_recptr *addr_inorecptr )
2546
int get_inorecptr_first(int is_aggregate,
2548
struct fsck_inode_record **addr_inorecptr)
2689
retcode_t girf_rc = FSCK_OK;
2690
int32_t iagidx, extidx, inoidx;
2691
inoext_tblptr inoexttbl;
2695
* find first active aggregate inode record
2697
if ( is_aggregate ) { /* for an aggregate inode */
2698
if ( agg_recptr->AIT_ext0_tbl == NULL ) {
2699
girf_rc = FSCK_INTERNAL_ERROR_68;
2701
sprintf( message_parm_0, "%d", girf_rc );
2702
msgprms[0] = message_parm_0;
2704
sprintf( message_parm_1, "%d", 0 );
2705
msgprms[1] = message_parm_1;
2707
sprintf( message_parm_2, "%d", 0 );
2708
msgprms[2] = message_parm_2;
2710
sprintf( message_parm_3, "%d", 0 );
2711
msgprms[3] = message_parm_3;
2713
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
2716
* the first allocated aggregate inode is inode 1,
2721
agg_recptr->AIT_ext0_tbl->inorectbl[inoidx];
2722
agg_recptr->agg_last_inoidx = inoidx;
2726
* find first active fileset inode record
2728
} else { /* for a fileset inode */
2729
if ( agg_recptr->FSIT_IAG_tbl == NULL ) {
2730
girf_rc = FSCK_INTERNAL_ERROR_69;
2731
sprintf( message_parm_0, "%d", girf_rc );
2732
msgprms[0] = message_parm_0;
2734
sprintf( message_parm_1, "%d", 0 );
2735
msgprms[1] = message_parm_1;
2737
sprintf( message_parm_2, "%d", 0 );
2738
msgprms[2] = message_parm_2;
2740
sprintf( message_parm_3, "%d", 0 );
2741
msgprms[3] = message_parm_3;
2743
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
2744
} else { /* the table is allocated */
2746
* IAG 0 is always the first active IAG in the
2747
* fileset and extent 0 is always the first active
2748
* extent since inode 2 (the root dir) is always
2749
* the first active inode.
2755
inoexttbl = agg_recptr->FSIT_IAG_tbl->inoext_tbl[iagidx];
2756
inotbl = inoexttbl->inotbl[extidx];
2757
*addr_inorecptr = inotbl->inorectbl[inoidx];
2759
* set things up for find next
2761
agg_recptr->fs_last_iagidx = iagidx;
2762
agg_recptr->fs_last_extidx = extidx;
2763
agg_recptr->fs_last_inoidx = inoidx;
2764
} /* end else the table is allocated */
2765
} /* end else for a fileset inode */
2767
if ( girf_rc == FSCK_OK ) { /* got one */
2768
*inonum = (*addr_inorecptr)->inonum;
2772
} /* end get_inorecptr_first */
2550
int girf_rc = FSCK_OK;
2551
int32_t iagidx, extidx, inoidx;
2552
struct inode_ext_tbl_t *inoexttbl;
2553
struct inode_tbl_t *inotbl;
2556
* find first active aggregate inode record
2558
if (is_aggregate) { /* for an aggregate inode */
2559
if (agg_recptr->AIT_ext0_tbl == NULL) {
2560
girf_rc = FSCK_INTERNAL_ERROR_68;
2562
fsck_send_msg(fsck_INTERNALERROR, girf_rc, 0, 0, 0);
2565
* the first allocated aggregate inode is inode 1,
2570
agg_recptr->AIT_ext0_tbl->inorectbl[inoidx];
2571
agg_recptr->agg_last_inoidx = inoidx;
2575
* find first active fileset inode record
2578
/* for a fileset inode */
2579
if (agg_recptr->FSIT_IAG_tbl == NULL) {
2580
girf_rc = FSCK_INTERNAL_ERROR_69;
2581
fsck_send_msg(fsck_INTERNALERROR, girf_rc, 0, 0, 0);
2583
/* the table is allocated */
2585
* IAG 0 is always the first active IAG in the
2586
* fileset and extent 0 is always the first active
2587
* extent since inode 2 (the root dir) is always
2588
* the first active inode.
2595
agg_recptr->FSIT_IAG_tbl->inoext_tbl[iagidx];
2596
inotbl = inoexttbl->inotbl[extidx];
2597
*addr_inorecptr = inotbl->inorectbl[inoidx];
2599
* set things up for find next
2601
agg_recptr->fs_last_iagidx = iagidx;
2602
agg_recptr->fs_last_extidx = extidx;
2603
agg_recptr->fs_last_inoidx = inoidx;
2607
if (girf_rc == FSCK_OK) {
2609
*inonum = (*addr_inorecptr)->inonum;
2775
2614
/****************************************************************************
2776
2615
* NAME: get_inorecptr_next
2819
2658
* success: FSCK_OK
2820
2659
* failure: something else
2822
retcode_t get_inorecptr_next ( int is_aggregate,
2824
fsck_inode_recptr *addr_inorecptr )
2661
int get_inorecptr_next(int is_aggregate,
2663
struct fsck_inode_record **addr_inorecptr)
2826
retcode_t girn_rc = FSCK_OK;
2827
int32_t iagidx, extidx, inoidx;
2828
int32_t extidx_init, inoidx_init;
2829
inoext_tblptr inoexttbl;
2833
* find next active aggregate inode record
2835
if ( is_aggregate ) { /* for an aggregate inode */
2836
if ( agg_recptr->AIT_ext0_tbl == NULL ) {
2837
girn_rc = FSCK_INTERNAL_ERROR_54;
2838
sprintf( message_parm_0, "%d", girn_rc );
2839
msgprms[0] = message_parm_0;
2841
sprintf( message_parm_1, "%d", 0 );
2842
msgprms[1] = message_parm_1;
2844
sprintf( message_parm_2, "%d", 0 );
2845
msgprms[2] = message_parm_2;
2847
sprintf( message_parm_3, "%d", 0 );
2848
msgprms[3] = message_parm_3;
2850
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
2852
*addr_inorecptr = NULL;
2853
for ( inoidx = agg_recptr->agg_last_inoidx + 1;
2854
( (inoidx < INOSPEREXT) && (*addr_inorecptr == NULL) );
2856
agg_recptr->agg_last_inoidx = inoidx;
2857
if ( agg_recptr->AIT_ext0_tbl->inorectbl[inoidx] != NULL ) {
2858
*addr_inorecptr = agg_recptr->AIT_ext0_tbl->inorectbl[inoidx];
2864
* find next active fileset inode record
2866
} else { /* for a fileset inode */
2867
if ( agg_recptr->FSIT_IAG_tbl == NULL ) {
2868
girn_rc = FSCK_INTERNAL_ERROR_55;
2869
sprintf( message_parm_0, "%d", girn_rc );
2870
msgprms[0] = message_parm_0;
2872
sprintf( message_parm_1, "%d", 0 );
2873
msgprms[1] = message_parm_1;
2875
sprintf( message_parm_2, "%d", 0 );
2876
msgprms[2] = message_parm_2;
2878
sprintf( message_parm_3, "%d", 0 );
2879
msgprms[3] = message_parm_3;
2881
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
2882
} else { /* the table is allocated */
2883
extidx_init = agg_recptr->fs_last_extidx;
2884
inoidx_init = agg_recptr->fs_last_inoidx + 1;
2885
*addr_inorecptr = NULL;
2886
for ( iagidx = agg_recptr->fs_last_iagidx;
2887
( (iagidx < agg_recptr->fset_imap.num_iags) &&
2888
(*addr_inorecptr == NULL) );
2890
agg_recptr->fs_last_iagidx = iagidx;
2891
if ( agg_recptr->FSIT_IAG_tbl->inoext_tbl[iagidx] != NULL ) {
2892
inoexttbl = agg_recptr->FSIT_IAG_tbl->inoext_tbl[iagidx];
2893
for ( extidx = extidx_init;
2894
( (extidx < EXTSPERIAG) &&
2895
(*addr_inorecptr == NULL) );
2897
agg_recptr->fs_last_extidx = extidx;
2898
if ( inoexttbl->inotbl[extidx] != NULL ) {
2899
inotbl = inoexttbl->inotbl[extidx];
2900
for ( inoidx = inoidx_init;
2901
( (inoidx < INOSPEREXT) &&
2902
(*addr_inorecptr == NULL) );
2904
agg_recptr->fs_last_inoidx = inoidx;
2905
if ( inotbl->inorectbl[inoidx] != NULL ) {
2906
*addr_inorecptr = inotbl->inorectbl[inoidx];
2908
} /* end for inoidx */
2909
} /* end if the inode table is allocated */
2911
} /* end for extidx */
2912
} /* end if the ext table is allocated */
2914
} /* end for iagidx */
2915
} /* end else the table is allocated */
2916
} /* end else for a fileset inode */
2918
if ( ((*addr_inorecptr) != NULL) && (girn_rc == FSCK_OK) ) { /* got one */
2919
*inonum = (*addr_inorecptr)->inonum;
2923
} /* end get_inorecptr_next */
2665
int girn_rc = FSCK_OK;
2666
int32_t iagidx, extidx, inoidx;
2667
int32_t extidx_init, inoidx_init;
2668
struct inode_ext_tbl_t *inoexttbl;
2669
struct inode_tbl_t *inotbl;
2672
* find next active aggregate inode record
2675
/* for an aggregate inode */
2676
if (agg_recptr->AIT_ext0_tbl == NULL) {
2677
girn_rc = FSCK_INTERNAL_ERROR_54;
2678
fsck_send_msg(fsck_INTERNALERROR, girn_rc, 0, 0, 0);
2680
*addr_inorecptr = NULL;
2681
for (inoidx = agg_recptr->agg_last_inoidx + 1;
2682
((inoidx < INOSPEREXT)
2683
&& (*addr_inorecptr == NULL)); inoidx++) {
2684
agg_recptr->agg_last_inoidx = inoidx;
2685
if (agg_recptr->AIT_ext0_tbl->
2686
inorectbl[inoidx] != NULL) {
2688
agg_recptr->AIT_ext0_tbl->
2696
if (agg_recptr->FSIT_IAG_tbl == NULL) {
2697
girn_rc = FSCK_INTERNAL_ERROR_55;
2698
fsck_send_msg(fsck_INTERNALERROR, girn_rc, 0, 0, 0);
2702
/* the table is allocated */
2703
extidx_init = agg_recptr->fs_last_extidx;
2704
inoidx_init = agg_recptr->fs_last_inoidx + 1;
2705
*addr_inorecptr = NULL;
2706
for (iagidx = agg_recptr->fs_last_iagidx;
2707
((iagidx < agg_recptr->fset_imap.num_iags) &&
2708
(*addr_inorecptr == NULL)); iagidx++) {
2709
agg_recptr->fs_last_iagidx = iagidx;
2710
if (agg_recptr->FSIT_IAG_tbl->
2711
inoext_tbl[iagidx] != NULL) {
2713
agg_recptr->FSIT_IAG_tbl->inoext_tbl[iagidx];
2714
for (extidx = extidx_init; ((extidx < EXTSPERIAG)
2715
&& (*addr_inorecptr == NULL)); extidx++) {
2716
agg_recptr->fs_last_extidx = extidx;
2717
if (inoexttbl->inotbl[extidx] != NULL) {
2718
inotbl = inoexttbl->inotbl[extidx];
2719
for (inoidx = inoidx_init;
2720
((inoidx < INOSPEREXT) &&
2721
(*addr_inorecptr == NULL));
2723
agg_recptr->fs_last_inoidx =
2725
if (inotbl->inorectbl[inoidx] !=
2740
if (((*addr_inorecptr) != NULL) && (girn_rc == FSCK_OK)) {
2742
*inonum = (*addr_inorecptr)->inonum;
2926
2748
/****************************************************************************
2927
2749
* NAME: init_agg_record
2937
2759
* success: FSCK_OK
2938
2760
* failure: something else
2940
retcode_t init_agg_record( )
2762
int init_agg_record()
2942
retcode_t iar_rc = FSCK_OK;
2944
memset ( agg_recptr, 0, sizeof(fsck_agg_record) );
2945
memcpy( (void *) &(agg_recptr->eyecatcher), (void *) "fsckagrc", 8 );
2946
memcpy( (void *) &(agg_recptr->this_inode.eyecatcher),
2947
(void *) "thisinod", 8 );
2948
memcpy( (void *) &(agg_recptr->agg_imap_eyecatcher),
2949
(void *) "agg imap", 8 );
2950
memcpy( (void *) &(agg_recptr->fset_imap_eyecatcher),
2951
(void *) "fsetimap", 8 );
2952
memcpy( (void *) &(agg_recptr->AIT_eyecatcher),
2953
(void *) "agg ITbl", 8 );
2954
memcpy( (void *) &(agg_recptr->FSIT_eyecatcher),
2955
(void *) "fsetITbl", 8 );
2956
memcpy( (void *) &(agg_recptr->flags_eyecatcher),
2957
(void *) "aggflags", 8 );
2958
memcpy( (void *) &(agg_recptr->fais.eyecatcher),
2959
(void *) "faisinfo", 8 );
2960
memcpy( (void *) &(agg_recptr->vlarge_info_eyecatcher),
2961
(void *) "vlargebf", 8 );
2962
memcpy( (void *) &(agg_recptr->fscklog_info_eyecatcher),
2963
(void *) "fscklog ", 8 );
2964
memcpy( (void *) &(agg_recptr->blkmp_info_eyecatcher),
2965
(void *) "blkmpbuf", 8 );
2966
memcpy( (void *) &(agg_recptr->ea_info_eyecatcher),
2967
(void *) "eabuffer", 8 );
2968
memcpy( (void *) &(agg_recptr->iag_info_eyecatcher),
2969
(void *) "iag buf ", 8 );
2970
memcpy( (void *) &(agg_recptr->mapctl_info_eyecatcher),
2971
(void *) "mapctbuf", 8 );
2972
memcpy( (void *) &(agg_recptr->maplf_info_eyecatcher),
2973
(void *) "maplfbuf", 8 );
2974
memcpy( (void *) &(agg_recptr->bmplv_info_eyecatcher),
2975
(void *) "bmplvbuf", 8 );
2976
memcpy( (void *) &(agg_recptr->bmpdm_info_eyecatcher),
2977
(void *) "bmpdmbuf", 8 );
2978
memcpy( (void *) &(agg_recptr->inobuf_info_eyecatcher),
2979
(void *) "inodebuf", 8 );
2980
memcpy( (void *) &(agg_recptr->nodbuf_info_eyecatcher),
2981
(void *) "node buf", 8 );
2982
memcpy( (void *) &(agg_recptr->agg_AGTbl_eyecatcher),
2983
(void *) "aggAGTbl", 8 );
2984
memcpy( (void *) &(agg_recptr->fset_AGTbl_eyecatcher),
2985
(void *) "fs AGTbl", 8 );
2986
memcpy( (void *) &(agg_recptr->amap_eyecatcher),
2987
(void *) "iagiamap", 8 );
2988
memcpy( (void *) &(agg_recptr->fextsumm_eyecatcher),
2989
(void *) "fextsumm", 8 );
2990
memcpy( (void *) &(agg_recptr->finosumm_eyecatcher),
2991
(void *) "finosumm", 8 );
2993
/* do the conversions from character to UniCharacter */
2995
agg_recptr->tree_height = 0;
2996
agg_recptr->delim_char = '/'; /* single char */
2997
agg_recptr->UniChar_LSFN_NAME = uni_LSFN_NAME; /* store the address */
2998
agg_recptr->UniChar_lsfn_name = uni_lsfn_name; /* store the address */
2999
agg_recptr->agg_imap.ag_tbl = &(agg_recptr->agg_AGTbl[0]);
3000
agg_recptr->fset_imap.ag_tbl = &(agg_recptr->fset_AGTbl[0]);
3002
* start the messaging level out as 'show everything'
3003
* It may be reset lower when the parms have been parsed.
3005
agg_recptr->effective_msg_level = fsck_verbose;
3007
* check to see whether standard out has been redirected, and
3008
* set the flag accordingly.
3010
if ( isatty( STDOUT_FILENO ) )
3011
agg_recptr->stdout_redirected = 0;
3013
agg_recptr->stdout_redirected = 1;
3016
} /* end init_agg_record */
2764
int iar_rc = FSCK_OK;
2766
memset(agg_recptr, 0, sizeof (struct fsck_agg_record));
2767
memcpy((void *) &(agg_recptr->eyecatcher), (void *) "fsckagrc", 8);
2768
memcpy((void *) &(agg_recptr->this_inode.eyecatcher),
2769
(void *) "thisinod", 8);
2770
memcpy((void *) &(agg_recptr->agg_imap_eyecatcher), (void *) "agg imap",
2772
memcpy((void *) &(agg_recptr->fset_imap_eyecatcher),
2773
(void *) "fsetimap", 8);
2774
memcpy((void *) &(agg_recptr->AIT_eyecatcher), (void *) "agg ITbl", 8);
2775
memcpy((void *) &(agg_recptr->FSIT_eyecatcher), (void *) "fsetITbl", 8);
2776
memcpy((void *) &(agg_recptr->flags_eyecatcher), (void *) "aggflags",
2778
memcpy((void *) &(agg_recptr->fais.eyecatcher), (void *) "faisinfo", 8);
2779
memcpy((void *) &(agg_recptr->vlarge_info_eyecatcher),
2780
(void *) "vlargebf", 8);
2781
memcpy((void *) &(agg_recptr->fscklog_info_eyecatcher),
2782
(void *) "fscklog ", 8);
2783
memcpy((void *) &(agg_recptr->blkmp_info_eyecatcher),
2784
(void *) "blkmpbuf", 8);
2785
memcpy((void *) &(agg_recptr->ea_info_eyecatcher), (void *) "eabuffer",
2787
memcpy((void *) &(agg_recptr->iag_info_eyecatcher), (void *) "iag buf ",
2789
memcpy((void *) &(agg_recptr->mapctl_info_eyecatcher),
2790
(void *) "mapctbuf", 8);
2791
memcpy((void *) &(agg_recptr->maplf_info_eyecatcher),
2792
(void *) "maplfbuf", 8);
2793
memcpy((void *) &(agg_recptr->bmplv_info_eyecatcher),
2794
(void *) "bmplvbuf", 8);
2795
memcpy((void *) &(agg_recptr->bmpdm_info_eyecatcher),
2796
(void *) "bmpdmbuf", 8);
2797
memcpy((void *) &(agg_recptr->inobuf_info_eyecatcher),
2798
(void *) "inodebuf", 8);
2799
memcpy((void *) &(agg_recptr->nodbuf_info_eyecatcher),
2800
(void *) "node buf", 8);
2801
memcpy((void *) &(agg_recptr->dnodbuf_info_eyecatcher),
2802
(void *) "dnodebuf", 8);
2803
memcpy((void *) &(agg_recptr->agg_AGTbl_eyecatcher),
2804
(void *) "aggAGTbl", 8);
2805
memcpy((void *) &(agg_recptr->fset_AGTbl_eyecatcher),
2806
(void *) "fs AGTbl", 8);
2807
memcpy((void *) &(agg_recptr->amap_eyecatcher), (void *) "iagiamap", 8);
2808
memcpy((void *) &(agg_recptr->fextsumm_eyecatcher), (void *) "fextsumm",
2810
memcpy((void *) &(agg_recptr->finosumm_eyecatcher), (void *) "finosumm",
2813
/* do the conversions from character to UniCharacter */
2815
agg_recptr->tree_height = 0;
2816
agg_recptr->delim_char = '/';
2817
agg_recptr->UniChar_LSFN_NAME = uni_LSFN_NAME;
2818
agg_recptr->UniChar_lsfn_name = uni_lsfn_name;
2819
agg_recptr->agg_imap.ag_tbl = &(agg_recptr->agg_AGTbl[0]);
2820
agg_recptr->fset_imap.ag_tbl = &(agg_recptr->fset_AGTbl[0]);
2822
* start the messaging level out as 'show everything'
2823
* It may be reset lower when the parms have been parsed.
2825
agg_recptr->effective_msg_level = fsck_verbose;
2827
* check to see whether standard out has been redirected, and
2828
* set the flag accordingly.
2830
if (isatty(STDOUT_FILENO))
2831
agg_recptr->stdout_redirected = 0;
2833
agg_recptr->stdout_redirected = 1;
3019
2838
/****************************************************************************
3020
2839
* NAME: inorec_agg_search
3077
2881
* PARAMETERS: none
3082
2884
* success: FSCK_OK
3083
2885
* failure: something else
3085
retcode_t inorec_agg_search_insert( uint32_t inonum,
3086
fsck_inode_recptr *addr_inorecptr )
2887
int inorec_agg_search_insert(uint32_t inonum,
2888
struct fsck_inode_record **addr_inorecptr)
3088
retcode_t iasi_rc = FSCK_OK;
3089
fsck_inode_recptr new_inorecptr;
3090
int I_am_logredo = 0;
3092
*addr_inorecptr = NULL;
3093
if ( agg_recptr->AIT_ext0_tbl == NULL ) {
3094
iasi_rc = FSCK_INTERNAL_ERROR_48;
3095
sprintf( message_parm_0, "%d", iasi_rc );
3096
msgprms[0] = message_parm_0;
3098
sprintf( message_parm_1, "%d", inonum );
3099
msgprms[1] = message_parm_1;
3101
sprintf( message_parm_2, "%d", 0 );
3102
msgprms[2] = message_parm_2;
3104
sprintf( message_parm_3, "%d", 0 );
3105
msgprms[3] = message_parm_3;
3107
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
3108
} else { /* the table is initialized */
3109
if ( agg_recptr->AIT_ext0_tbl->inorectbl[inonum] == NULL ) { /* not allocated*/
3110
iasi_rc = alloc_wrksp( inode_record_length, dynstg_inorec,
3111
I_am_logredo, (void **) &new_inorecptr );
3112
if ( iasi_rc == FSCK_OK ) {
3113
new_inorecptr->inonum = inonum;
3114
agg_recptr->AIT_ext0_tbl->inorectbl[inonum] = new_inorecptr;
3117
if ( iasi_rc == FSCK_OK ) {
3118
*addr_inorecptr = agg_recptr->AIT_ext0_tbl->inorectbl[inonum];
3123
} /* end inorec_agg_search_insert() */
2890
int iasi_rc = FSCK_OK;
2891
struct fsck_inode_record *new_inorecptr;
2892
int I_am_logredo = 0;
2894
*addr_inorecptr = NULL;
2895
if (agg_recptr->AIT_ext0_tbl == NULL) {
2896
iasi_rc = FSCK_INTERNAL_ERROR_48;
2897
fsck_send_msg(fsck_INTERNALERROR, iasi_rc, inonum, 0, 0);
2899
/* the table is initialized */
2900
if (agg_recptr->AIT_ext0_tbl->inorectbl[inonum] == NULL) {
2903
alloc_wrksp(inode_record_length, dynstg_inorec,
2904
I_am_logredo, (void **) &new_inorecptr);
2905
if (iasi_rc == FSCK_OK) {
2906
new_inorecptr->inonum = inonum;
2907
agg_recptr->AIT_ext0_tbl->inorectbl[inonum] =
2911
if (iasi_rc == FSCK_OK) {
2913
agg_recptr->AIT_ext0_tbl->inorectbl[inonum];
3126
2920
/****************************************************************************
3127
2921
* NAME: inorec_fs_search
3136
2930
* PARAMETERS: none
3141
2933
* success: FSCK_OK
3142
2934
* failure: something else
3144
retcode_t inorec_fs_search( uint32_t inonum,
3145
fsck_inode_recptr *addr_inorecptr )
2936
int inorec_fs_search(uint32_t inonum, struct fsck_inode_record **addr_inorecptr)
3147
retcode_t ifs_rc = FSCK_OK;
3148
int32_t iag_in_agg, ext_in_iag, ino_in_ext;
3149
inoext_tblptr inoexttbl;
3152
*addr_inorecptr = NULL;
3153
if ( agg_recptr->FSIT_IAG_tbl == NULL ) {
3154
ifs_rc = FSCK_INTERNAL_ERROR_49;
3155
sprintf( message_parm_0, "%d", ifs_rc );
3156
msgprms[0] = message_parm_0;
3158
sprintf( message_parm_1, "%d", inonum );
3159
msgprms[1] = message_parm_1;
3161
sprintf( message_parm_2, "%d", 0 );
3162
msgprms[2] = message_parm_2;
3164
sprintf( message_parm_3, "%d", 0 );
3165
msgprms[3] = message_parm_3;
3167
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
3168
} else { /* the IAG table is initialized */
3169
locate_inode( inonum, &iag_in_agg, &ext_in_iag, &ino_in_ext );
3170
if ( iag_in_agg < agg_recptr->fset_imap.num_iags ) { /* IAG num in range */
3171
if ( agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] != NULL ) { /* ext table alloc */
3172
inoexttbl = agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg];
3173
if ( inoexttbl->inotbl[ext_in_iag] != NULL ) { /* inode table allocated */
3174
inotbl = inoexttbl->inotbl[ext_in_iag];
3175
*addr_inorecptr = inotbl->inorectbl[ino_in_ext];
3176
} /* end extent's inode table is allocated */
3177
} /* end IAG's extent table is allocated */
3178
} /* end IAG number in range */
3179
} /* end else IAG table is initialized */
3182
} /* end inorec_fs_search() */
2938
int ifs_rc = FSCK_OK;
2939
int32_t iag_in_agg, ext_in_iag, ino_in_ext;
2940
struct inode_ext_tbl_t *inoexttbl;
2941
struct inode_tbl_t *inotbl;
2943
*addr_inorecptr = NULL;
2944
if (agg_recptr->FSIT_IAG_tbl == NULL) {
2945
ifs_rc = FSCK_INTERNAL_ERROR_49;
2946
fsck_send_msg(fsck_INTERNALERROR, ifs_rc, inonum, 0, 0);
2948
/* the IAG table is initialized */
2949
locate_inode(inonum, &iag_in_agg, &ext_in_iag, &ino_in_ext);
2950
if (iag_in_agg < agg_recptr->fset_imap.num_iags) {
2951
/* IAG num in range */
2952
if (agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] !=
2954
/* ext table alloc */
2956
agg_recptr->FSIT_IAG_tbl->
2957
inoext_tbl[iag_in_agg];
2958
if (inoexttbl->inotbl[ext_in_iag] != NULL) {
2959
/* inode table allocated */
2960
inotbl = inoexttbl->inotbl[ext_in_iag];
2962
inotbl->inorectbl[ino_in_ext];
3185
2971
/****************************************************************************
3186
2972
* NAME: inorec_fs_search_insert
3193
2979
* If not found, create a record to represent the inode,
3194
2980
* insert it into the structure, and return its address.
3201
2985
* success: FSCK_OK
3202
2986
* failure: something else
3204
retcode_t inorec_fs_search_insert( uint32_t inonum,
3205
fsck_inode_recptr *addr_inorecptr )
2988
int inorec_fs_search_insert(uint32_t inonum,
2989
struct fsck_inode_record **addr_inorecptr)
3207
retcode_t ifsi_rc = FSCK_OK;
3208
int32_t iag_in_agg, ext_in_iag, ino_in_ext;
3209
inoext_tblptr inoexttbl = 0, new_inoexttbl;
3210
ino_tblptr inotbl = 0, new_inotbl;
3211
fsck_inode_recptr new_inorecptr;
3212
int I_am_logredo = 0;
3214
*addr_inorecptr = NULL;
3215
if ( agg_recptr->FSIT_IAG_tbl == NULL ) {
3216
ifsi_rc = FSCK_INTERNAL_ERROR_67;
3217
sprintf( message_parm_0, "%d", ifsi_rc );
3218
msgprms[0] = message_parm_0;
3220
sprintf( message_parm_1, "%d", inonum );
3221
msgprms[1] = message_parm_1;
3223
sprintf( message_parm_2, "%d", 0 );
3224
msgprms[2] = message_parm_2;
3226
sprintf( message_parm_3, "%d", 0 );
3227
msgprms[3] = message_parm_3;
3229
fsck_send_msg( fsck_INTERNALERROR, 0, 4 );
3230
} else { /* the IAG table is initialized */
3231
locate_inode( inonum, &iag_in_agg, &ext_in_iag, &ino_in_ext );
3232
if ( iag_in_agg < agg_recptr->fset_imap.num_iags ) {
3234
* the IAG number is in range
3236
if ( agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] == NULL ) {
3238
* extent table not allocated
3240
ifsi_rc = alloc_wrksp( inode_ext_tbl_length, dynstg_inoexttbl,
3241
I_am_logredo, (void **) &new_inoexttbl );
3242
if ( ifsi_rc == FSCK_OK ) {
3243
memcpy( (void *) &(new_inoexttbl->eyecatcher),
3244
(void *) "InoExTbl", 8 );
3245
agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] =
3248
} /* end IAG's extent table is not allocated */
3250
if ( ifsi_rc == FSCK_OK ) {
3251
inoexttbl = agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg];
3253
if ( inoexttbl->inotbl[ext_in_iag] == NULL ) {
3255
* the inode table is not allocated
3257
ifsi_rc = alloc_wrksp( inode_tbl_length, dynstg_inotbl,
3258
I_am_logredo, (void **) &new_inotbl );
3259
if ( ifsi_rc == FSCK_OK ) {
3260
memcpy( (void *) &(new_inotbl->eyecatcher),
3261
(void *) "InodeTbl", 8 );
3262
inoexttbl->inotbl[ext_in_iag] = new_inotbl;
3264
} /* end extent's inode table is not allocated */
3267
if ( ifsi_rc == FSCK_OK ) {
3268
inotbl = inoexttbl->inotbl[ext_in_iag];
3270
if ( inotbl->inorectbl[ino_in_ext] == NULL ) {
3272
* the inode record is not allocated
3274
ifsi_rc = alloc_wrksp( inode_record_length, dynstg_inorec,
3275
I_am_logredo, (void **) &new_inorecptr );
3276
if ( ifsi_rc == FSCK_OK ) {
3277
new_inorecptr->inonum = inonum;
3278
inotbl->inorectbl[ino_in_ext] = new_inorecptr;
3280
} /* end inode record not allocated */
3283
if ( ifsi_rc == FSCK_OK ) {
3284
*addr_inorecptr = inotbl->inorectbl[ino_in_ext];
3286
} /* end IAG number in range */
3287
} /* end else IAG table is initialized */
3290
} /* end inorec_fs_search_insert() */
2991
int ifsi_rc = FSCK_OK;
2992
int32_t iag_in_agg, ext_in_iag, ino_in_ext;
2993
struct inode_ext_tbl_t *inoexttbl = 0;
2994
struct inode_ext_tbl_t *new_inoexttbl;
2995
struct inode_tbl_t *inotbl = 0;
2996
struct inode_tbl_t *new_inotbl;
2997
struct fsck_inode_record *new_inorecptr;
2998
int I_am_logredo = 0;
3000
*addr_inorecptr = NULL;
3001
if (agg_recptr->FSIT_IAG_tbl == NULL) {
3002
ifsi_rc = FSCK_INTERNAL_ERROR_67;
3003
fsck_send_msg(fsck_INTERNALERROR, ifsi_rc, inonum, 0, 0);
3007
/* the IAG table is initialized */
3008
locate_inode(inonum, &iag_in_agg, &ext_in_iag, &ino_in_ext);
3009
if (iag_in_agg >= agg_recptr->fset_imap.num_iags)
3013
* the IAG number is in range
3015
if (agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] == NULL) {
3017
* extent table not allocated
3019
ifsi_rc = alloc_wrksp(inode_ext_tbl_length, dynstg_inoexttbl,
3020
I_am_logredo, (void **) &new_inoexttbl);
3021
if (ifsi_rc == FSCK_OK) {
3022
memcpy((void *)&(new_inoexttbl->eyecatcher),
3023
(void *) "InoExTbl", 8);
3024
agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg] =
3028
if (ifsi_rc == FSCK_OK) {
3029
inoexttbl = agg_recptr->FSIT_IAG_tbl->inoext_tbl[iag_in_agg];
3031
if (inoexttbl->inotbl[ext_in_iag] == NULL) {
3033
* the inode table is not allocated
3035
ifsi_rc = alloc_wrksp(inode_tbl_length, dynstg_inotbl,
3037
(void **) &new_inotbl);
3038
if (ifsi_rc == FSCK_OK) {
3039
memcpy((void *)&(new_inotbl->eyecatcher),
3040
(void *) "InodeTbl", 8);
3041
inoexttbl->inotbl[ext_in_iag] = new_inotbl;
3046
if (ifsi_rc == FSCK_OK) {
3047
inotbl = inoexttbl->inotbl[ext_in_iag];
3049
if (inotbl->inorectbl[ino_in_ext] == NULL) {
3051
* the inode record is not allocated
3053
ifsi_rc = alloc_wrksp(inode_record_length,
3056
(void **)&new_inorecptr);
3057
if (ifsi_rc == FSCK_OK) {
3058
new_inorecptr->inonum = inonum;
3059
inotbl->inorectbl[ino_in_ext] = new_inorecptr;
3064
if (ifsi_rc == FSCK_OK) {
3065
*addr_inorecptr = inotbl->inorectbl[ino_in_ext];
3293
3072
/****************************************************************************
3294
3073
* NAME: locate_inode
3352
3126
* desired_action - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK |
3353
3127
* FSCK_UNRECORD | FSCK_QUERY }
3358
3130
* success: FSCK_OK
3359
3131
* failure: something else
3361
retcode_t process_extent ( fsck_inode_recptr inorecptr,
3362
reg_idx_t extent_length,
3363
fsblkidx_t extent_addr,
3366
fsck_msg_info_ptr msg_info_ptr,
3367
reg_idx_t *adjusted_length,
3368
int8_t *extent_is_valid,
3369
int desired_action )
3133
int process_extent(struct fsck_inode_record *inorecptr,
3134
uint32_t extent_length,
3135
int64_t extent_addr,
3138
struct fsck_ino_msg_info *msg_info_ptr,
3139
uint32_t * adjusted_length,
3140
int8_t * extent_is_valid, int desired_action)
3371
retcode_t ve_rc = FSCK_OK;
3372
fsblkidx_t first_valid;
3373
fsblkidx_t last_valid;
3374
int8_t range_adjusted = 0;
3376
if ( inorecptr->inode_type == metadata_inode ) {
3377
first_valid = extent_addr;
3379
first_valid = (extent_addr < agg_recptr->lowest_valid_fset_datablk)
3380
? agg_recptr->lowest_valid_fset_datablk
3384
((extent_addr + extent_length) >
3385
agg_recptr->highest_valid_fset_datablk)
3386
? agg_recptr->highest_valid_fset_datablk
3387
: extent_addr + extent_length -1;
3389
if ( ( (first_valid > agg_recptr->highest_valid_fset_datablk) &&
3390
(inorecptr->inode_type != metadata_inode) ) || /*
3391
* starts after end of valid fset area AND
3392
* isn't a meta data inode OR
3394
( (last_valid < agg_recptr->lowest_valid_fset_datablk) &&
3395
(inorecptr->inode_type != metadata_inode) ) || /*
3396
* ends before the beginning of valid fset area AND
3397
* isn't a meta data inode OR
3399
(last_valid < first_valid) ) { /* ends before it starts */
3400
*adjusted_length = 0;
3401
*extent_is_valid = 0;
3402
if ( is_EA ) { /* this is an extended attributes extent */
3403
inorecptr->clr_ea_fld = 1;
3404
inorecptr->ignore_ea_blks = 1;
3405
agg_recptr->corrections_needed = 1;
3406
} else if ( is_ACL ) { /* this is an access control list extent */
3407
inorecptr->clr_acl_fld = 1;
3408
inorecptr->ignore_acl_blks = 1;
3409
agg_recptr->corrections_needed = 1;
3410
} else { /* either a node (internal or leaf) or data */
3411
inorecptr->selected_to_rls = 1;
3412
inorecptr->ignore_alloc_blks = 1;
3413
agg_recptr->corrections_needed = 1;
3414
} /* end either a node (internal or leaf) or data */
3415
} else { /* not out of the question */
3416
*adjusted_length = last_valid - first_valid + 1;
3417
if ( (first_valid != extent_addr) ||
3418
(last_valid != (extent_addr + extent_length - 1)) ) {
3420
* blocks are not valid for the fileset
3422
range_adjusted = -1;
3423
*extent_is_valid = 0;
3424
if ( is_EA ) { /* this is an extended attributes extent */
3425
inorecptr->clr_ea_fld = 1;
3426
agg_recptr->corrections_needed = 1;
3427
} else if ( is_ACL ) { /* this is an access control list extent */
3428
inorecptr->clr_acl_fld = 1;
3429
agg_recptr->corrections_needed = 1;
3430
} else { /* either a node (internal or leaf) or data */
3431
inorecptr->selected_to_rls = 1;
3432
agg_recptr->corrections_needed = 1;
3433
} /* end either a node (internal or leaf) or data */
3434
} else { /* else the extent is ok */
3435
*extent_is_valid = -1;
3436
} /* end else the extent is ok */
3438
* Finally, depending on the parm passed by the caller,
3440
* either: record the ownership of the blocks which are within
3441
* range and keep a count of multiply allocated blocks.
3443
* or: reverse notations made in the workspace for the ownership
3444
* of blocks which are within range and decrement the count
3445
* of multiply allocated blocks.
3447
* or: check the extent to see if it contains the first reference
3448
* to any multiply allocated block for which the first
3449
* reference is still unresolved.
3451
switch ( desired_action ) {
3453
ve_rc = extent_record( first_valid, last_valid );
3455
case FSCK_RECORD_DUPCHECK:
3456
ve_rc = extent_record_dupchk( first_valid, last_valid,
3457
range_adjusted, is_EA, is_ACL,
3458
msg_info_ptr, inorecptr );
3461
ve_rc = extent_unrecord( first_valid, last_valid );
3464
ve_rc = extent_1stref_chk( first_valid, last_valid,
3465
is_EA, is_ACL, msg_info_ptr, inorecptr );
3468
ve_rc = FSCK_INTERNAL_ERROR_7; /* shouldn't ever get here */
3470
} /* end else not out of the question */
3473
} /* end of process_extent () */
3142
int ve_rc = FSCK_OK;
3143
int64_t first_valid;
3145
int8_t range_adjusted = 0;
3147
if (inorecptr->inode_type == metadata_inode) {
3148
first_valid = extent_addr;
3151
(extent_addr < agg_recptr->lowest_valid_fset_datablk)
3152
? agg_recptr->lowest_valid_fset_datablk : extent_addr;
3155
((extent_addr + extent_length) >
3156
agg_recptr->highest_valid_fset_datablk)
3157
? agg_recptr->highest_valid_fset_datablk : extent_addr +
3160
if (((first_valid > agg_recptr->highest_valid_fset_datablk)
3161
&& (inorecptr->inode_type != metadata_inode)) ||
3163
* starts after end of valid fset area AND
3164
* isn't a meta data inode OR
3166
((last_valid < agg_recptr->lowest_valid_fset_datablk)
3167
&& (inorecptr->inode_type != metadata_inode)) ||
3169
* ends before the beginning of valid fset area AND
3170
* isn't a meta data inode OR
3172
(last_valid < first_valid)) {
3173
/* ends before it starts */
3175
*adjusted_length = 0;
3176
*extent_is_valid = 0;
3178
/* this is an extended attributes extent */
3179
inorecptr->clr_ea_fld = 1;
3180
inorecptr->ignore_ea_blks = 1;
3181
agg_recptr->corrections_needed = 1;
3182
} else if (is_ACL) {
3183
/* this is an access control list extent */
3184
inorecptr->clr_acl_fld = 1;
3185
inorecptr->ignore_acl_blks = 1;
3186
agg_recptr->corrections_needed = 1;
3188
/* either a node (internal or leaf) or data */
3189
inorecptr->selected_to_rls = 1;
3190
inorecptr->ignore_alloc_blks = 1;
3191
agg_recptr->corrections_needed = 1;
3194
/* not out of the question */
3195
*adjusted_length = last_valid - first_valid + 1;
3196
if ((first_valid != extent_addr) ||
3197
(last_valid != (extent_addr + extent_length - 1))) {
3199
* blocks are not valid for the fileset
3201
range_adjusted = -1;
3202
*extent_is_valid = 0;
3204
/* this is an extended attributes extent */
3205
inorecptr->clr_ea_fld = 1;
3206
agg_recptr->corrections_needed = 1;
3207
} else if (is_ACL) {
3208
/* this is an access control list extent */
3209
inorecptr->clr_acl_fld = 1;
3210
agg_recptr->corrections_needed = 1;
3212
/* either a node (internal or leaf) or data */
3213
inorecptr->selected_to_rls = 1;
3214
agg_recptr->corrections_needed = 1;
3217
/* else the extent is ok */
3218
*extent_is_valid = -1;
3221
* Finally, depending on the parm passed by the caller,
3223
* either: record the ownership of the blocks which are within
3224
* range and keep a count of multiply allocated blocks.
3226
* or: reverse notations made in the workspace for the ownership
3227
* of blocks which are within range and decrement the count
3228
* of multiply allocated blocks.
3230
* or: check the extent to see if it contains the first reference
3231
* to any multiply allocated block for which the first
3232
* reference is still unresolved.
3234
switch (desired_action) {
3236
ve_rc = extent_record(first_valid, last_valid);
3238
case FSCK_RECORD_DUPCHECK:
3239
ve_rc = extent_record_dupchk(first_valid, last_valid,
3240
range_adjusted, is_EA,
3241
is_ACL, msg_info_ptr,
3245
ve_rc = extent_unrecord(first_valid, last_valid);
3248
ve_rc = extent_1stref_chk(first_valid, last_valid,
3249
is_EA, is_ACL, msg_info_ptr,
3253
ve_rc = FSCK_INTERNAL_ERROR_7;
3476
3260
/****************************************************************************
3477
3261
* NAME: release_inode_extension
3891
3652
* PARAMETERS: none
3896
3655
* success: FSCK_OK
3897
3656
* failure: something else
3899
retcode_t workspace_release ( )
3658
int workspace_release()
3901
retcode_t wr_rc = FSCK_OK;
3902
wsp_ext_rec_ptr this_fer, next_fer;
3904
* If the very large buffer is (still) allocated, release it.
3906
if ( agg_recptr->vlarge_buf_ptr != NULL ) {
3907
free( (void *) agg_recptr->vlarge_buf_ptr );
3908
agg_recptr->vlarge_buf_ptr = NULL;
3909
agg_recptr->ea_buf_ptr = NULL;
3910
agg_recptr->recon_buf_extent = NULL;
3913
* release the allocated extents
3915
this_fer = agg_recptr->wsp_extent_list;
3916
while ( this_fer != NULL ) { /* for each extent record */
3917
next_fer = this_fer->next; /* the one after this one (if any) */
3918
if ( ! this_fer->from_high_memory ) {
3919
free( (void *) this_fer->extent_addr ); /* free the extent this
3920
* fer describes (and occupies)
3923
this_fer = next_fer; /* go on to the next one in the list */
3924
} /* end for each extent record */
3660
int wr_rc = FSCK_OK;
3661
struct wsp_ext_rec *this_fer;
3662
struct wsp_ext_rec *next_fer;
3664
* If the very large buffer is (still) allocated, release it.
3666
if (agg_recptr->vlarge_buf_ptr != NULL) {
3667
free((void *) agg_recptr->vlarge_buf_ptr);
3668
agg_recptr->vlarge_buf_ptr = NULL;
3669
agg_recptr->ea_buf_ptr = NULL;
3670
agg_recptr->recon_buf_extent = NULL;
3673
* release the allocated extents
3675
this_fer = agg_recptr->wsp_extent_list;
3676
while (this_fer != NULL) {
3677
/* for each extent record */
3678
/* the one after this one (if any) */
3679
next_fer = this_fer->next;
3680
if (!this_fer->from_high_memory) {
3681
/* free the extent this
3682
* fer describes (and occupies)
3684
free((void *) this_fer->extent_addr);
3686
/* go on to the next one in the list */
3687
this_fer = next_fer;
3927
} /* end of workspace_release () */