📄 apiext.c
字号:
/* We found a large enough contiguos group of clusters */
/* Turn them into a chain */
clno = first_cluster;
for (i = 0; i < (n_clusters-1); i++, clno++)
{
/* Link the current cluster to the next one */
ret_stat = pc_pfaxx(pdr, clno, (UINT32) (clno+1));
if (ret_stat != NU_SUCCESS)
goto alloc_done;
}
/* Terminate the list */
ret_stat = pc_pfaxx(pdr, clno, ((UINT32)-1));
if (ret_stat != NU_SUCCESS)
goto alloc_done;
if (last_cluster_in_chain)
{
/* The file already has clusters in it. Append our new chain */
ret_stat = pc_pfaxx(pdr, last_cluster_in_chain, first_cluster);
if (ret_stat != NU_SUCCESS)
goto alloc_done;
}
else
{
/* Put our chain into the directory entry */
pfile->pobj->finode->fcluster = first_cluster;
/* Use synch_pointers to set our file pointers up */
pfile->fptr_cluster = 0L; /* This is already true but... */
pfile->fptr_block = 0L;
pfile->fptr = 0L;
}
/* Now recalculate the file size */
ltemp = n_clusters;
ltemp <<= (pdr->log2_secpalloc + 9);
pfile->pobj->finode->fsize += ltemp;
/* call synch to take care of both the eof condition and the case where
we just alloced the beginning of the chain */
_synch_file_ptrs(pfile);
/* Flush the fat */
ret_stat = pc_flushfat(pdr);
if (ret_stat != NU_SUCCESS)
goto alloc_done;
/* Write the directory entry */
ret_stat = pc_update_inode(pfile->pobj, DSET_UPDATE);
if (ret_stat != NU_SUCCESS)
goto alloc_done;
/* It worked ! Set the return to the number of clusters requested */
ret_val = n_clusters;
fs_user->p_errno = 0;
/* All code exits through here. ret_val determines if the function was
successful. If 0xffff it's an error. If n_clusters it's a success and
the file is expanded. Otherwise the return value */
alloc_done:
PC_FAT_EXIT(pdr->driveno)
PC_INODE_EXIT(pfile->pobj->finode)
PC_DRIVE_EXIT(pdr->driveno)
return_error:
/* Restore the kernel state */
PC_FS_EXIT()
return(ret_val);
}
/************************************************************************
* FUNCTION
*
* po_extend_file
*
* DESCRIPTION
*
* Using the provided method, search the FAT from start_pt to the
* end for a free contiguous chain of at least MIN_CLUSTERS. If
* less than MIN_CLUSTERS are found the largest free chain in the
* region is returned.
*
* There are three possible methods:
* PC_FIRST_FIT - The first free chain >= MIN_CLUSTERS is returned
* PC_BEST_FIT - The smallest chain >= MIN_CLUSTERS is returned
* PC_WORST_FIT - The largest chain >= MIN_CLUSTERS is returned
*
* Choose the method that will work best for you.
*
* Note: The chain is not created. The caller must convert the
* clusters to an allocated chain.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* pdr Drive management structure
* startpt Search start cluster
* pchain Free chain pointer
* min_clusters Minimum chain clusters
* method Method 丂
*
* OUTPUTS
*
* Returns the number of contiguous clusters found up to
* MIN_CLUSTERS. *pchain contains the cluster number at the
* beginning of the chain.
* On error return 0xffff
* Example:
* Get the largest free chain on the disk:
* large =
* pc_find_contig_clusters(pdr, 2, &chain, 0xffff, PC_FIRST_FIT);
*
*************************************************************************/
UINT32 pc_find_contig_clusters(DDRIVE *pdr, UINT32 startpt, UINT32 *pchain,
UINT32 min_clusters, INT16 method) /* __fn__ */
{
STATUS ret_stat;
UINT32 i;
UINT32 value;
UINT32 best_chain;
UINT32 best_size;
UINT32 chain_start;
UINT32 chain_size;
UINT32 largest_size;
UINT32 largest_chain;
UINT32 endpt;
best_chain = 0;
best_size = 0;
chain_start = 0;
chain_size = 0;
largest_size = 0;
largest_chain = 0;
endpt = pdr->maxfindex;
for (i = startpt; i <= endpt; i++)
{
ret_stat = pc_faxx(pdr, i, &value);
if (ret_stat != NU_SUCCESS)
return((UINT32) -1); /* IO error .. oops */
if (value == 0)
{
/* Cluster is free. Run some tests on it. */
if (chain_start)
{
/* We're in a contiguous region already. Bump the count */
chain_size++;
}
else
{
/* Just starting a contiguous region */
chain_size = 1;
chain_start = i;
}
/* If using first fit see if we crossed the threshold */
if (method == PC_FIRST_FIT)
{
if (chain_size >= min_clusters)
{
best_chain = chain_start;
best_size = chain_size;
break;
}
}
} /* if value == 0*/
/* Did we just finish scanning a contiguous chain ?? */
if ( chain_size && ((value != 0) || (i == endpt)) )
{
/* Remember the largest chain */
if (chain_size > largest_size)
{
largest_size = chain_size;
largest_chain = chain_start;
}
if (method == PC_BEST_FIT)
{
if (chain_size == min_clusters)
{
/* The chain is exactly the size we need take it. */
best_chain = chain_start;
best_size = chain_size;
break;
}
if (chain_size > min_clusters)
{
if ( !best_chain || (chain_size < best_size) )
{
/* Chain is closest to what we need so far note it. */
best_size = chain_size;
best_chain = chain_start;
}
}
} /* if BEST_FIT */
else if (method == PC_WORST_FIT)
{
if (chain_size >= min_clusters)
{
if ( !best_chain || chain_size > best_size )
{
best_size = chain_size;
best_chain = chain_start;
}
}
} /* if WORST_FIT */
/*
* else if (method == PC_BEST_FIT)
* ;
*/
chain_size = 0;
chain_start = 0;
} /* if (chain_size && ((value != 0) || (i == endpt)) ) */
} /* for (i = startpt; i <= endpt; i++) */
/* If we have a best chain return it here. Else return the largest chain */
if (best_chain)
{
*pchain = best_chain;
return(best_size);
}
else
{
*pchain = largest_chain;
return(largest_size);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -