twl_wrapsdk/build/libraries/fatfs/ARM7/apiwrite.c
Shirait 4fe5688d29 add SD driver and FATFS library (tentative)
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@96 4ee2a332-4b2b-5046-8439-1ba90f034370
2007-05-30 10:22:28 +00:00

829 lines
31 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1987-2003
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* APIWRITE.C - Contains user api level file IO source code.
The following routines are included:
po_write - Write Bytes to a file.
po_flush - Flush an open file
po_trunc - Truncate an open file
pc_set_attributes - Set File Attributes
pc_diskflush - Flush the FAT and all files on a disk
*/
#include <rtfs.h>
/***************************************************************************
PO_WRITE - Write to a file.
Description
Attempt to write count bytes from buf to the current file pointer of file
at fd. The file pointer is updated.
Returns
Returns the number of bytes written or -1 on error.
errno is set to one of the following
0 - No error
PEBADF - Invalid file descriptor
PEACCES - File is read only
PEIOERRORWRITE - Error performing write
PEIOERRORREAD - Error reading block for merge and write
PENOSPC - Disk full
An ERTFS system error
****************************************************************************/
int po_write(PCFD fd, byte *in_buff, int count) /*__apifn__*/
{
PC_FILE *pfile;
DDRIVE *pdrive;
dword block_in_cluster;
dword byte_offset_in_block;
dword n_blocks_left;
dword n_to_write, n_w_to_write;
CLUSTERTYPE next_cluster;
CLUSTERTYPE n_clusters;
dword ltemp;
int n_bytes;
int n_written;
int n_left;
dword alloced_size;
dword block_to_write;
int end_of_chain;
BOOLEAN extending_file;
int ret_val;
int p_errno;
CHECK_MEM(int, -1) /* Make sure memory is initted */
/* Return 0 (none written) on bad args */
if (!count)
return(0);
p_errno = 0;
rtfs_set_errno(0); /* po_write: clear error status */
/* Get the FILE. must be open for write */
/* Get the file structure and semaphore lock the drive */
pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
if (!pfile)
{ /* fd2file set errno */
ret_val = -1;
goto return_unlocked;
}
pdrive = pfile->pobj->pdrive;
/* Only one process may write at a time */
/* if the file is zero sized make sure the current cluster pointer
is invalid */
if (!pfile->pobj->finode->fsize)
pfile->fptr_cluster = 0;
/* 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);
if (alloced_size < pfile->pobj->finode->fsize)
alloced_size = 0xffffffff;
/* Set the cluster and block file pointers if not already set */
if (!_synch_file_ptrs(pfile))
{ /* _synch_file_ptrs set errno */
ret_val = -1;
goto return_locked;
}
/* Seek to the end if append mode */
if (pfile->flag & PO_APPEND)
{
if (pfile->pobj->finode->fsize)
{
if (!_po_ulseek(pfile, 0L, &ltemp, PSEEK_END))
{ /* po_ulseek will set error status */
ret_val = -1;
goto return_locked;
}
if (!_synch_file_ptrs(pfile))
{ /* _synch_file_ptrs set errno */
ret_val = -1;
goto return_locked;
}
}
}
/* Check if this write will wrap past 4 Gigabytes
if so truncate the count to 4 Gig minus 1*/
ltemp = pfile->fptr + count;
if (ltemp < pfile->fptr)
{
#if (RTFS_TRUNCATE_WRITE_TO_MAX)
ltemp = 0xffffffff;
count = ltemp - pfile->fptr;
#else
p_errno = PETOOLARGE;
ret_val = -1;
goto return_locked;
#endif
}
if (ltemp > RTFS_MAX_FILE_SIZE)
{
#if (RTFS_TRUNCATE_WRITE_TO_MAX)
ltemp = RTFS_MAX_FILE_SIZE;
count = ltemp - pfile->fptr;
#else
p_errno = PETOOLARGE;
ret_val = -1;
goto return_locked;
#endif
}
/* calculate initial values */
n_left = count;
n_written = 0;
while (n_left)
{
end_of_chain = 0;
block_in_cluster = (dword) (pfile->fptr & pdrive->byte_into_cl_mask);
block_in_cluster >>= 9;
if (pfile->fptr >= alloced_size)
{
/* Extending the file */
extending_file = TRUE;
ltemp = (dword) n_left;
n_blocks_left = (dword) ((ltemp + 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 = ( CLUSTERTYPE ) (1 +
((n_blocks_left + block_in_cluster -1) >> pdrive->log2_secpalloc));
/* 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 */
n_clusters = FATOP(pdrive)->fatop_alloc_chain(pdrive, &(pfile->fptr_cluster), n_clusters, TRUE);
if (!n_clusters)
{ /* Allocchain will set errno to PENOSPC or an IO or internal error */
break;
}
/* Calculate the last cluster in this chain. */
next_cluster = (CLUSTERTYPE) (pfile->fptr_cluster + n_clusters -1);
/* link the chain to the directory object if just starting */
if (!pc_finode_cluster(pfile->pobj->pdrive,pfile->pobj->finode))
pc_pfinode_cluster(pfile->pobj->pdrive,pfile->pobj->finode,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;
if (alloced_size < ltemp)
alloced_size = 0xffffffff;
}
else /* Not extending the file. (writing inside the file) */
{
extending_file = FALSE;
ltemp = (dword) n_left;
n_blocks_left = (dword) ((ltemp + 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 = (CLUSTERTYPE) (1 +
((n_blocks_left + block_in_cluster -1) >> pdrive->log2_secpalloc));
/* how many contiguous clusters can we get ? <= n_clusters */
end_of_chain = 0;
n_clusters = FATOP(pdrive)->fatop_get_chain(pdrive, pfile->fptr_cluster,
&next_cluster, n_clusters, &end_of_chain);
if (!n_clusters)
{
/* get_chain already set errno */
ret_val = (int) -1;
goto return_locked;
}
}
/* Are we inside a block */
if ( (pfile->fptr & 0x1ffL) || (n_left < 512) )
{
block_in_cluster = (dword) (pfile->fptr & pdrive->byte_into_cl_mask);
block_in_cluster >>= 9;
block_to_write = pfile->fptr_block + block_in_cluster;
byte_offset_in_block = (dword) (pfile->fptr & 0x1ffL);
/* Copy source data to the local buffer */
n_bytes = (int) (512 - byte_offset_in_block);
if (n_bytes > n_left)
n_bytes = n_left;
/* READ - Use the block buffer pool to read for us */
if (!pc_load_file_buffer(pfile, block_to_write))
break; /* load_file_block set errno */
/* Merge the data and mark it dirty */
if (in_buff)
copybuff(&(pfile->pobj->finode->pfile_buffer->data[byte_offset_in_block]), in_buff, n_bytes);
pfile->pobj->finode->file_buffer_dirty = 1;
if (!(pfile->pobj->finode->openflags & OF_BUFFERED))
{
/* Write the buffer. and discard it */
if (!pc_load_file_buffer(pfile, 0))
break; /* load_file_block set errno */
}
if (in_buff)
in_buff += n_bytes;
n_left = (int) (n_left - n_bytes);
pfile->fptr += n_bytes;
n_written += n_bytes;
/* Are we on a cluster boundary ? */
if (!(pfile->fptr & pdrive->byte_into_cl_mask))
{
if (--n_clusters) /* If contiguous */
{
pfile->fptr_block += pdrive->secpalloc;
pfile->fptr_cluster += (CLUSTERTYPE)1;
}
else
{
/* Check for corrupted file
We are about to advance fptr_cluster by
making next_cluster the current cluster.
If the file pointer is less than the current file
size, but we are at the end of chain we know
that there is no next_cluster and the chain is
corrupted. It shorter than the file size indicates.
Reset the byte pointer to match the current
block and cluster pointers, set errno to
PEINVALIDCLUSTER, return -1
We check against alloced_size here because next
time through the write routine will check and if
fptr >= alloced_size then it will link a new cluster
to the file.
*/
if (!extending_file &&
pfile->fptr < alloced_size &&
end_of_chain)
{
pfile->fptr -= n_bytes;
p_errno = PEINVALIDCLUSTER;
ret_val = -1;
goto return_locked;
}
else
{
/* NOTE: Put the next cluster into the pointer. If we had
alloced a chain this value is the last cluster in
the chain and does not concur with the byte file pointer.
This is not a problem since the cluster pointer is known
to be off at this point any (fptr>=alloced_size) */
pfile->fptr_cluster = next_cluster;
pfile->fptr_block = pc_cl2sector(pdrive, next_cluster);
}
} /* if (--nclusters) {} else {}; */
} /* if (!(pfile->fptr & byte_into_cl_mask)) */
} /* if ( (pfile->fptr & 0x1ff) || (n_left < 512) ) */
if (n_clusters && (n_left>511))
{
/* If we get here we need to write contiguous blocks */
block_in_cluster = (dword) (pfile->fptr & pdrive->byte_into_cl_mask);
block_in_cluster >>= 9;
block_to_write = pfile->fptr_block + block_in_cluster;
/* how many do we write ? */
ltemp = (dword) n_left;
n_blocks_left = (dword) (ltemp >> 9);
n_to_write = (dword) ((n_clusters << pdrive->log2_secpalloc) - block_in_cluster);
if (n_to_write > n_blocks_left)
{
n_to_write = n_blocks_left;
/* If we are not writing to the end of the chain we may not
advance the cluster pointer to the beginning of the next
chain. We add in block_in_cluster so we account for the
partial cluster we have already seen */
next_cluster = (CLUSTERTYPE) (pfile->fptr_cluster +
((n_to_write+block_in_cluster) >> pdrive->log2_secpalloc));
}
/* Devio takes words for blocks so split it up */
ltemp = n_to_write;
while (ltemp)
{
if (ltemp > 0xffff)
n_w_to_write = 0xffff;
else
n_w_to_write = ltemp & 0xffff;
/* Set pdrive->drive_flags to tell the device driver we are perfroming
file data transfer */
pdrive->drive_flags |= DRIVE_FLAGS_FILEIO;
if (in_buff && !devio_write(pdrive->driveno, block_to_write, in_buff, (word) n_w_to_write, FALSE))
{
pdrive->drive_flags &= ~DRIVE_FLAGS_FILEIO;
/* set errno to IO error unless devio set PEDEVICE */
if (!get_errno())
p_errno = PEIOERRORWRITE;
ret_val = n_written;
goto return_locked;
}
pdrive->drive_flags &= ~DRIVE_FLAGS_FILEIO;
/* Purge the file block buffer if it was in our range, since we will overwrite */
pc_sync_file_buffer(pfile, block_to_write, n_w_to_write, FALSE);
n_bytes = (int) n_w_to_write * 512;
if (in_buff)
in_buff = in_buff + n_bytes;
block_to_write += n_w_to_write;
ltemp = ltemp - n_w_to_write;
}
/* See note above */
n_bytes = (int) n_to_write * 512;
n_left = n_left - n_bytes;
pfile->fptr += n_bytes;
n_written += n_bytes;
pfile->fptr_cluster = next_cluster;
pfile->fptr_block = pc_cl2sector(pdrive, next_cluster);
}
} /* while n_left */
ret_val = n_written;
/* If we wrote anything change the last modified time and date */
if (pfile->pobj && ret_val > 0)
{
DATESTR crdate;
pc_getsysdate(&crdate);
pfile->pobj->finode->fattribute |= ARCHIVE;
pfile->pobj->finode->ftime = crdate.time;
pfile->pobj->finode->fdate = crdate.date;
pfile->needs_flush = TRUE;
}
return_locked:
if (pfile->pobj && (pfile->fptr > pfile->pobj->finode->fsize))
{
pfile->needs_flush = TRUE;
pfile->pobj->finode->fsize = pfile->fptr;
pfile->pobj->finode->fattribute |= ARCHIVE;
}
/* If the file pointer is beyond the space allocated to the file note it.
since we may need to adjust this files cluster and block pointers
later if someone else extends the file behind our back */
if (pfile->fptr >= alloced_size)
pfile->at_eof = TRUE;
else
pfile->at_eof = FALSE;
/* If the file is open in auto flush mode flush directory entry changes to disk */
if (pfile->flag & PO_AFLUSH)
if (!_po_flush(pfile))
ret_val = -1;
if (!release_drive_mount_write(pdrive->driveno))/* Release lock, unmount if aborted */
return(-1);
return_unlocked:
if (p_errno)
rtfs_set_errno(p_errno);
return(ret_val);
}
/**************************************************************************
PO_TRUNCATE - Truncate an open file.
Description
Move the file pointer offset bytes from the beginning of the file
and truncate the file beyond that point by adjusting the file size
and freeing the cluster chain past the file pointer.
Returns
Returns TRUE if successful otherwise FALSE
errno is set to one of the following
0 - No error
PEBADF - Invalid file descriptor
PEACCES - File is read only or opened more than once
PEINVALIDPARMS - Invalid or inconsistent arguments
An ERTFS system error
*****************************************************************************/
BOOLEAN po_truncate(PCFD fd, dword offset) /*__apifn__*/
{
PC_FILE *pfile;
DDRIVE *pdrive;
BOOLEAN ret_val;
CLUSTERTYPE first_cluster_to_release;
CLUSTERTYPE last_cluster_in_chain;
CLUSTERTYPE clno;
int p_errno;
dword clusters_to_release;
dword old_chain_len;
dword new_chain_len;
dword range_check;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
p_errno = 0;
rtfs_set_errno(0); /* po_truncate: clear error status */
/* Assume failure */
ret_val = FALSE;
/* Get the FILE. must be open for write */
/* Get the file structure and semaphore lock the drive */
pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
/* Make sure we have write privilages */
if (!pfile)
goto return_error;
pdrive = pfile->pobj->pdrive;
/* Can only truncate a file that you hold exclusively */
if (pfile->pobj->finode->opencount > 1)
{
p_errno = PEACCES;
goto errex;
}
/* Set the cluster and block file pointers if not already set */
if (!_synch_file_ptrs(pfile))
{ /* _synch_file_ptrs set errno */
goto errex;
}
/* Make sure the file buffer is clear */
pc_load_file_buffer(pfile, 0);
if (offset > pfile->pobj->finode->fsize)
{
p_errno = PEINVALIDPARMS;
goto errex;
}
/* Call the internal seek routine that we share with po_lseek. Seek to
offset from the origin of zero. */
if (!_po_ulseek(pfile, offset, &offset, PSEEK_SET))
goto errex; /* _po_lseek() set errno */
else if (offset == pfile->pobj->finode->fsize)
{
ret_val = TRUE;
}
else
{
pfile->needs_flush = TRUE;
/* calculate maximum number of clusters we will need to release */
/* Round the file size up to its cluster size by adding in clustersize-1
and masking off the low bits */
old_chain_len = pc_chain_length(pdrive, pfile->pobj->finode->fsize);
new_chain_len = pc_chain_length(pdrive, offset);
clusters_to_release = old_chain_len - new_chain_len;
/* Are we on a cluster boundary ? */
if (!(offset & pdrive->byte_into_cl_mask))
{
/* Free the current cluster and beyond since we are on a cluster boundary. */
first_cluster_to_release = pfile->fptr_cluster;
/* Find the previous cluster so we can terminate the chain */
clno = pc_finode_cluster(pdrive,pfile->pobj->finode);
last_cluster_in_chain = clno;
range_check = 0;
while (clno != first_cluster_to_release)
{
if ((clno < 2) || (clno > pdrive->maxfindex) || (++range_check > old_chain_len) )
{
rtfs_set_errno(PEINVALIDCLUSTER);
goto errex;
}
last_cluster_in_chain = clno;
clno = FATOP(pdrive)->fatop_clnext(pdrive , clno); /* File */
if (!clno)
{ /* FATOP will set errno */
goto errex;
}
}
/* Set ptr_cluster to last in chain so read&write will work right */
pfile->fptr_cluster = last_cluster_in_chain;
if (last_cluster_in_chain)
{
if ((clno < 2) || (clno > pdrive->maxfindex))
{
rtfs_set_errno(PEINVALIDCLUSTER);
goto errex;
}
pfile->fptr_block = pc_cl2sector(pdrive, last_cluster_in_chain);
}
else
pfile->fptr_block = 0;
pfile->at_eof = TRUE;
}
else /* Simple case. we are not on a cluster boundary. Just free*/
{ /* The chain beyond us and terminate the list */
last_cluster_in_chain = pfile->fptr_cluster;
first_cluster_to_release = FATOP(pdrive)->fatop_clnext(pdrive, pfile->fptr_cluster); /* File */
if (!first_cluster_to_release) /* if 0 and not end of chain it's an error */
{ /* clnext set errno */
goto errex;
}
/* Clear cluster number if clnext returned eof */
if (first_cluster_to_release == 0xffffffff)
first_cluster_to_release = 0;
pfile->at_eof = TRUE;
}
/* Now update the directory entry. */
pfile->pobj->finode->fsize = offset;
if (!offset) /* If the file goes to zero size unlink the chain */
{
pc_pfinode_cluster(pdrive,pfile->pobj->finode,0);
pfile->fptr_cluster = 0;
pfile->fptr_block = 0;
pfile->fptr = 0;
pfile->at_eof = FALSE;
/* We are freeing the whole chain so we do not mark last_cluster in chain */
last_cluster_in_chain = 0;
}
ret_val = TRUE; /* If it doesn't get changed to false, it worked */
/* Convert to native. Overwrite the existing inode.Set archive/date */
if (!pc_update_inode(pfile->pobj, TRUE, TRUE))
ret_val = FALSE;
/* Terminate the chain and free the lost chain part */
/* Free the rest of the chain */
if (ret_val && clusters_to_release && first_cluster_to_release)
{
/* Release the chain FATOP will set erno if needed - set min and max
the same so it must delete exactly this many clusters */
if (!FATOP(pdrive)->fatop_freechain(pdrive, first_cluster_to_release, clusters_to_release, clusters_to_release))
ret_val = FALSE;
}
/* Null terminate the chain */
if (ret_val && last_cluster_in_chain)
{
if (!FATOP(pdrive)->fatop_pfaxxterm(pdrive, last_cluster_in_chain)) /* File */
ret_val = FALSE;
}
if (ret_val && !FATOP(pdrive)->fatop_flushfat(pdrive->driveno))
ret_val = FALSE;
}
errex:
if (!release_drive_mount_write(pdrive->driveno))/* Release lock, unmount if aborted */
return(FALSE);
return_error: /* No only errors return through here. Everything does. */
if (p_errno)
rtfs_set_errno(p_errno);
return(ret_val);
}
/*
* Note: when this routine is caled the files finode is LOCKED so the code
* need not be reentrant relative to the finode.
*/
/* Internal version of po_flush() called by po_flush and po_close */
BOOLEAN _po_flush(PC_FILE *pfile) /*__fn__*/
{
/*---------- ctr modified ----------*/
int driveno;
DDRIVE *pdr;
/*----------------------------------*/
BOOLEAN ret_val;
/* Flush the file buffer if it is in use */
if (!pc_flush_file_buffer(pfile))
return(FALSE);
ret_val = TRUE;
/* Convert to native. Overwrite the existing inode.Set archive
set date. */
if (pfile->needs_flush)
{
if (pc_update_inode(pfile->pobj, TRUE, TRUE))
{ /* pc_update_inode and FATOP both set errno */
pfile->needs_flush = FALSE;
/* Flush the file allocation table */
if (!FATOP(pfile->pobj->pdrive)->fatop_flushfat(pfile->pobj->pdrive->driveno))
ret_val = FALSE;
}
else
ret_val = FALSE;
}
/*---------- ctr modified ----------*/
driveno = pfile->pobj->pdrive->driveno;
pdr = pc_drno_to_drive_struct( driveno);
if( pdr) {
if( pdr->dev_table_perform_device_ioctl) {
if( pdr->dev_table_perform_device_ioctl( driveno,
DEVCTL_FLUSH,
NULL) != 0) {
ret_val = FALSE;
}
}
}
/*----------------------------------*/
return(ret_val);
}
/****************************************************************************
PO_FLUSH - Flush a file.
Description
Flush the file updating the disk.
Returns
Returns TRUE if all went well otherwise it returns FALSE.
errno is set to one of the following
0 - No error
PEBADF - Invalid file descriptor
PEACCES - File is read only
An ERTFS system error
****************************************************************************/
BOOLEAN po_flush(PCFD fd) /*__apifn__*/
{
PC_FILE *pfile;
BOOLEAN ret_val;
int driveno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
rtfs_set_errno(0); /* po_flush: clear error status */
/* Get the FILE. must be open for write */
/* Get the file structure and semaphore lock the drive */
pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
if (pfile)
{
driveno = pfile->pobj->pdrive->driveno;
ret_val = _po_flush(pfile); /* _po_flush() will set errno */
if (!release_drive_mount_write(driveno))/* Release lock, unmount if aborted */
ret_val = -1;
return(ret_val);
}
else
{ /* fd2file set errno */
return(FALSE);
}
}
/*****************************************************************************
pc_set_attributes - Set File Attributes
Description
Given a file or directory name return set directory entry attributes
associated with the entry.
The following values may be set:
BIT Nemonic
0 ARDONLY
1 AHIDDEN
2 ASYSTEM
5 ARCHIVE
Note: bits 3 & 4 (AVOLUME,ADIRENT) may not be changed.
Returns
Returns TRUE if successful otherwise it returns FALSE.
errno is set to one of the following
0 - No error
PEINVALIDDRIVEID- Drive component is invalid
PEINVALIDPATH - Path specified badly formed.
PENOENT - Path not found
PEACCESS - Object is read only
PEINVALIDPARMS - attribute argument is invalid
An ERTFS system error
****************************************************************************/
BOOLEAN pc_set_attributes(byte *path, byte attributes) /*__apifn__*/
{
DROBJ *pobj;
BOOLEAN ret_val;
int driveno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
rtfs_set_errno(0); /* pc_set_attributes: clear error status */
if ((attributes&(0x40|0x80)) !=0 ) /* Illegal */
{
rtfs_set_errno(PEINVALIDPARMS);
return(FALSE);
}
driveno = check_drive_name_mount(path);
if (driveno < 0)
{ /* errno was set by check_drive */
return (FALSE);
}
ret_val = FALSE;
/* pc_fndnode will set errno */
pobj = pc_fndnode(path);
if (pobj)
{
/* Change the attributes if legal */
if (
(attributes & (AVOLUME|ADIRENT)) == /* Still same type */
(pobj->finode->fattribute & (AVOLUME|ADIRENT)))
{
pobj->finode->fattribute = attributes;
/* Overwrite the existing inode. Do not set archive/date */
/* pc_update_inode() will set errno */
ret_val = pc_update_inode(pobj, FALSE, FALSE);
}
else
rtfs_set_errno(PEACCES);
pc_freeobj(pobj);
}
if (!release_drive_mount_write(driveno))/* Release lock, unmount if aborted */
ret_val = FALSE;
return (ret_val);
}
/****************************************************************************
PC_DISKFLUSH - Flush the FAT and all files on a disk
Description
If an application may call this functions to force all files
to be flushed and the fat to be flushed. After this call returns
the disk image is synchronized with RTFSs internal view of the
voulme.
Returns
TRUE if the disk flushed else no
errno is set to one of the following
0 - No error
PEINVALIDDRIVEID- Drive component is invalid
An ERTFS system error
****************************************************************************/
BOOLEAN pc_diskflush(byte *path) /*__apifn__*/
{
int driveno;
DDRIVE *pdrive;
BOOLEAN ret_val;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
rtfs_set_errno(0); /* pc_diskflush: clear error status */
ret_val = FALSE;
driveno = check_drive_name_mount(path);
/* if error, errno was set by check_drive */
if (driveno >= 0)
{
/* Find the drive */
pdrive = pc_drno2dr(driveno);
if (pdrive)
{
/*---------- ctr modified ----------*/
if (pc_flush_all_fil(pdrive)) {
if (FATOP(pdrive)->fatop_flushfat(driveno)) {
ret_val = TRUE;
}
}
if( pdrive->dev_table_perform_device_ioctl) {
if( pdrive->dev_table_perform_device_ioctl( driveno,
DEVCTL_FLUSH,
NULL) == 0) {
ret_val = TRUE;
}
}/*----------------------------------*/
}
if (!release_drive_mount_write(driveno))/* Release lock, unmount if aborted */
ret_val = FALSE;
}
return(ret_val);
}
/*ctr modified
<20>{<7B><><EFBFBD>Apc_diskflush<73><68>RTFS<46>̃o<CC83>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>f<EFBFBD><66><EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>A
nand<6E>̓h<CD83><68><EFBFBD>C<EFBFBD>o<EFBFBD><6F><EFBFBD>ł<EFBFBD><C582>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>߃f<DF83>o<EFBFBD>C<EFBFBD>X<EFBFBD>ɔ<EFBFBD><C994>f<EFBFBD><66><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>B
<20>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD><6F><EFBFBD>̃o<CC83>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ăf<C483>o<EFBFBD>C<EFBFBD>X<EFBFBD>ɓf<C993><66><EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD>߂̕ύX<CF8D>B
<20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD><EFBFBD>_po_flush<73><68>DEVCTL_FLUSH<53><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD>Ă<EFBFBD><C482><EFBFBD>Ƃɂ<C682><C982><EFBFBD><EFBFBD>΍<EFBFBD><CE8D>B
mkdir, rmdir<69>Ȃǂ́A<CD81>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>łȂ<C582><C882><EFBFBD><EFBFBD><EFBFBD>_po_flush<73><68><EFBFBD>f<EFBFBD>ʂ肵<CA82>Ă<EFBFBD><C482>܂<EFBFBD><DC82>̂ŁA
pc_diskflush<73>ɂ<EFBFBD>DEVCTL_FLUSH<53><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD>Ƃɂ<C682><C982><EFBFBD><EFBFBD>΍<EFBFBD><CE8D>B
<20><><EFBFBD><EFBFBD>Ə<EFBFBD><C68F>ʑw<CA91><77>pc_diskflush<73><68><EFBFBD>Ă΂Ȃ<CE82><C882>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>̂<EFBFBD>mkdir,rmdir<69>Ȃǂ<C882>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B<EFBFBD>ipc_diskflush<73><68>DEVCTL_FLUSH<53>͍폜<CD8D><ED8F9C><EFBFBD>Ă悢<C482><E682A2><EFBFBD><EFBFBD><EFBFBD>j
*/