⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfswrite.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -