Esempio n. 1
0
/**
 * @brief Removes a file block from
 * the binary tree of all file blocks.
 * @return Zero for success, 
 * negative value otherwise.
 */
int remove_block_from_file_blocks_tree(udefrag_job_parameters *jp, winx_blockmap *block)
{
    struct file_block *fb;
    struct file_block b;
    
    if(block == NULL)
        return (-1);
    
    if(jp->file_blocks == NULL)
        return (-1);

    b.file = NULL;
    b.block = block;
    fb = prb_delete(jp->file_blocks,&b);
    if(fb == NULL){
        /* the following debugging output indicates either
           a bug, or file system inconsistency */
        etrace("failed for %p: VCN = %I64u, LCN = %I64u, LEN = %I64u",
            block, block->vcn, block->lcn, block->length);
        /* if block does not exist in tree, we have nothing to cleanup */
        return 0;
    }
    winx_free(fb);
    return 0;
}
Esempio n. 2
0
/**
 * @brief Searches for the first movable file block
 * after the specified cluster on the volume.
 * @param[in] jp job parameters.
 * @param[in,out] min_lcn pointer to variable containing
 * minimum LCN - file blocks below it will be ignored.
 * @param[in] flags one of SKIP_xxx flags defined in udefrag.h
 * @param[out] first_file pointer to variable receiving information
 * about the file the first block belongs to.
 * @return Pointer to the first block. NULL indicates failure.
 */
winx_blockmap *find_first_block(udefrag_job_parameters *jp,
    ULONGLONG *min_lcn, int flags, winx_file_info **first_file)
{
    winx_file_info *found_file;
    winx_blockmap *first_block;
    winx_blockmap b;
    struct file_block fb, *item;
    struct prb_traverser t;
    int movable_file;
    ULONGLONG tm = winx_xtime();
    
    if(min_lcn == NULL || first_file == NULL)
        return NULL;
    
    found_file = NULL; first_block = NULL;
    b.lcn = *min_lcn; fb.block = &b;
    prb_t_init(&t,jp->file_blocks);
    item = prb_t_insert(&t,jp->file_blocks,&fb);
    if(item == &fb){
        /* block at min_lcn not found */
        item = prb_t_next(&t);
        if(prb_delete(jp->file_blocks,&fb) == NULL){
            etrace("cannot remove block from the tree");
            winx_flush_dbg_log(0); /* 'cause error is critical */
        }
    }
    if(item){
        found_file = item->file;
        first_block = item->block;
    }
    while(!jp->termination_router((void *)jp)){
        if(found_file == NULL) break;
        if(flags & SKIP_PARTIALLY_MOVABLE_FILES){
            movable_file = can_move_entirely(found_file,jp);
        } else {
            movable_file = can_move(found_file,jp);
        }
        if(is_file_locked(found_file,jp)) movable_file = 0;
        if(movable_file){
            if(jp->is_fat && is_directory(found_file) && first_block == found_file->disp.blockmap){
                /* skip first fragments of FAT directories */
            } else {
                /* desired block found */
                *min_lcn = first_block->lcn + 1; /* the current block will be skipped later anyway in this case */
                *first_file = found_file;
                jp->p_counters.searching_time += winx_xtime() - tm;
                return first_block;
            }
        }
        
        /* skip current block */
        *min_lcn = *min_lcn + 1;
        /* and go to the next one */
        item = prb_t_next(&t);
        if(item == NULL) break;
        found_file = item->file;
        first_block = item->block;
    }
    *first_file = NULL;
    jp->p_counters.searching_time += winx_xtime() - tm;
    return NULL;
}
Esempio n. 3
0
/**
 * @brief Removes file from the list of fragmented files.
 */
void truncate_fragmented_files_list(winx_file_info *f,udefrag_job_parameters *jp)
{
    if(!prb_delete(jp->fragmented_files,(void *)f))
        etrace("%ws is not found in the tree",f->path);
}