📄 zfswrite.c
字号:
cur_sec_id = sec_hdr.nxtsecnum ;
}
// check whether the offset is in last sector and still some space is present to write
// the data.
if( bytes <= bytesleft_in_sec )
curNumBytesToWrite = bytes ;
else
curNumBytesToWrite = bytesleft_in_sec ;
bytesWrittenWithoutCRLF = 0 ;
while( numBytesToWrite != 0 )
{
// Read the sector data into the sector.
bytes_read = pvol_info->pcfg->pfn_drv_read( GetSecAddr( pvol_info, cur_sec_id), &g_sec_data_write[0], ZFS_SEC_SIZE ) ;
if( bytes_read == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
// now remove the checksum for valid present data.
filecs = RemoveCheckSum(filecs, &g_sec_data_write[ umod + sizeof( ZFS_SEC_HDR_t) ], curNumBytesToWrite) ;
if( pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
{
new_sec_id = OverWriteSector( pvol_info, cur_sec_id, ZFS_SEC_TYPE_DATA ) ;
/*
// free sector
FreeSector( pvol_info, cur_sec_id ) ;
// allocate a new sector and free the old sector.
new_sec_id = AllocSector( pvol_info, cur_sec_id, ZFS_SEC_TYPE_DATA ) ;
*/
if( new_sec_id == 0 )
{
// space is not present, just return disk full error.
// Just think of not returning an error !!!! Try to return an error if OverWriteFIR fails // Mahadev
// return only the number of bytes that could be written on to the file at OverWriteFIR
goto _write_fir2 ;
// EnablePreemption( preempt_status ) ;
// return ZFSERR_DATAMEDIA_FULL ;
}
}
else
{
new_sec_id = cur_sec_id ;
}
// write the data onto the device
pAddr = GetSecAddr( pvol_info, new_sec_id ) ; // + sizeof(ZFS_SEC_HDR_t);
if( !( handle->attr & ZFS_MODE_BINARY ) )
{
// if the file is opened in ascii mode, then check the buffer for \n. If \n is found, then
// write till \n and then write \r\n.
// from the umod onwards, just, copy the buf contents onto the g_sec_data_write.
ptmp_buf = buf ;
pbuf = &g_sec_data_write[0] + umod + sizeof( ZFS_SEC_HDR_t) ;
// tmp_len = ZFS_SEC_DATA_SIZE - umod ;
idx = umod ;
actNumBytesWritten = 0 ;
tmp_bytes_written = 0 ;
// if tmp_write_lf is true, then we have to write \n at starting of this sector. Just write it.
if( tmp_write_lf == ZFS_TRUE )
{
tmp_write_lf = ZFS_FALSE ;
*pbuf = '\n' ;
pbuf++;
actNumBytesWritten = 1 ;
}
for( i = actNumBytesWritten ; i < curNumBytesToWrite ; )
{
if( *ptmp_buf == '\n' )
{
*pbuf = '\r' ;
if( i != 0 && idx == ZFS_SEC_DATA_SIZE - 1 )
{
// if the \n to be written is at the end, then \n should be written to the next sector
tmp_write_lf = ZFS_TRUE ;
}
else
{
*(pbuf + 1) = '\n' ;
pbuf++ ;
i++ ;
idx++ ;
}
}
else
{
*pbuf = *ptmp_buf ;
}
pbuf++ ;
ptmp_buf++ ;
tmp_bytes_written++ ;
i++ ;
idx++;
}
// now we have filled the whole buffer, just write the buffer into the data media.
bytes_written = pvol_info->pcfg->pfn_drv_write( pAddr, &g_sec_data_write[0], ZFS_SEC_SIZE ) ;
if( bytes_written == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
// now all bytes are written, just select
}
else
{
// mode is binary
// now modify the RAM contents with given buf.
memcpy( &(g_sec_data_write[ sizeof( ZFS_SEC_HDR_t) + umod]), buf, curNumBytesToWrite ) ;
// compute checksum.
filecs = ComputeCheckSum( filecs, &g_sec_data_write[ sizeof( ZFS_SEC_HDR_t) + umod], curNumBytesToWrite) ;
// now write the data to the device
bytes_written = pvol_info->pcfg->pfn_drv_write( pAddr, &g_sec_data_write[ 0], ZFS_SEC_SIZE ) ; //curNumBytesToWrite + umod + sizeof( ZFS_SEC_HDR_t) ) ;
if( bytes_written == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
// CR# 5461 fix.
if( curNumBytesToWrite < ( ZFS_SEC_SIZE - sizeof( ZFS_SEC_HDR_t) ) )
tmp_bytes_written = curNumBytesToWrite ;
else
tmp_bytes_written = ( bytes_written - sizeof( ZFS_SEC_HDR_t ) - umod ) ;
}
// here bytes_written may be more than curNumBytesToWrite
buf += tmp_bytes_written ;
numBytesWritten += curNumBytesToWrite ;
numBytesToWrite -= curNumBytesToWrite ;
bytesWrittenWithoutCRLF += tmp_bytes_written ;
if( numBytesToWrite > 0 )
{
PZFS_SEC_HDR_t psec_hdr = ( PZFS_SEC_HDR_t ) &g_sec_data_write[ 0 ] ;
if( numBytesToWrite >= ZFS_SEC_DATA_SIZE )
curNumBytesToWrite = ZFS_SEC_DATA_SIZE ;
else
curNumBytesToWrite = numBytesToWrite ;
if( psec_hdr->nxtsecnum != ( ZFS_SEC_ID_t ) FREE_SECTOR )
{
// still data need to be overwritten on to the next sector.
cur_sec_id = psec_hdr->nxtsecnum ;
umod = 0 ;
continue ;
}
else
{
// we already reached at the end of the sector, so need to allocate a sector.
// next sector is a free sector, so need to allocate and start writing the data from this sector.
while( numBytesToWrite > 0 )
{
// allocate and link to previous sector.
new_sec_id = AllocSector( pvol_info, 0, ZFS_SEC_TYPE_DATA ) ;
if( new_sec_id == 0 )
{
// space is not present, just return disk full error.
// return only the number of bytes that could be written on to the file at OverWriteFIR - Mahadev
goto _write_fir2 ;
// EnablePreemption( preempt_status ) ;
// return ZFSERR_DATAMEDIA_FULL ;
}
LinkSector( pvol_info, last_sec_num, new_sec_id ) ;
last_sec_num = new_sec_id ;
pAddr = GetSecAddr( pvol_info, new_sec_id ) + sizeof( ZFS_SEC_HDR_t ) ;
// if the mode is ascii, then format the data with \r\n wherever \n is present
if( !( handle->attr & ZFS_MODE_BINARY ) )
{
// if the file is opened in ascii mode, then check the buffer for \n. If \n is found, then
// write till \n and then write \r\n.
// from the umod onwards, just, copy the buf contents onto the g_sec_data_write.
ptmp_buf = buf ;
pbuf = &g_sec_data_write[0] + sizeof( ZFS_SEC_HDR_t) ;
// tmp_len = ZFS_SEC_DATA_SIZE ;
idx = 0 ;
actNumBytesWritten = 0 ;
tmp_bytes_written = 0 ;
// if tmp_write_lf is true, then we have to write \n at starting of this sector. Just write it.
if( tmp_write_lf == ZFS_TRUE )
{
tmp_write_lf = ZFS_FALSE ;
*pbuf = '\n' ;
pbuf++;
actNumBytesWritten = 1 ;
}
for( i = actNumBytesWritten ; i < curNumBytesToWrite ; )
{
if( *ptmp_buf == '\n' )
{
*pbuf = '\r' ;
if( i != 0 && idx == ZFS_SEC_DATA_SIZE - 1 )
{
// if the \n to be written is at the end, then \n should be written to the next sector
tmp_write_lf = ZFS_TRUE ;
}
else
{
*(pbuf + 1) = '\n' ;
pbuf++ ;
i++ ;
idx++ ;
}
}
else
{
*pbuf = *ptmp_buf ;
}
pbuf++ ;
ptmp_buf++ ;
tmp_bytes_written++ ;
i++ ;
idx++;
}
// now we have filled the whole buffer, just write the buffer into the data media.
bytes_written = pvol_info->pcfg->pfn_drv_write( pAddr, &g_sec_data_write[0] + sizeof( ZFS_SEC_HDR_t ), curNumBytesToWrite ) ;
if( bytes_written == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
// now all bytes are written, just select
}
else
{
bytes_written = pvol_info->pcfg->pfn_drv_write( pAddr, buf, curNumBytesToWrite ) ;
if( bytes_written == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
tmp_bytes_written = bytes_written ;
}
filecs = ComputeCheckSum( filecs, buf, bytes_written ) ;
buf += tmp_bytes_written ;
numBytesWritten += bytes_written ;
numBytesToWrite -= bytes_written ;
bytesWrittenWithoutCRLF += tmp_bytes_written ;
if( numBytesToWrite >= ZFS_SEC_DATA_SIZE )
curNumBytesToWrite = ZFS_SEC_DATA_SIZE ;
else
curNumBytesToWrite = numBytesToWrite ;
cur_sec_id = new_sec_id ;
}
// by this time all data is written onto the device, update the FIR and OR, return success
}
}
else
{
// num bytes to write is zero.
}
break ; // if it comes here it is due to numBytesToWrite == 0 or internal break condition.
}
// now everything is over here, just overwrite the FIR, update the OR and return 0.
_write_fir2:
pvol_info->pcfg->pfn_drv_read( handle->pfir_file, &fir_hdr, sizeof( ZFS_FIR_t ) ) ;
// update the size.
if( ( handle->offset + numBytesWritten ) > handle->size )
new_size = handle->offset + numBytesWritten ;
else
new_size = handle->size ;
fir_hdr.size = new_size ;
fir_hdr.filecs = filecs ;
fir_hdr.fir_type_status = ~ZFS_FILE_TYPE ;
fir_hdr.sec_datanum = handle->first_secnum ;
/*
// Get the time and data
if( GetTimeData( &fir_hdr.tom ) != ZFSERR_SUCCESS )
{
// do not do anything here, just write the old date and time.
}
*/
// overwrite the FIR
pnew_fir = OverWriteFIR( pvol_info, (PZFS_FIT_HDR_t) handle->pdir_node->sec_num, handle->pfir_file, &fir_hdr ) ;
if( pnew_fir == NULL )
{
// Media is full,
// Here the error should be returned not after the AllocSector is failed.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DATAMEDIA_FULL ;
}
// now update the OR
handle->filecs = filecs ;
handle->size = new_size ;
handle->offset += numBytesWritten ;
handle->last_secnum = last_sec_num ;
handle->cur_secnum = cur_sec_id ;
handle->pfir_file = pnew_fir ;
// now update the size, fir pointer, sec_numbers in OR where in fiels
// are opened in read mode.
pzfs_or = &g_zfs_or[0];
for( idx = 0 ; idx < g_max_or_entries ; idx++, pzfs_or++ )
{
if( pzfs_or->status == ZFS_OR_MAGIC_NUM &&
pzfs_or->pfir_file == pold_fir &&
( pzfs_or->mode & ZFS_READ ) )
{
// now update this record with appropriate values.
PZFS_OPEN_REC_t or_handle = pzfs_or ;
or_handle->filecs = filecs ;
or_handle->size = new_size ;
or_handle->last_secnum = last_sec_num ;
or_handle->first_secnum = old_first_sec_id ;
or_handle->pfir_file = pnew_fir ;
}
}
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return bytesWrittenWithoutCRLF ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -