📄 apiext.c
字号:
/************************************************************************
*
* Copyright (c) 2001 by Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in
* the subject matter of this material. All manufacturing,
* reproduction, use, and sales rights pertaining to this subject
* matter are governed by the license agreement. The recipient of
* this software implicitly accepts the terms of the license.
*
*
*************************************************************************
*************************************************************************
* FILE NAME VERSION
*
* APIEXT.C FILE 2.2
*
* COMPONENT
*
* Nucleus File
*
* DESCRIPTION
*
* Extensions to the API.
*
* DATA STRUCTURES
*
* None
*
* FUNCTIONS
*
* pc_cluster_size Return the number of bytes
* per cluster for a drive.
* po_extend_file Extend a file by
* N contiguous clusters.
* pc_find_contig_clusters Find at least MIN_CLUSTER
* clusters.
*
* DEPENDENCIES
*
* pcdisk.h File common definitions
*
************************************************************************/
#include "pcdisk.h"
/************************************************************************
* FUNCTION
*
* pc_cluster_size
*
* DESCRIPTION
*
* This function will return the cluster size mounted device
* named in the argument.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* drive Driver charactor
*
* OUTPUTS
*
* The cluster size or zero if the device is not mounted.
*
*************************************************************************/
INT16 pc_cluster_size(UINT8 *drive)
{
UINT16 drive_no;
DDRIVE *pdrive;
/* get drive no */
if ( *drive && (*(drive+1) == ':') )
{
drive_no = (UINT16) (*drive - 'A');
pdrive = pc_drno2dr(drive_no);
if (pdrive)
return(pdrive->bytespcluster);
}
return(0);
}
/************************************************************************
* FUNCTION
*
* po_extend_file
*
* DESCRIPTION
*
* Given a file descriptor, n_clusters clusters and method,
* extend the file and update the file size.
*
* Method may be one of the following:
* PC_FIRST_FIT - The first free chain >= n_clusters is alloced
* PC_BEST_FIT - The smallest chain >= n_clusters is alloced
* PC_WORST_FIT - The largest chain >= n_clusters is alloced
*
* Note: PC_FIRST_FIT is significantly faster than the others
* See: pc_find_contig_clusters()
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* fd File descriptor
* n_clusters Number of clusters
* method Method
*
* OUTPUTS
*
* 0xffffffff if an error occured.
* Returns n_clusters if the file was extended. Otherwise it
* returns the largest free chain available. If it n_clusters is
* not returned the files was not extended.
*
*************************************************************************/
UINT32 po_extend_file(INT fd, UINT32 n_clusters, INT16 method)
{
STATUS ret_stat;
UINT32 ret_val;
UINT32 clno;
UINT32 n_alloced;
UINT32 largest_chain;
UINT32 first_cluster;
UINT32 last_cluster_in_chain;
UINT32 i;
UINT32 ltemp;
PC_FILE *pfile;
DDRIVE *pdr;
PC_FS_ENTER() /* Must be last line in declarations */
CHECK_USER(UINT32, -1) /* Check if a valid user if multitasking */
if (!n_clusters)
{
fs_user->p_errno = 0;
ret_val = 0;
goto return_error;
}
/* Assume error to start */
fs_user->p_errno = PENOSPC;
ret_val = (UINT32) -1;
/* Get the FILE. Second argument is ignored */
pfile = pc_fd2file(fd);
/* Make sure we have write privilages. Make sure we got a count */
if ( (!pfile) || !n_clusters || !((pfile->flag & PO_WRONLY) || (pfile->flag & PO_RDWR)) )
{
fs_user->p_errno = PEBADF;
goto return_error;
}
/* From here on we exit through alloc_done so we will unlock these resources */
pdr = pfile->pobj->pdrive;
PC_DRIVE_ENTER(pdr->driveno, NO)
PC_INODE_ENTER(pfile->pobj->finode, YES) /* Exclusive */
PC_FAT_ENTER(pdr->driveno)
/* Make sure our file pointer is ok */
_synch_file_ptrs(pfile);
/* Find the end of the file's chain */
last_cluster_in_chain = 0;
clno = pfile->fptr_cluster;
while (clno)
{
last_cluster_in_chain = clno;
pc_clnext(&clno, pdr, clno);
}
/* Now allocate clusters. To find the free space we look in three
regions until we find space:
1 we look from the last cluster in the file to the end of the fat
(skip 1 if there is no chain)
2 we look from the beginning of the data area to the end of the fat
3 we look from the beginning of the fat area to the end of the fat
*/
n_alloced = 0;
largest_chain = 0;
clno = last_cluster_in_chain;
if (!clno)
clno = pdr->free_contig_pointer;
while (clno)
{
n_alloced = pc_find_contig_clusters(pdr, clno, &first_cluster, n_clusters, method);
if (n_alloced == ((UINT32) -1))
goto alloc_done;
else if (n_alloced >= n_clusters)
break; /* We got our chain */
else
{
/* We didn't get enough space. keep track of the biggest chain.
Don't need to store first_cluster since we won't alocate chains
smaller than what we need */
if (largest_chain < n_alloced)
largest_chain = n_alloced;
}
/* If we were searching between from the end of the file and end of fat
look from the beginning of the file data area */
if (clno == last_cluster_in_chain)
clno = pdr->free_contig_pointer;
/* If we were searching between the beginning of the file data area
and end of fat look from the fat */
else if ( (clno == pdr->free_contig_pointer) && (clno != 2) )
clno = 2;
else /* We've looked everywhere. No luck */
break;
}
if (n_alloced < n_clusters)
{
/* We didn't get what we asked for so we return the biggest free
contiguous chain */
ret_val = largest_chain;
goto alloc_done;
}
/* else */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -