nu_file.c
来自「移植Nuclues_RTC到coldfire5307在diab下编译通过」· C语言 代码 · 共 1,389 行 · 第 1/5 页
C
1,389 行
utemp = n_to_read;
while(utemp)
{
if (utemp > MAXSECTORS)
nblocks = MAXSECTORS;
else
nblocks = (UINT16) utemp;
/* READ */
PC_DRIVE_IO_ENTER(pdrive->driveno)
if ( !pc_bdevsw[pdrive->driveno].io_proc(pdrive->driveno, block_to_read, (UINT8 *)buf, nblocks, YES))
{
PC_DRIVE_IO_EXIT(pdrive->driveno)
fs_user->p_errno = PENOSPC;
ret_val = NUF_IO_ERROR;
break;
}
PC_DRIVE_IO_EXIT(pdrive->driveno)
utemp -= nblocks;
block_to_read += nblocks;
buf += (nblocks << 9);
}
n_bytes = (UINT32) (n_to_read << 9);
n_left -= n_bytes;
pfile->fptr += n_bytes;
/* if we advanced to a cluster boundary advance the
cluster pointer */
/* utemp ==s how many clusters we read */
utemp =(UINT32) ((n_to_read+block_in_cluster) >> pdrive->log2_secpalloc);
if (utemp == n_clusters)
{
pfile->fptr_cluster = next_cluster;
}
else
{
/* advance the pointer as many as we read */
pfile->fptr_cluster += utemp;
}
pfile->fptr_block = pc_cl2sector(pdrive, pfile->fptr_cluster);
}
}
} /* while n_left */
if (ret_val < 0)
{
/* Restore pointers and return */
pfile->fptr = saved_ptr;
pfile->fptr_block = saved_ptr_block;
pfile->fptr_cluster = saved_ptr_cluster;
}
else
{
ret_val = count;
}
PC_INODE_EXIT(pfile->pobj->finode)
PC_DRIVE_EXIT(pdrive->driveno)
}
/* Restore the kernel state */
PC_FS_EXIT()
return(ret_val);
}
/************************************************************************
* FUNCTION
*
* NU_Write
*
* DESCRIPTION
*
* Attempt to write count bytes from buf to the current file
* pointer of file at fd. The file pointer is updated.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* fd File descriptor.
* *buf Pointer of buffer to write.
* count Write byte count.
*
* OUTPUTS
*
* Returns the number of bytes written or negative value on error.
* If the return value is negative, the meaning is follows:
*
* INT32 A non-negative integer to be
* used as a number of bytes
* written.
* NUF_BAD_USER Not a file user.
* NUF_BADPARM Invalid parameter specified.
* NUF_BADFILE File descriptor invalid.
* NUF_ACCES Not a PO_WRONLY or PO_RDWR
* open flag or file
* attributes is ARDONLY.
* NUF_NOSPC Write failed. Presumably
* because of no space.
* NUF_IO_ERROR IO error occured.
* NUF_INTERNAL Nucleus FILE internal error.
*
* fs_user->p_errno is set to one of these values
*
* PEBADF Invalid file descriptor.
* PEACCES Attempt to open a read only
* file or a special
* (directory) file.
* PENOSPC Create failed.
*
*************************************************************************/
INT32 NU_Write(INT fd, CHAR *buf, INT32 count)
{
PC_FILE *pfile;
DDRIVE *pdrive;
UINT32 block_in_cluster;
UINT16 byte_offset_in_block;
UINT32 next_cluster;
UINT32 saved_ptr;
UINT32 saved_ptr_block;
UINT32 saved_ptr_cluster;
UINT32 ltemp;
UINT32 n_bytes;
UINT32 n_to_write;
UINT32 n_left;
UINT32 n_blocks_left;
UINT16 nblocks;
UINT32 n_clusters;
UINT32 alloced_size;
UINT32 block_to_write;
UINT8 local_buf[512];
INT32 ret_val;
STATUS status;
PC_FS_ENTER() /* Must be last line in declarations */
CHECK_USER(INT32, NUF_BAD_USER) /* Check if a valid user if multitasking */
fs_user->p_errno = 0;
/* Get the FILE. Second argument is ignored */
if ( (pfile = pc_fd2file(fd)) == NULL )
{
fs_user->p_errno = PEBADF;
ret_val = NUF_BADFILE;
}
/* Check the file attributes */
else if (pfile->pobj->finode->fattribute & ARDONLY)
{
fs_user->p_errno = PEACCES;
ret_val = NUF_ACCES;
}
/* Opened for write ? */
else if ( !((pfile->flag & PO_WRONLY) || (pfile->flag & PO_RDWR)) )
{
fs_user->p_errno = PEACCES;
ret_val = NUF_ACCES;
}
/* Return 0 (none written) on bad args */
else if (!count)
{
ret_val = 0;
}
/* Return -1 bad parameter */
else if ( count < 0 || !buf )
{
ret_val = NUF_BADPARM;
}
else
{
pdrive = pfile->pobj->pdrive;
PC_DRIVE_ENTER(pdrive->driveno, NO) /* Register drive in use (non excl) */
/* Only one process may write at a time */
PC_INODE_ENTER(pfile->pobj->finode, YES)
/* if the file is zero sized make sure the current cluster pointer
is invalid */
if (!pfile->pobj->finode->fsize)
pfile->fptr_cluster = 0L;
/* Set the cluster and block file pointers if not already set */
_synch_file_ptrs(pfile);
saved_ptr = pfile->fptr;
saved_ptr_block = pfile->fptr_block;
saved_ptr_cluster = pfile->fptr_cluster;
/* calculate initial values */
n_left = count;
/* Round the file size up to its cluster size by adding in clustersize-1
and masking off the low bits */
alloced_size = (pfile->pobj->finode->fsize + pdrive->byte_into_cl_mask) &
~(pdrive->byte_into_cl_mask);
while (n_left)
{
block_in_cluster = (UINT32) (pfile->fptr & pdrive->byte_into_cl_mask);
block_in_cluster >>= 9;
if (pfile->fptr >= alloced_size)
{
/* Extending the file */
n_blocks_left = (UINT32) ((n_left + 511) >> 9);
/* how many clusters are left-
* assume 1 for the current cluster.
* subtract out the blocks in the current
* round up by adding secpalloc-1 and then
* divide by sectors per cluster
| n_clusters = 1 +
| (n_blocks_left-
| (pdrive->secpalloc-block_in_cluster)
| + pdrive->secpalloc-1) >> pdrive->log2_secpalloc;
==>
*/
n_clusters = ( UINT32) (1 +
((n_blocks_left + block_in_cluster - 1) >> pdrive->log2_secpalloc));
if (pdrive->fasize == 8) /* FAT32 */
{
/* Calculate file total size */
ltemp = alloced_size >> pdrive->log2_secpalloc;
ltemp >>= 9; /* Divide by 512 */
ltemp += n_clusters;
/* Chech the maximum file size(4GB) */
if (pdrive->maxfsize_cluster < ltemp)
{
ret_val = NUF_MAXFILE_SIZE;
break; /* Exit from write loop */
}
}
/* Call pc_alloc_chain to build a chain up to n_cluster clusters
long. Return the first cluster in pfile->fptr_cluster and
return the # of clusters in the chain. If pfile->fptr_cluster
is non zero link the current cluster to the new one */
PC_FAT_ENTER(pdrive->driveno)
status = pc_alloc_chain(&n_clusters, pdrive, &(pfile->fptr_cluster), n_clusters);
PC_FAT_EXIT(pdrive->driveno)
if (status != NU_SUCCESS)
{
ret_val = (INT32)status;
break; /* Exit from write loop */
}
/* Calculate the last cluster in this chain. */
next_cluster = (UINT32) (pfile->fptr_cluster + n_clusters - 1);
/* link the chain to the directory object if just starting */
if (!pfile->pobj->finode->fcluster)
pfile->pobj->finode->fcluster = pfile->fptr_cluster;
/* calculate the new block pointer */
pfile->fptr_block = pc_cl2sector(pdrive, pfile->fptr_cluster);
/* calculate amount of space used by the file */
ltemp = n_clusters << pdrive->log2_secpalloc; ltemp <<= 9;
alloced_size += ltemp;
}
else /* Not extending the file. (writing inside the file) */
{
n_blocks_left = (UINT32) ((n_left + 511) >> 9);
/* how many clusters are left-
* assume 1 for the current cluster.
* subtract out the blocks in the current
* round up by adding secpalloc-1 and then
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?