📄 fsckwsp.c
字号:
fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); dio_rc = dupall_insert_blkrec( first_in_dup_range, first_in_dup_range + size_of_dup_range - 1, NULL); if (dio_rc) return dio_rc; agg_recptr->dup_block_count++; agg_recptr->unresolved_1stref_count++; size_of_dup_range = 0; first_in_dup_range = 0; is_a_dup = 1; } } else { /* already allocated */ if (!size_of_dup_range++) first_in_dup_range = blk_num; } } if (last_page_num != -1) blkmap_put_page(last_page_num); /* Record duplicate range */ if (size_of_dup_range) { if (msg_info_ptr) fsck_send_msg(fsck_DUPBLKREF, size_of_dup_range, (long long) first_in_dup_range, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); dio_rc = dupall_insert_blkrec(first_in_dup_range, first_in_dup_range + size_of_dup_range - 1, NULL); if (dio_rc) return dio_rc; agg_recptr->dup_block_count++; agg_recptr->unresolved_1stref_count++; is_a_dup = 1; } return (is_a_dup);}/**************************************************************************** * NAME: blkall_split_blkrec * * FUNCTION: Split the current duplicate block record * * PARAMETERS: * blkrec - input - duplicate block record to be split * first_block - input - first block of range whose intersection with * blkrec causes the split * last_block - input - last block of range whose intersection with * blkrec causes the split * RETURNS: * success: FSCK_OK * failure: something else */int blkall_split_blkrec(struct dupall_blkrec *blkrec, int64_t first_block, int64_t last_block){ int bsb_rc = FSCK_OK; struct dupall_blkrec *new_blkrec; int64_t temp; if (blkrec->first_blk < first_block) { temp = blkrec->last_blk; blkrec->last_blk = first_block - 1; bsb_rc = dupall_insert_blkrec(first_block, temp, &new_blkrec); if (bsb_rc) return bsb_rc; new_blkrec->first_ref_resolved = blkrec->first_ref_resolved; new_blkrec->owner_count = blkrec->owner_count; agg_recptr->dup_block_count++; if (!new_blkrec->first_ref_resolved) agg_recptr->unresolved_1stref_count++; blkrec = new_blkrec; } if (blkrec->last_blk > last_block) { temp = blkrec->last_blk; blkrec->last_blk = last_block; bsb_rc = dupall_insert_blkrec(first_block, temp, &new_blkrec); if (bsb_rc) return bsb_rc; new_blkrec->first_ref_resolved = blkrec->first_ref_resolved; new_blkrec->owner_count = blkrec->owner_count; agg_recptr->dup_block_count++; if (!new_blkrec->first_ref_resolved) agg_recptr->unresolved_1stref_count++; } return FSCK_OK;}/**************************************************************************** * NAME: dire_buffer_alloc * * FUNCTION: Allocate an I/O buffer for use during directory entry insertion * and removal processing. * * PARAMETERS: * addr_dnode_ptr - input - pointer to a variable in which to return * the address of the allocated buffer (or * NULL if no buffer could be allocated) * * RETURNS: * success: FSCK_OK * failure: something else */int dire_buffer_alloc(dtpage_t ** addr_dnode_ptr){ int rba_rc = FSCK_OK; uint32_t bufrec_length, bytes_available; struct recon_buf_record *bufrec_ptr; if (agg_recptr->recon_buf_stack != NULL) { /* stack not empty */ bufrec_ptr = agg_recptr->recon_buf_stack; agg_recptr->recon_buf_stack = bufrec_ptr->stack_next; bufrec_ptr->stack_next = NULL; bufrec_ptr->dnode_blkoff = 0; bufrec_ptr->dnode_byteoff = 0; *addr_dnode_ptr = &(bufrec_ptr->dnode_buf); } else { /* the stack is empty */ bufrec_length = sizeof (struct recon_buf_record); bytes_available = agg_recptr->recon_buf_extent->extent_length - agg_recptr->recon_buf_extent->last_byte_used; if (bytes_available < bufrec_length) { /* we've used up a whole * extent of dynamic storage -- something * strange is going on */ *addr_dnode_ptr = NULL; rba_rc = FSCK_INSUFDSTG4RECON; } else { /* there is enough dynamic storage for another one */ bufrec_ptr = (struct recon_buf_record *) (agg_recptr->recon_buf_extent->extent_addr + agg_recptr->recon_buf_extent->last_byte_used + 1); agg_recptr->recon_buf_extent->last_byte_used += bufrec_length; /* * now initialize the record */ wsp_dynstg_object = dynstg_recondnodebuf; wsp_dynstg_action = dynstg_initialization; memset((void *) bufrec_ptr, 0, bufrec_length); *addr_dnode_ptr = &(bufrec_ptr->dnode_buf); } } return (rba_rc);}/**************************************************************************** * NAME: dire_buffer_release * * FUNCTION: Deallocate (make available for reuse) an I/O buffer for used * during directory entry insertion and removal processing. * * PARAMETERS: * dnode_ptr - input - the address of the buffer to release * * RETURNS: * success: FSCK_OK * failure: something else */int dire_buffer_release(dtpage_t * dnode_ptr){ int rbr_rc = FSCK_OK; struct recon_buf_record *bufrec_ptr; bufrec_ptr = (struct recon_buf_record *) dnode_ptr; bufrec_ptr->stack_next = agg_recptr->recon_buf_stack; agg_recptr->recon_buf_stack = bufrec_ptr; return (rbr_rc);}/**************************************************************************** * NAME: directory_buffers_alloc * * FUNCTION: Allocate storage for use as I/O buffers while inserting and * removing directory entries during file system repair processing. * FUNCTION: Make use of the VeryLarge Multi-Use Buffer for * I/O buffers while inserting and removing directory entries * during file system repair processing. * * NOTES: The directory buffers are the only use of the VeryLarge Buffer * during Phase 6 processing. * * PARAMETERS: none * * NOTES: The address of the storage allocated for this purpose is stored * in the aggregate record, field: recon_buf_extent * * RETURNS: * success: FSCK_OK * failure: something else */int directory_buffers_alloc(){ int dba_rc = FSCK_OK; agg_recptr->vlarge_current_use = USED_FOR_DIRPAGE_BUFS; agg_recptr->recon_buf_extent = (struct wsp_ext_rec *) agg_recptr->vlarge_buf_ptr; agg_recptr->recon_buf_extent->next = NULL; agg_recptr->recon_buf_extent->extent_length = agg_recptr->vlarge_buf_length; agg_recptr->recon_buf_extent->extent_addr = (char *) agg_recptr->recon_buf_extent; agg_recptr->recon_buf_extent->last_byte_used = sizeof (struct wsp_ext_rec) - 1; return (dba_rc);}/**************************************************************************** * NAME: directory_buffers_release * * FUNCTION: Free storage which was allocated for use as I/O buffers while * inserting and removing directory entries during file system * repair processing. * * PARAMETERS: none * * NOTES: The address of the storage allocated for this purpose is stored * in the aggregate record, field: recon_buf_extent * * RETURNS: * success: FSCK_OK * failure: something else */int directory_buffers_release(){ int dbr_rc = FSCK_OK; if (agg_recptr->recon_buf_extent != NULL) { /* something is allocated */ agg_recptr->recon_buf_extent = NULL; agg_recptr->vlarge_current_use = NOT_CURRENTLY_USED; } return (dbr_rc);}/**************************************************************************** * NAME: dtreeQ_dequeue * * FUNCTION: If the directory tree queue is not empty, remove the front * element and return a pointer to it. Otherwise, return NULL. * * PARAMETERS: * dtreeQ_elptr - input - pointer to a variable in which the address of * the front queue element should be returned * * NOTES: The directory tree queue is described in the aggregate record, * fields: dtreeQ_front, dtreeQ_back * * RETURNS: * success: FSCK_OK * failure: something else */int dtreeQ_dequeue(struct dtreeQelem **dtreeQ_elptr){ int dQd_rc = FSCK_OK; *dtreeQ_elptr = agg_recptr->dtreeQ_front; if (agg_recptr->dtreeQ_back == agg_recptr->dtreeQ_front) { /* empty */ agg_recptr->dtreeQ_back = agg_recptr->dtreeQ_front = NULL; } else { /* not empty */ agg_recptr->dtreeQ_front = agg_recptr->dtreeQ_front->next; agg_recptr->dtreeQ_front->prev = NULL; } return (dQd_rc);}/**************************************************************************** * NAME: dtreeQ_enqueue * * FUNCTION: Adds the given element to the back of the directory tree queue. * * PARAMETERS: * dtreeQ_elptr - input - address of the element to add to the queue. * * NOTES: The directory tree queue is described in the aggregate record, * fields: dtreeQ_front, dtreeQ_back * * RETURNS: * success: FSCK_OK * failure: something else */int dtreeQ_enqueue(struct dtreeQelem *dtreeQ_elptr){ int dQe_rc = FSCK_OK; if (agg_recptr->dtreeQ_back == NULL) { /* empty queue */ agg_recptr->dtreeQ_back = agg_recptr->dtreeQ_front = dtreeQ_elptr; dtreeQ_elptr->prev = dtreeQ_elptr->next = NULL; } else { /* queue not empty */ dtreeQ_elptr->next = NULL; dtreeQ_elptr->prev = agg_recptr->dtreeQ_back; agg_recptr->dtreeQ_back->next = dtreeQ_elptr; agg_recptr->dtreeQ_back = dtreeQ_elptr; } return (dQe_rc);}/**************************************************************************** * NAME: dtreeQ_get_elem * * FUNCTION: Allocates workspace storage for an fsck directory tree queue element * * PARAMETERS: * addr_dtreeQ_ptr - input - pointer to a variable in which the address * of the new element should be returned. * * RETURNS: * success: FSCK_OK * failure: something else */int dtreeQ_get_elem(struct dtreeQelem **addr_dtreeQ_ptr){ int dge_rc = FSCK_OK; int I_am_logredo = 0; if (agg_recptr->free_dtreeQ != NULL) { /* free list isn't empty */ *addr_dtreeQ_ptr = agg_recptr->free_dtreeQ; agg_recptr->free_dtreeQ = agg_recptr->free_dtreeQ->next; memset((void *) (*addr_dtreeQ_ptr), 0, dtreeQ_elem_length); } else { /* else the free list is empty */ dge_rc = alloc_wrksp(dtreeQ_elem_length, dynstg_dtreeQ_elem, I_am_logredo, (void **) addr_dtreeQ_ptr); } return (dge_rc);}/**************************************************************************** * NAME: dtreeQ_rel_elem * * FUNCTION: Makes an fsck directory tree queue element available for reuse * * PARAMETERS: * dtreeQ_elptr - input - the address of the element to release * * RETURNS: * success: FSCK_OK * failure: something else */int dtreeQ_rel_elem(struct dtreeQelem *dtreeQ_elptr){ int dQre_rc = FSCK_OK; dtreeQ_elptr->next = agg_recptr->free_dtreeQ; agg_recptr->free_dtreeQ = dtreeQ_elptr; return (dQre_rc);}/**************************************************************************** * NAME: dupall_extract_blkrec * * FUNCTION: Remove the given (previously found) record from the list of * duplicate allocation block records. * * PARAMETERS: * block_recptr - input - the address of the record to remove * * NOTES: The duplicate allocation list is described in the aggregate record, * field: dup_alloc_lst */void dupall_extract_blkrec(struct dupall_blkrec *block_recptr){ /* * remove it from the list of multiply-allocated block */ if (block_recptr->prev) block_recptr->prev->next = block_recptr->next; else /* first in list */ agg_recptr->dup_alloc_lst = block_recptr->next; if (block_recptr->next) block_recptr->next->prev = block_recptr->prev; /* * release it for reuse */ block_recptr->next = agg_recptr->free_dupall_blkrec; agg_recptr->free_dupall_blkrec = block_recptr;}/**************************************************************************** * NAME: dupall_find_blkrec * * FUNCTION: Search for a record with the given block number in the duplicate * allocation list. * * PARAMETERS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -