#include <bea_diskvolume.h>


Definition at line 46 of file bea_diskvolume.h.
Public Types | |
| enum | dv_FileType_e { dv_HeaderFile, dv_DataFile, dv_FRIFile } |
Public Member Functions | |
| bea_DiskVolume (bea_Medium *const a_medium_p, UInt32_t a_volNumber, UInt32_t a_volSize) | |
| virtual UInt32_t | GetPosition () |
| virtual void | Erase () |
| virtual void | WriteFileMarks (UInt32_t a_count=1) |
| virtual void | Flush () |
| virtual void | SeekEOD () |
| virtual void | Rewind () |
| virtual void | SeekBlock (UInt32_t a_block) |
| virtual void | SeekFileMark (Int32_t a_relativeFM) |
Protected Member Functions | |
| virtual | ~bea_DiskVolume () |
| virtual void | WriteRaw (const UInt8_t *a_buf, UInt32_t a_size) |
| virtual void | ReadRaw (UInt8_t *a_buf, UInt32_t a_size) |
| virtual void | ReadEstimSizes () |
| Reads estimated overall and remaining capacity of this medium volume. | |
Private Member Functions | |
| void | ReparseFiles () |
| dv_FileType_e | GetTypeFromExt (const string &a_extStr) |
| void | CreateNewFile () |
| void | ExtendToFullBlock (cmn_File &a_file, ivd_FilePosition_t a_filePos, UInt32_t a_blkSize) |
| void | ReadVolInfo () |
| void | WriteVolInfo () |
Static Private Member Functions | |
| static string | CreateOffsetFileName (UInt32_t a_offset, dv_FileType_e a_type) |
Private Attributes | |
| log_CLASSID_m | |
| cmn_Path | m_dvPath |
| cmn_File | m_dvinfo |
| vector< VolFile > | m_files |
| UInt32_t | m_curFile |
Classes | |
| class | VolFile |
| bea_DiskVolume::bea_DiskVolume | ( | bea_Medium *const | a_medium_p, | |
| UInt32_t | a_volNumber, | |||
| UInt32_t | a_volSize | |||
| ) |
Definition at line 50 of file bea_diskvolume.cpp.
References dbg_NORM, log_DBG_m, log_FUNC_A_m, m_dvPath, ReadVolInfo(), ReparseFiles(), and bea_Volume::SetDeclaredSize().
00054 : bea_Volume(a_medium_p, a_volNumber, a_size), 00055 m_dvPath(bea_DiskMedium::GetDiskMediumPath(a_medium_p->GetBarcode()) + 00056 bea_DiskMedium::VolDirName(a_volNumber)), 00057 m_dvinfo( m_dvPath + dv_VOLINFO ), 00058 m_curFile(0) { 00059 00060 log_FUNC_A_m(bea_DiskVolume, 00061 "location: " << m_dvPath << " num: " << a_volNumber << " size: " << a_size); 00062 00063 if (a_size > 0) { 00064 log_DBG_m(dbg_NORM, "Setting default declared volume size to: " << a_size); 00065 SetDeclaredSize(a_size); 00066 }; 00067 00068 ReadVolInfo(); 00069 ReparseFiles(); 00070 }

| bea_DiskVolume::~bea_DiskVolume | ( | ) | [protected, virtual] |
Definition at line 74 of file bea_diskvolume.cpp.
References log_FUNC_m.
00074 { 00075 log_FUNC_m(~bea_DiskVolume); 00076 00077 // WriteVolInfo(); 00078 }
| UInt32_t bea_DiskVolume::GetPosition | ( | ) | [virtual] |
Implements bea_Volume.
Definition at line 154 of file bea_diskvolume.cpp.
References bea_DiskVolume::VolFile::blkOffset, df_VOLHDR_REC_SIZE, bea_DiskVolume::VolFile::file, file, bea_Volume::GetBlockSize(), cmn_File::GetCurrentPosF(), cmn_File::IsOpen(), log_FUNC_m, m_curFile, and m_files.
Referenced by ReadRaw(), SeekBlock(), and SeekEOD().
00154 { 00155 log_FUNC_m(GetPosition); 00156 00157 const VolFile& file = m_files[m_curFile]; 00158 UInt32_t position(file.blkOffset); 00159 00160 if (file.file.IsOpen()) { 00161 if (file.file.GetCurrentPosF() == 0) { 00162 position += 0; 00163 } 00164 else { 00165 ivd_FilePosition_t pos(file.file.GetCurrentPosF()); 00166 00167 // Special handling for volume header block, which occupies one 00168 // fixed-size block. 00169 if (m_curFile == 0) { 00170 if (pos < df_VOLHDR_REC_SIZE) { 00171 position = 0; 00172 } 00173 else { 00174 position = 1 + ( (pos - df_VOLHDR_REC_SIZE) / GetBlockSize() ); 00175 } 00176 } 00177 else { 00178 position += pos / GetBlockSize(); 00179 } 00180 } 00181 } 00182 return position; 00183 }


| void bea_DiskVolume::Erase | ( | ) | [virtual] |
Implements bea_Volume.
Definition at line 315 of file bea_diskvolume.cpp.
References dbg_DETAIL, dbg_NORM, cmn_File::DeleteF(), file, fom_READWRITE, cmn_File::GetCurrentPosF(), bea_Volume::InvalidateSizes(), cmn_File::IsOpen(), log_DBG_m, log_FUNC_m, bea_Volume::m_atEOD, m_curFile, m_files, cmn_File::OpenF(), cmn_File::SeekEndF(), size, and cmn_File::TruncF().
Referenced by WriteFileMarks(), and WriteRaw().
00315 { 00316 log_FUNC_m(Erase); 00317 00318 // WriteVolInfo(); 00319 InvalidateSizes(); 00320 00321 if (m_files.size() == 0) { 00322 return; 00323 } 00324 00325 UInt32_t deletedFiles(0); 00326 for (UInt32_t i(m_curFile+1); i < m_files.size(); ++i) { 00327 log_DBG_m(dbg_DETAIL, "Deleting file: " << i); 00328 cmn_File& file = m_files[i].file; 00329 file.DeleteF(); 00330 ++deletedFiles; 00331 } 00332 00333 cmn_File& file = m_files[m_curFile].file; 00334 if (!file.IsOpen()) { 00335 file.OpenF(fom_READWRITE); 00336 } 00337 00338 ivd_FilePosition_t pos = file.GetCurrentPosF(); 00339 if (pos == 0) { 00340 if (m_files[m_curFile].size > 0 || deletedFiles == 0) { 00341 log_DBG_m(dbg_DETAIL, 00342 "Positioned at the beginning of file. Deleting file: " << m_curFile); 00343 file.DeleteF(); 00344 --m_curFile; 00345 } 00346 else { 00347 log_DBG_m(dbg_DETAIL, 00348 "Erase already deleted files after empty file: " << m_curFile); 00349 } 00350 } 00351 else { 00352 log_DBG_m(dbg_DETAIL, 00353 "Truncating file " << m_curFile << " on position: " << pos); 00354 file.TruncF(pos); 00355 file.SeekEndF(); 00356 } 00357 00358 if (m_curFile+1 < m_files.size()) { 00359 m_files.resize(m_curFile+1); 00360 }; 00361 00362 log_DBG_m(dbg_NORM, 00363 "Files left after erasing: " << m_files.size() << "."); 00364 00365 m_atEOD = true; 00366 }


| void bea_DiskVolume::WriteFileMarks | ( | UInt32_t | a_count = 1 |
) | [virtual] |
Implements bea_Volume.
Definition at line 370 of file bea_diskvolume.cpp.
References CreateNewFile(), dbg_LOW, bea_Volume::DoMediumLogging(), Erase(), bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), log_DBG_m, log_FUNC_A_m, log_WriteEvent(), bea_Volume::m_atEOD, m_files, and bea_Volume::m_medium_p.
00370 { 00371 log_FUNC_A_m(WriteFileMarks, "count: " << a_count); 00372 00373 // WriteVolInfo(); 00374 00375 if (DoMediumLogging()) { 00376 ostringstream sstr; 00377 sstr << "Vol " << GetVolumeNumber() 00378 << ": Writing filemark(s) "<< a_count << "..."; 00379 00380 log_WriteEvent( 00381 sstr.str(), "", 00382 GetJobID(), 00383 m_medium_p->GetBarcode()); 00384 } 00385 00386 if (!m_atEOD) { 00387 Erase(); 00388 } 00389 00390 for (UInt32_t i(0); i < a_count; ++i) { 00391 CreateNewFile(); 00392 } 00393 00394 log_DBG_m(dbg_LOW, "Currently " << m_files.size() << " files on volume."); 00395 00396 m_atEOD = true; 00397 }

| void bea_DiskVolume::Flush | ( | ) | [virtual] |
Implements bea_Volume.
Definition at line 401 of file bea_diskvolume.cpp.
References file, cmn_File::IsOpen(), log_FUNC_m, m_curFile, m_files, and cmn_File::SyncF().
00401 { 00402 log_FUNC_m(Flush); 00403 00404 cmn_File& file = m_files[m_curFile].file; 00405 if (file.IsOpen()) { 00406 file.SyncF(); 00407 } 00408 00409 // WriteVolInfo(); 00410 }

| void bea_DiskVolume::SeekEOD | ( | ) | [virtual] |
Implements bea_Volume.
Definition at line 414 of file bea_diskvolume.cpp.
References cmn_File::CloseF(), dbg_DETAIL, df_VOLHDR_REC_SIZE, bea_Volume::DoMediumLogging(), ExtendToFullBlock(), fom_READWRITE, bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), bea_Volume::GetJobID(), GetPosition(), bea_Volume::GetVolumeNumber(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, log_WriteEvent(), bea_Volume::m_atEOD, m_curFile, m_dvPath, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), and cmn_File::SeekEndF().
00414 { 00415 log_FUNC_m(SeekEOD); 00416 00417 if (DoMediumLogging()) { 00418 ostringstream sstr; 00419 sstr << "Vol " << GetVolumeNumber() 00420 << ": Seeking to EOD..."; 00421 00422 log_WriteEvent( 00423 sstr.str(), "", 00424 GetJobID(), 00425 m_medium_p->GetBarcode()); 00426 } 00427 00428 if (m_files.size() == 0) { 00429 m_curFile = 0; 00430 } 00431 else { 00432 cmn_File& cf = m_files[m_curFile].file; 00433 cf.CloseF(); 00434 00435 m_curFile = m_files.size()-1; 00436 cmn_File& lf = m_files[m_curFile].file; 00437 lf.OpenF(fom_READWRITE); 00438 ivd_FilePosition_t filePos = lf.SeekEndF(); 00439 00440 // 00441 // Check consistency of the file: EOD must be either: 00442 // - at the end of the header: size is known 00443 // - EOF position must be divisible by block size 00444 // 00445 if (m_curFile == 0) { 00446 if ( filePos != df_VOLHDR_REC_SIZE + GetBlockSize() ) { 00447 ostringstream sstr; 00448 sstr << "Disk medium error (header size mismatch): " << m_dvPath; 00449 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str()); 00450 } 00451 } 00452 else { 00453 ExtendToFullBlock(lf, filePos, GetBlockSize()); 00454 } 00455 } 00456 m_atEOD = true; 00457 00458 if (DoMediumLogging()) { 00459 ostringstream sstr; 00460 sstr << "Vol " << GetVolumeNumber() 00461 << ": At EOD (" << GetPosition() << ")"; 00462 00463 log_WriteEvent( 00464 sstr.str(), "", 00465 GetJobID(), 00466 m_medium_p->GetBarcode()); 00467 } 00468 00469 log_DBG_m(dbg_DETAIL, 00470 "Volume:" << m_dvPath << " CurrentFile:" << m_curFile); 00471 }

| void bea_DiskVolume::Rewind | ( | ) | [virtual] |
Implements bea_Volume.
Definition at line 568 of file bea_diskvolume.cpp.
References bea_Volume::DoMediumLogging(), bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), log_FUNC_m, log_WriteEvent(), bea_Volume::m_medium_p, and SeekBlock().
00568 { 00569 log_FUNC_m(Rewind); 00570 00571 if (DoMediumLogging()) { 00572 ostringstream sstr; 00573 sstr << "Vol " << GetVolumeNumber() 00574 << ": Rewind..."; 00575 00576 log_WriteEvent( 00577 sstr.str(), "", 00578 GetJobID(), 00579 m_medium_p->GetBarcode()); 00580 } 00581 00582 SeekBlock(0); 00583 }

| void bea_DiskVolume::SeekBlock | ( | UInt32_t | a_block | ) | [virtual] |
Implements bea_Volume.
Definition at line 475 of file bea_diskvolume.cpp.
References bea_DiskVolume::VolFile::blkOffset, cmn_File::CloseF(), dbg_DETAIL, dbg_LOW, bea_Volume::DoMediumLogging(), bea_DiskVolume::VolFile::file, fom_READ, bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), bea_Volume::GetJobID(), GetPosition(), bea_Volume::GetVolumeNumber(), ie_FATAL_ERROR, ie_MEDIUM_EOM, bea_Volume::InvalidateEOD(), bea_Volume::InvalidateSizes(), ivd_Error, log_DBG_m, log_FUNC_A_m, log_MARKLINE_m, log_WriteEvent(), m_curFile, m_dvPath, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), cmn_File::SeekF(), and bea_DiskVolume::VolFile::size.
Referenced by Rewind().
00475 { 00476 log_FUNC_A_m(SeekBlock, " blk: " << a_block); 00477 00478 if (DoMediumLogging()) { 00479 ostringstream sstr; 00480 sstr << "Vol " << GetVolumeNumber() 00481 << ": Seeking to " << a_block << "..."; 00482 00483 log_WriteEvent( 00484 sstr.str(), "", 00485 GetJobID(), 00486 m_medium_p->GetBarcode()); 00487 } 00488 00489 InvalidateSizes(); 00490 InvalidateEOD(); 00491 00492 if (m_files.size() == 0) { 00493 if (a_block > 0) { 00494 throw ivd_Error(ie_MEDIUM_EOM, "Disk volume is empty. Already on EOM."); 00495 } 00496 else { 00497 return; 00498 } 00499 } 00500 00501 UInt32_t tgtFile(UINT_MAX); 00502 UInt32_t relOffset(0); 00503 00504 cmn_File& cf = m_files[m_curFile].file; 00505 cf.CloseF(); 00506 00507 if (a_block == 0) { 00508 tgtFile = 0; 00509 relOffset = 0; 00510 VolFile& tf = m_files[tgtFile]; 00511 tf.file.OpenF(fom_READ); 00512 tf.file.SeekF(0); 00513 } 00514 else { 00515 for (UInt32_t i(0); i < m_files.size(); ++i) { 00516 if (m_files[i].blkOffset > a_block) { 00517 tgtFile = i-1; 00518 break; 00519 } 00520 } 00521 00522 // Try the last file 00523 if (tgtFile == UINT_MAX) { 00524 tgtFile = m_files.size()-1; 00525 } 00526 00527 VolFile& tf = m_files[tgtFile]; 00528 tf.file.OpenF(fom_READ); 00529 00530 relOffset = a_block - tf.blkOffset; 00531 ivd_FilePosition_t seekPos(static_cast<ivd_FilePosition_t>(relOffset) * GetBlockSize()); 00532 00533 if (seekPos > tf.size) { 00534 log_MARKLINE_m; 00535 #if TGT_OS_linux 00536 #warning Check consistency of the file size (see SeekEOD). 00537 #endif 00538 if (tgtFile == m_files.size()-1) { 00539 throw ivd_Error(ie_MEDIUM_EOM, "Seek over the EOD."); 00540 } 00541 else { 00542 throw ivd_InternalError(ie_FATAL_ERROR, 00543 "Invalid internal calculation.", 00544 string("Seek over the size of the file.")); 00545 } 00546 }; 00547 tf.file.SeekF(seekPos); 00548 } 00549 00550 m_curFile = tgtFile; 00551 00552 log_DBG_m(dbg_DETAIL, "Volume:" << m_dvPath << 00553 " CurrentFile:" << m_curFile ); 00554 00555 // Verify that new position is OK. 00556 UInt32_t newPosition(GetPosition()); 00557 if ( newPosition != a_block ) { 00558 log_DBG_m(dbg_LOW, "CurrentPosition: " << newPosition << " a_blk: " << a_block); 00559 00560 throw ivd_InternalError(ie_FATAL_ERROR, 00561 "Invalid internal calculation.", 00562 string("GetPosition() returns value different from a_block.")); 00563 } 00564 }


| void bea_DiskVolume::SeekFileMark | ( | Int32_t | a_relativeFM | ) | [virtual] |
Implements bea_Volume.
Definition at line 587 of file bea_diskvolume.cpp.
References cmn_File::CloseF(), dbg_NORM, bea_Volume::DoMediumLogging(), bea_DiskVolume::VolFile::file, fom_READWRITE, bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), ie_MEDIUM_BLANK, ie_MEDIUM_EOD, bea_Volume::InvalidateEOD(), ivd_Error, log_DBG_m, log_FUNC_A_m, log_MARKLINE_m, log_WriteEvent(), bea_Volume::m_atEOD, m_curFile, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), and cmn_File::SeekEndF().
00587 { 00588 log_FUNC_A_m(SeekFileMark, "relativeFM: " << a_relativeFM); 00589 00590 if (DoMediumLogging()) { 00591 ostringstream sstr; 00592 sstr << "Vol " << GetVolumeNumber() 00593 << ": Seeking " << a_relativeFM << " filemark(s) forward..."; 00594 00595 log_WriteEvent( 00596 sstr.str(), "", 00597 GetJobID(), 00598 m_medium_p->GetBarcode()); 00599 } 00600 00601 InvalidateEOD(); 00602 00603 if (m_files.size() == 0) { 00604 if (a_relativeFM > 0) { 00605 log_MARKLINE_m; 00606 throw ivd_Error(ie_MEDIUM_BLANK); 00607 } 00608 else { 00609 m_curFile = 0; 00610 return; 00611 } 00612 } 00613 00614 VolFile& cf = m_files[m_curFile]; 00615 cf.file.CloseF(); 00616 00617 Int32_t absFile = m_curFile + a_relativeFM; 00618 00619 if (absFile < 0) { 00620 m_curFile = 0; 00621 return; 00622 } 00623 00624 // Seeking over the end of medium 00625 if (UInt32_t(absFile) >= m_files.size()) { 00626 m_curFile = m_files.size()-1; 00627 VolFile& tf = m_files[m_curFile]; 00628 tf.file.OpenF(fom_READWRITE); 00629 (void)tf.file.SeekEndF(); 00630 m_atEOD = true; 00631 throw ivd_Error(ie_MEDIUM_EOD, "Seek over the disk volume boundaries."); 00632 } 00633 00634 // Positioning to proper file 00635 m_curFile = absFile; 00636 VolFile& tf = m_files[m_curFile]; 00637 tf.file.OpenF(fom_READWRITE); 00638 00639 log_DBG_m(dbg_NORM, "Positioned to file: " << m_curFile); 00640 00641 // This is the same as the tape: negative seek positions just before 00642 // the file mark. 00643 if (a_relativeFM < 0) { 00644 log_DBG_m(dbg_NORM, "Reverse file mark seek -> positioning to end of file."); 00645 (void)tf.file.SeekEndF(); 00646 } 00647 }

Implements bea_Volume.
Definition at line 187 of file bea_diskvolume.cpp.
References CreateNewFile(), Erase(), file, fom_READWRITE, cmn_File::GetCurrentPosF(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), ie_MEDIUM_MEDERR, ie_MEDIUM_OVERFLOW, cmn_File::IsOpen(), ivd_Error, log_FUNC_m, log_WRN_m, bea_Volume::m_atEOD, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), cmn_File::TruncF(), and cmn_File::WriteF().
00187 { 00188 log_FUNC_m(WriteRaw); 00189 00190 if (!m_atEOD) { 00191 Erase(); 00192 } 00193 00194 if (m_files.empty()) { 00195 CreateNewFile(); 00196 } 00197 00198 cmn_File& file = m_files[m_curFile].file; 00199 00200 if (!file.IsOpen()) { 00201 file.OpenF(fom_READWRITE); 00202 } 00203 00204 try { 00205 // 00206 // Atomic append to the file. 00207 // TODO: Shall this functionality be moved to cmn_File? 00208 // 00209 ivd_FileRetSize_t wrote = file.WriteF(a_buf, a_size); 00210 00211 if (static_cast<UInt32_t>(wrote) < a_size) { 00212 log_WRN_m( 00213 "Writing failed. Truncating file to last full block: " << 00214 file.GetFullPathRef() ); 00215 00216 ivd_FilePosition_t filePos = file.GetCurrentPosF(); 00217 file.TruncF(filePos - wrote); 00218 00219 ostringstream sstr; 00220 sstr << "Disk medium out of space: " << m_dvPath; 00221 throw ivd_Error(ie_MEDIUM_OVERFLOW, sstr.str(), true); 00222 } 00223 } 00224 catch (const ivd_SysError& se) { 00225 if (se.GetError() == ENOSPC) { 00226 ostringstream sstr; 00227 sstr << "Disk medium out of space: " << m_dvPath; 00228 throw ivd_Error(ie_MEDIUM_OVERFLOW, sstr.str(), true); 00229 } 00230 else { 00231 ostringstream sstr; 00232 sstr << "Disk medium error: " << m_dvPath; 00233 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly()); 00234 } 00235 }; 00236 00237 m_files[m_curFile].size += a_size; 00238 }

Implements bea_Volume.
Definition at line 242 of file bea_diskvolume.cpp.
References cmn_File::CloseF(), dbg_NORM, df_VOLHDR_REC_SIZE, ExtendToFullBlock(), file, fom_READWRITE, bea_Volume::GetBlockSize(), cmn_File::GetCurrentPosF(), ivd_BaseException::GetFriendly(), GetPosition(), ie_DATA_CORRUPTION, ie_MEDIUM_BLANK, ie_MEDIUM_EOD, ie_MEDIUM_FILEMARK, ie_MEDIUM_ILENGTH, ie_MEDIUM_MEDERR, cmn_File::IsOpen(), ivd_Error, log_DBG_m, log_FUNC_m, log_WRN_m, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), and cmn_File::ReadF().
00242 { 00243 log_FUNC_m(ReadRaw); 00244 00245 if ( m_files.size() == 0 || 00246 (m_files.size() == 1 && m_files[0].size == 0) ) { 00247 throw ivd_Error(ie_MEDIUM_BLANK); 00248 } 00249 00250 if (m_files.size() <= m_curFile) { 00251 throw ivd_InternalError(ie_DATA_CORRUPTION, "m_curFile >= #files"); 00252 } 00253 00254 cmn_File& file = m_files[m_curFile].file; 00255 00256 if (!file.IsOpen()) { 00257 file.OpenF(fom_READWRITE); 00258 } 00259 00260 UInt32_t toRead(a_size); 00261 if (GetPosition() == 0) { 00262 toRead = df_VOLHDR_REC_SIZE; 00263 } 00264 00265 UInt32_t readAmount(0); 00266 try { 00267 readAmount = file.ReadF(a_buf, toRead); 00268 } 00269 catch (const ivd_SysError& se) { 00270 ostringstream sstr; 00271 sstr << "Disk medium error: " << m_dvPath; 00272 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly()); 00273 }; 00274 00275 if (readAmount == 0) { 00276 if (m_curFile == (m_files.size()-1) ) { 00277 throw ivd_Error(ie_MEDIUM_EOD, "End of disk volume reached."); 00278 } 00279 else { 00280 log_DBG_m(dbg_NORM, "File mark reached. Skip over to next file."); 00281 file.CloseF(); 00282 ++m_curFile; 00283 throw ivd_Error(ie_MEDIUM_FILEMARK, "Disk medium filemark reached."); 00284 } 00285 } 00286 00287 if (readAmount < toRead) { 00288 if ( (m_curFile + 1) == m_files.size() && m_curFile > 0) { 00289 ivd_FilePosition_t pos = file.GetCurrentPosF(); 00290 bea_DiskVolume::ExtendToFullBlock(file, pos, GetBlockSize()); 00291 } 00292 else { 00293 log_WRN_m( 00294 "Read less that requested on non-last file."); 00295 } 00296 00297 ostringstream sstr; 00298 sstr 00299 << "Read less (" << readAmount 00300 << ") than block size (" << toRead << ")."; 00301 00302 throw ivd_Error(ie_MEDIUM_ILENGTH, "File too short.", sstr.str()); 00303 } 00304 00305 if (toRead < a_size) { 00306 ostringstream sstr; 00307 sstr << "Attempt to read more (" << a_size 00308 << ") than block size (" << toRead << ")."; 00309 throw ivd_Error(ie_MEDIUM_ILENGTH, sstr.str()); 00310 } 00311 }

| void bea_DiskVolume::ReadEstimSizes | ( | ) | [protected, virtual] |
Reads estimated overall and remaining capacity of this medium volume.
It stores the values so that they can be retrieved by Get* methods. This method converts sizes to MB.
Implements bea_Volume.
Definition at line 657 of file bea_diskvolume.cpp.
References ivd_FileSystemSize_t::bytesFree, ivd_FileSystemSize_t::bytesTotal, cfg_MEGABYTE, dbg_DETAIL, dbg_LOW, dbg_NORM, bea_Medium::GetCurVolNumber(), cmn_File::GetFileSystemSize(), bea_Volume::GetSize(), bea_Volume::GetVolumeNumber(), ie_INVALID_ARG, ivd_Error, log_DBG_m, log_FUNC_m, log_WRN_m, m_dvPath, m_files, bea_Volume::m_medium_p, and bea_Volume::SetEstimatedSizes().
00657 { 00658 log_FUNC_m(ReadEstimSizes); 00659 00660 if (m_medium_p->GetCurVolNumber() != GetVolumeNumber()) { 00661 throw ivd_Error( 00662 ie_INVALID_ARG, 00663 "Estimated sizes can only be read for current volume."); 00664 }; 00665 00666 UInt32_t estimSize(GetSize()); 00667 UInt64_t sumOfFiles(0); 00668 UInt32_t estimFree(0); 00669 for (UInt32_t i(0); i < m_files.size(); i++) { 00670 // Re-read file allocated sizes. 00671 ivd_FileInfo_t info; 00672 m_files[i].file.StatF(info); 00673 00674 sumOfFiles += info.allocated; 00675 } 00676 sumOfFiles /= cfg_MEGABYTE; 00677 log_DBG_m(dbg_DETAIL, "sumOfFiles:" << sumOfFiles); 00678 00679 if (sumOfFiles <= estimSize) { 00680 estimFree = estimSize - sumOfFiles; 00681 log_DBG_m(dbg_DETAIL, "estimFree:" << estimFree); 00682 } 00683 else { 00684 log_WRN_m("Sum of file size bigger that actual space."); 00685 estimFree = 0; 00686 }; 00687 00688 { 00689 cmn_File info(m_dvPath); 00690 ivd_FileSystemSize_t fsSize; 00691 info.GetFileSystemSize(fsSize); 00692 00693 log_DBG_m(dbg_NORM, "fsSize.bytesTotal:" << fsSize.bytesTotal << 00694 ", fsSize.bytesFree:" << fsSize.bytesFree); 00695 00696 if ( (fsSize.bytesTotal/cfg_MEGABYTE) < estimSize) { 00697 estimSize = fsSize.bytesTotal/cfg_MEGABYTE; 00698 log_DBG_m(dbg_LOW, 00699 "File system size is smaller than declared size. Using " << 00700 estimSize); 00701 } 00702 00703 if ( (fsSize.bytesFree/cfg_MEGABYTE) < estimFree) { 00704 estimFree = fsSize.bytesFree/cfg_MEGABYTE; 00705 log_DBG_m(dbg_LOW, 00706 "File system free space is smaller than declared size. Using " << 00707 estimFree); 00708 } 00709 }; 00710 00711 log_DBG_m(dbg_NORM, 00712 "Estimated capacity info [MB]:" << 00713 " total: " << estimSize << " free : " << estimFree); 00714 00715 SetEstimatedSizes(estimSize, estimFree); 00716 }

| void bea_DiskVolume::ReparseFiles | ( | ) | [private] |
Definition at line 720 of file bea_diskvolume.cpp.
References val_Integer::Bind(), val_Value::Conv(), dbg_DETAIL, dbg_LOW, dbg_NORM, dv_FRIFile, dv_HeaderFile, dv_VOLINFO, cmn_DirLst::GetNextName(), GetTypeFromExt(), ie_MEDIUM_MEDERR, ift_FILE, ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, m_dvPath, m_files, stat(), and cmn_File::StatF().
Referenced by bea_DiskVolume().
00720 { 00721 log_FUNC_m(ReparseFiles); 00722 // Scan for <offset>.[hdr|dta|fri] files 00723 00724 list<string> volFNames; 00725 { 00726 cmn_DirLst volFiles(m_dvPath, ""); 00727 string name; 00728 name = volFiles.GetNextName(); 00729 while ( name.size() > 0 ) { 00730 cmn_Path fullName(m_dvPath + name); 00731 ivd_FileType_e type; 00732 { 00733 cmn_File entry(fullName); 00734 ivd_FileInfo_t stat; 00735 entry.StatF(stat); 00736 type = stat.type; 00737 } 00738 00739 string firstChar = name.substr(0, 1); //bug 8417 ignore all hidden files (e.g. sh_history) 00740 00741 if ( (name.compare(".") == 0) || 00742 (name.compare("..") == 0) || 00743 (firstChar.compare(".") == 0) || 00744 (name.compare(dv_VOLINFO) == 0) ) { 00745 00746 log_DBG_m(dbg_DETAIL, "Skipped file."); 00747 } 00748 else { 00749 if (type != ift_FILE) { 00750 log_MARKLINE_m; 00751 ostringstream sstr; 00752 sstr << m_dvPath << ": Found non-file entry \'" << name << "\'"; 00753 log_DBG_m(dbg_LOW, "Entry type: " << type); 00754 00755 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str()); 00756 }; 00757 volFNames.push_back(name); 00758 } 00759 name = volFiles.GetNextName(); 00760 } 00761 volFNames.sort(); 00762 } 00763 00764 list<string>::const_iterator name_i; 00765 UInt32_t idx(0); 00766 for (name_i = volFNames.begin(); name_i != volFNames.end(); ++name_i) { 00767 const string& fn(*name_i); 00768 string::size_type dotPos = fn.find_first_of('.'); 00769 if (dotPos == string::npos || dotPos == 0) { 00770 log_MARKLINE_m; 00771 throw ivd_Error(ie_MEDIUM_MEDERR, 00772 string("Invalid disk volume name: ") + fn); 00773 } 00774 00775 string offsetStr(fn.substr(0, dotPos)); 00776 string extStr(fn.substr(dotPos)); 00777 00778 VolFile volFile; 00779 val_Integer iv("Offset", val_Limit(0, UINT_MAX)); 00780 iv.Bind(volFile.blkOffset); 00781 iv.Conv(offsetStr); 00782 00783 volFile.type = GetTypeFromExt(extStr); 00784 volFile.file.SetFullPath(m_dvPath + fn); 00785 00786 if (idx == 0) { 00787 if (volFile.type != dv_HeaderFile) { 00788 throw ivd_Error(ie_MEDIUM_MEDERR, 00789 "Header file not on the first place."); 00790 } 00791 else if (volFile.blkOffset != 0) { 00792 throw ivd_Error(ie_MEDIUM_MEDERR, 00793 "Block offset for header larger that 0."); 00794 } 00795 } 00796 else if (idx < (volFNames.size()-1)) { 00797 if (volFile.type == dv_FRIFile) { 00798 throw ivd_Error(ie_MEDIUM_MEDERR, 00799 "FRI file not on the last place."); 00800 } 00801 } 00802 00803 ivd_FileInfo_t info; 00804 volFile.file.StatF(info); 00805 volFile.size = info.size; 00806 00807 m_files.push_back(volFile); 00808 00809 log_DBG_m(dbg_NORM, "Found valid file: " << fn); 00810 00811 ++idx; 00812 } 00813 00814 }


| bea_DiskVolume::dv_FileType_e bea_DiskVolume::GetTypeFromExt | ( | const string & | a_extStr | ) | [private] |
Definition at line 839 of file bea_diskvolume.cpp.
References dv_DATA_EXT, dv_DataFile, dv_FRI_EXT, dv_FRIFile, dv_HEADER_EXT, dv_HeaderFile, ie_MEDIUM_MEDERR, and ivd_Error.
Referenced by ReparseFiles().
00839 { 00840 00841 if (a_extStr.compare(dv_HEADER_EXT) == 0) { 00842 return dv_HeaderFile; 00843 } 00844 else if (a_extStr.compare(dv_DATA_EXT) == 0) { 00845 return dv_DataFile; 00846 } 00847 else if (a_extStr.compare(dv_FRI_EXT) == 0) { 00848 return dv_FRIFile; 00849 } 00850 else { 00851 throw ivd_Error(ie_MEDIUM_MEDERR, string("Wrong extension: ") + a_extStr); 00852 }; 00853 }

| string bea_DiskVolume::CreateOffsetFileName | ( | UInt32_t | a_offset, | |
| dv_FileType_e | a_type | |||
| ) | [static, private] |
Definition at line 819 of file bea_diskvolume.cpp.
References dv_DATA_EXT, dv_DataFile, dv_FRI_EXT, dv_FRIFile, dv_HEADER_EXT, and dv_HeaderFile.
Referenced by CreateNewFile().
00819 { 00820 00821 ostringstream ostr; 00822 ostr 00823 << std::setw(8) 00824 << std::setfill('0') 00825 << a_offset; 00826 00827 switch (a_type) { 00828 case dv_HeaderFile: ostr << dv_HEADER_EXT; break; 00829 case dv_DataFile: ostr << dv_DATA_EXT; break; 00830 case dv_FRIFile: ostr << dv_FRI_EXT; break; 00831 }; 00832 00833 return ostr.str(); 00834 00835 }

| void bea_DiskVolume::CreateNewFile | ( | ) | [private] |
Definition at line 857 of file bea_diskvolume.cpp.
References bea_DiskVolume::VolFile::blkOffset, cmn_File::CloseF(), CreateOffsetFileName(), dbg_LOW, dbg_NORM, dv_DataFile, dv_FRIFile, dv_HeaderFile, file, bea_DiskVolume::VolFile::file, fom_CREATE_NEW, bea_Volume::GetBlockSize(), cmn_File::GetFullPathRef(), ie_DATA_CORRUPTION, log_DBG_m, log_FUNC_m, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), S_IREAD, S_IWRITE, cmn_File::SetFullPath(), bea_DiskVolume::VolFile::size, and bea_DiskVolume::VolFile::type.
Referenced by WriteFileMarks(), and WriteRaw().
00857 { 00858 log_FUNC_m(CreateNewFile); 00859 00860 cmn_Path filePath( m_dvPath ); 00861 00862 VolFile vol; 00863 UInt32_t blkOffset(0); 00864 if (m_files.size() == 0) { 00865 //make .hdr file. 00866 filePath += CreateOffsetFileName(0, dv_HeaderFile); 00867 vol.type = dv_HeaderFile; 00868 } 00869 else { 00870 UInt32_t absOffset(0); 00871 UInt32_t relOffset(0); 00872 if (m_files.size() == 1) { 00873 //make .vdf 00874 vol.type = dv_DataFile; 00875 relOffset = 2; 00876 } 00877 else if (m_files.size() == 2) { 00878 //make .fri 00879 vol.type = dv_FRIFile; 00880 00881 VolFile& f = m_files[m_files.size() - 1]; 00882 absOffset = f.blkOffset; 00883 relOffset = f.size/GetBlockSize(); 00884 } 00885 else { 00886 ostringstream sstr; 00887 sstr 00888 << "All files of the volume " << m_dvPath 00889 << " already exist."; 00890 throw ivd_InternalError(ie_DATA_CORRUPTION, sstr.str()); 00891 } 00892 00893 log_DBG_m(dbg_NORM, 00894 "Offset of file: " << absOffset << " Offset in file: " << relOffset); 00895 00896 // Simulate tape: each file mark uses one SCSI block 00897 blkOffset = absOffset + relOffset + 1; 00898 filePath += CreateOffsetFileName(blkOffset, vol.type); 00899 } 00900 00901 log_DBG_m(dbg_LOW, "Creating new file:" << filePath); 00902 00903 vol.file.SetFullPath(filePath); 00904 vol.file.OpenF(fom_CREATE_NEW); 00905 vol.file.CloseF(); 00906 00907 // Change permissions to allow access only for the owner 00908 #if TGT_OS_windows 00909 (void)chmod(filePath.c_str(), S_IREAD|S_IWRITE); 00910 #elif TGT_OS_linux 00911 (void)chmod(filePath.c_str(), S_IRUSR | S_IWUSR); 00912 #endif 00913 00914 vol.size = 0; 00915 vol.blkOffset = blkOffset; 00916 00917 log_DBG_m(dbg_NORM, "vol.file.PATH:" << vol.file.GetFullPathRef() << 00918 " vol.size:" << vol.size << 00919 " vol.blkOffset:" << vol.blkOffset); 00920 00921 if (m_files.size() > 0) { 00922 cmn_File& file = m_files[m_curFile].file; 00923 file.CloseF(); 00924 } 00925 00926 m_files.push_back(vol); 00927 m_curFile = m_files.size() - 1; 00928 }


| void bea_DiskVolume::ExtendToFullBlock | ( | cmn_File & | a_file, | |
| ivd_FilePosition_t | a_filePos, | |||
| UInt32_t | a_blkSize | |||
| ) | [private] |
Definition at line 930 of file bea_diskvolume.cpp.
References ivd_BaseException::GetFriendly(), ie_MEDIUM_MEDERR, ivd_Error, log_FUNC_m, log_WRN_m, m_dvPath, and cmn_File::TruncF().
Referenced by ReadRaw(), and SeekEOD().
00933 { 00934 00935 log_FUNC_m(ExtendToFullBlock); 00936 00937 Int32_t remainder = a_filePos % a_blkSize; 00938 if (remainder != 0) { 00939 ivd_FilePosition_t extSize = a_filePos + a_blkSize - remainder; 00940 log_WRN_m( 00941 "Disk medium error (size mismatch): " << m_dvPath << 00942 " Autocorrecting: Extending file to next block: " << extSize); 00943 try { 00944 a_file.TruncF(extSize); 00945 } 00946 catch (const ivd_SysError& se) { 00947 ostringstream sstr; 00948 sstr << "Disk medium error (extending failed): " << m_dvPath; 00949 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly() ); 00950 } 00951 } 00952 }


| void bea_DiskVolume::ReadVolInfo | ( | ) | [private] |
Definition at line 83 of file bea_diskvolume.cpp.
References cmn_File::CloseF(), dbg_LOW, dbg_NORM, fom_READ, ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), bea_Volume::GetSize(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, m_dvinfo, cmn_File::OpenF(), cmn_File::ReadF(), bea_Volume::SetDeclaredSize(), dv_Info_t::size, and WriteVolInfo().
Referenced by bea_DiskVolume().
00083 { 00084 log_FUNC_m(ReadVolInfo); 00085 00086 dv_Info_t info; 00087 00088 try { 00089 m_dvinfo.OpenF(fom_READ); 00090 m_dvinfo.ReadF(&info, sizeof(info)); 00091 m_dvinfo.CloseF(); 00092 00093 log_DBG_m(dbg_LOW, "Disk volume size: " << info.size); 00094 SetDeclaredSize(info.size); 00095 } 00096 catch (const ivd_Error& ie) { 00097 log_DBG_m(dbg_LOW, "Can't read volume info: " << ie.GetFriendly() ); 00098 throw ivd_Error(ie_MEDIUM_MEDERR, 00099 string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(), 00100 ie.GetFriendly(), 00101 true); 00102 } 00103 catch (const ivd_SysError& ie) { 00104 if (ie.GetError() == ENOENT) { 00105 if (GetSize() > 0) { 00106 log_DBG_m(dbg_NORM, "vol.info doesn't exist. Creating new."); 00107 WriteVolInfo(); 00108 } 00109 else { 00110 log_DBG_m(dbg_LOW, 00111 "Volume info doesn't exist, but no new size specified: " << 00112 ie.GetFriendly() ); 00113 throw ivd_Error(ie_MEDIUM_MEDERR, 00114 string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(), 00115 ie.GetFriendly(), 00116 true); 00117 } 00118 } 00119 else { 00120 log_DBG_m(dbg_LOW, "Can't read volume info: " << ie.GetFriendly() ); 00121 throw ivd_Error(ie_MEDIUM_MEDERR, 00122 string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(), 00123 ie.GetFriendly(), 00124 true); 00125 }; 00126 } 00127 }


| void bea_DiskVolume::WriteVolInfo | ( | ) | [private] |
Definition at line 131 of file bea_diskvolume.cpp.
References cmn_File::CloseF(), dbg_LOW, fom_CREATE_ALWAYS, fom_WRITE, ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), bea_Volume::GetSize(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, m_dvinfo, cmn_File::OpenF(), dv_Info_t::size, and cmn_File::WriteF().
Referenced by ReadVolInfo().
00131 { 00132 log_FUNC_m(WriteVolInfo); 00133 00134 dv_Info_t info; 00135 00136 info.size = GetSize(); 00137 00138 try { 00139 m_dvinfo.OpenF(fom_WRITE | fom_CREATE_ALWAYS); 00140 m_dvinfo.WriteF(&info, sizeof(info)); 00141 m_dvinfo.CloseF(); 00142 } 00143 catch (const ivd_Exception& ie) { 00144 log_DBG_m(dbg_LOW, "Can't write volume info: " << ie.GetFriendly() ); 00145 throw ivd_Error(ie_MEDIUM_MEDERR, 00146 string("Can't write volume info: ") + m_dvinfo.GetFullPathRef(), 00147 ie.GetFriendly(), 00148 true); 00149 } 00150 00151 }


bea_DiskVolume::log_CLASSID_m [private] |
cmn_Path bea_DiskVolume::m_dvPath [private] |
Definition at line 92 of file bea_diskvolume.h.
Referenced by bea_DiskVolume(), CreateNewFile(), ExtendToFullBlock(), ReadEstimSizes(), ReadRaw(), ReparseFiles(), SeekBlock(), SeekEOD(), and WriteRaw().
cmn_File bea_DiskVolume::m_dvinfo [private] |
vector<VolFile> bea_DiskVolume::m_files [private] |
Definition at line 95 of file bea_diskvolume.h.
Referenced by CreateNewFile(), Erase(), Flush(), GetPosition(), ReadEstimSizes(), ReadRaw(), ReparseFiles(), SeekBlock(), SeekEOD(), SeekFileMark(), WriteFileMarks(), and WriteRaw().
UInt32_t bea_DiskVolume::m_curFile [private] |
Definition at line 96 of file bea_diskvolume.h.
Referenced by CreateNewFile(), Erase(), Flush(), GetPosition(), ReadRaw(), SeekBlock(), SeekEOD(), SeekFileMark(), and WriteRaw().
1.5.6