Archive.html
---------------------------------------------------------------------
CLASS: Archive --DVM
PUBLIC METHODS:
_GENERAL_
error() - return error state
setDevice() - supply a device
openArchive() - open, supplying volset info
closeArchive() - close
_LABELING_
getVolumeInfo() - return info about a vol
addLabeledVolume() - add a labeled vol
isCompleteVolSet() - True if no missing vols
getVolSetInfo() - return info about a volume set
getRootVolume() - identify which vol in set is root
checkOpenIntegrity() - is logicalVol open?
markOpenIntegrity() - mark logicalVol as open
destroyFileSet() - render fileset inaccessible
destroyVolumeLabel() - make a vol unlabeled
getWriteProtect() - return logicalVol status
setWriteProtect() - set logicalVol writeprot status
_GROWING_
beginGrow() - start volume set growth process
addUnlabeledVolume() - label and add an unlabeled vol
completeGrow() - end volume set growth process
_EXPORT_
overflowSectors() - return extra space needed for ICB
sizeICBTable() - return space needed for ICBs
sizeDirectory() - return space needed for a directory
setAvailSpace() - supply free space for a volume
allocateSeqSectors() - alloc space for USE,FSD sequences
allocateICBTable() - alloc space for ICBTable
beginExport() - start export process
createDirectory() - create a directory
addDirEntry() - add a file or subdir to current dir
writeDirectory() - write current dir
closeDirectory() - go back to parent dir
writeRootICB() - write ICB for root dir
writeNextICB() - write next ICB in ICBTable
completeExport() - end export process
_IMPORT_
getImplementInfo() - return info on who wrote fileset
beginImport() - start import process
readRootICB() - read ICB for root dir
readNextICB() - read next ICB in table
endOfICBTable() - at end of ICB table
readPath() - read path for symlink
locateDirectory() - seek to and open a dir
numDirEntries() - return # entries in current dir
getFirstDirEntry() - get first entry in current dir
getNextDirEntry() - get next entry in current dir
getDirEntry() - get specified entry in current dir
endOfDirectory() - at end of current dir
completeImport() - end import process
_DEBUGGING_
logFile() - sets file to log to.
logErrors() - enables/disables logging of error state.
logAlgorithms() - enables/disables miscellaneous printf() s
logCalls() - enables/disables logging of entries/exits
USAGE NOTES:
User notes go here.
----------------------------------------------------------------------
---------------------------------------------------------------------
METHOD: Archive::setDevice
ARGS:
MSDevice dev IN multi-surface device object
RETURNS:
PRE-CONDS:
POST-CONDS:
The private data member "currentDevice" is set.
ERRORS:
NOTES: import & export
----------------------------------------------------------------------
void
NSR::Archive::setDevice( MSDevice *msDev )
{
---------------------------------------------------------------------
METHOD: Archive::openArchive
ARGS:
UINT16 maxNumLabeledVols IN maximum number of labeled
volumes in set
const char *volSetName IN volume set name
UINT32 sectorSize IN logical block size
MediaType mt IN Rewritable or WORM
RETURNS:
PRE-CONDS:
POST-CONDS:
- volumeTable is populated with empty volumes. It will be filled
in later with real volume information via the function
addVolume(). Note that this implementation will likely change in
order to allow the
- various other private member variables are set.
ERRORS:
openArchive replaces the pre-alpha createArchive() and
openArchive(). It requires a vsname, lvname, and a sectorSize, as
well as the number of volumes in the volume set. The other two
parameters from createArchive() are moved as follows:
- fsname - beginExport(fsname)
- fileDataStartSector - addUnlabeledVol(labelLimit)
openArchive now also requires the media type, replacing
setMediaType(). NOTE that the mediaType and sectorSize are then
checked against the properties of the media in addVolume().
NOTE that the vsname is simply stored off in a data member, and
addVolume does not allow any volumes to be added whose vsname does
not match it.
NOTE ALSO that the sectorSize is used in the calculation of the
overflow numbers below, inside of openArchive.
- extentsPerICB
- extentsPerBlock
- extentsPerUSE
- extentsPerAED
CONCERNS:
- How will other methods cope without the default openArchive()? Do
we need to have a private openArchive() with no parms? Surely it
should be named something else...?
----------------------------------------------------------------------
void
NSR::Archive::openArchive( UINT16 maxNumLabeledVols,
const char *volSetName,
UINT32 sectorSize,
MediaType mt )
{
---------------------------------------------------------------------
METHOD: Archive::closeArchive
Performs clean up operations on archive object.
ARGS:
NONE.
RETURNS:
PRE-CONDS:
POST-CONDS:
- The icb table is freed.
- mode = Closed.
ERRORS:
This clears out any errors.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::closeArchive()
{
---------------------------------------------------------------------
METHOD: Archive::getVolumeInfo
Return volume information to the archive user.
ARGS:
sid_t sid, IN surface id of volume
UINT16 *nvols OUT # volumes. > 0 if is or has been root.
char *vsname OUT volume set name (132 bytes)
char *vname OUT volume name (32 bytes)
UINT16 *vid OUT ordinal volume number - 0,1,2,...
ExtentList *unerased OUT unerased space information
ExtentList *erased OUT erased space information
UINT32 *dataStart OUT where file data starts (end of fsd seq + 1)
RETURNS:
Returns True if volume has a UDF label; otherwise, returns False.
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
This temporarily changes the mediaType and sectorSize states of
the Archive object, but then changes them back to what they were.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getVolumeInfo( sid_t sid,
UINT16 *nvols,
char *vsname,
char *vname,
UINT16 *vid,
ExtentList *unerasedSpace,
ExtentList *erasedSpace,
UINT32 *dataStart )
{
---------------------------------------------------------------------
METHOD: Archive::addLabeledVolume
Adds a volume to the Archive if, after checking its blockSize
and mediaType, as well as its vsname and its volume number, it
finds that it fits in the open VolumeSet.
Its mediaType, sectorSize, and volume set name must exactly
match that of the current volume set, and the volume number must
be less than or equal to the maxNumLabeledVols parameter
supplied in the openArchive() method.
ARGS:
sid IN surface identifier
RETURNS:
void
PRE-CONDS:
POST-CONDS:
ERRORS:
This clears out any existent error before doing anything.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addLabeledVolume( sid_t sid )
{
---------------------------------------------------------------------
METHOD: Archive::isCompleteVolSet --DVM
This returns True if all labeled volumes in the set have been
added. This means that there are no missing volumes (i.e., all
volumes up through the highest-numbered volume have been added),
and that the current highest-numbered volume is a valid root.
ARGS:
NONE.
RETURNS:
See above.
PRE-CONDS:
openArchive() must have been called.
POST-CONDS:
May set the error state.
ERRORS:
error_Empty_volume_set - Not complete if empty
error_Not_root_volume - Highest-numbered vol is not a root
error_Missing_volume - Holes in set.
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::isCompleteVolSet( void )
{
---------------------------------------------------------------------
METHOD: Archive::getVolSetInfo --AP
This returns a summary of the information currently held by the
archive object about the current volume set.
Note that if the isComplete field is False, the rest of the
structure is simply zeroed out. Thus:
Always filled in appropriately:
expectedVols
sectorSize
mediaType
volSetName
volList
isComplete
Zeroed if volume set incomplete:
rootSid
integrityType
writeProtectType
fileSetList
ARGS:
VolumeSetInfo *vsip OUT all info about volume set
RETURNS: void
PRE-CONDS:
NONE
POST-CONDS:
Error may be set, based upon whether or not a valid root volume
exists. It should return the same errors as isCompleteVolSet().
ERRORS:
error_
NOTES:
volInfoList will be fill in only for those volumes which have been
added to the Archive. Thus, volInfoList.entries() returns how many
volumes have been added so far.
----------------------------------------------------------------------
void
NSR::Archive::getVolSetInfo( VolumeSetInfo *vsip )
{
---------------------------------------------------------------------
METHOD: Archive::getRootVolume --DVM
Returns sid of root volume in Volume Set.
ARGS:
NONE.
RETURNS:
The Surface ID of the root volume in the volume table. If an error
occurs, it returns zero, and sets the Archive object's error.
PRE-CONDS: A complete volume set must be loaded.
POST-CONDS: The error may be set.
ERRORS:
NOTES:
getRootVolume() now is only informational, and need not be called
during each export (or import).
The root volume is BY DEFINITION the volume in the set with the
largest vid or volume number. This method may be used on import,
labeling, and/or export and simply returns the sid for that
volume.
----------------------------------------------------------------------
NSR::sid_t
NSR::Archive::getRootVolume( void )
{
---------------------------------------------------------------------
METHOD: Archive::checkOpenIntegrity --DVM
This is returns True if the currently-loaded volume set is OPEN.
This may be used with a partially-loaded volume set (i.e., with
only the root volume loaded. To do this, use the REAL volume set
size for the maxLabeledVols argument in openArchive(), and then
load it.
ARGS: none.
RETURNS:
True if OPEN, False if CLOSED.
PRE-CONDS:
The root volume must be loaded.
POST-CONDS:
This sets an error if the highest-numbered volume is not a root
volume.
ERRORS:
error_Not_root_volume (returns False)
NOTES:
This simply returns the value in the volumeTable for the root
volume.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::checkOpenIntegrity( void )
{
---------------------------------------------------------------------
METHOD: Archive::destroyFileSet --DVM
Overwrites the FileSetDescriptor.
This wipes out the file set descriptor on the supplied root volume
sid. It is used on rewritable when metadata space is re-used, in
addition to marking a logical volume open.
This is called in addition to markOpenIntegrity() on Rewritable.
ARGS:
NONE
RETURNS:
NONE.
PRE-CONDS:
- The volume set is complete.
- markOpenIntegrity() has been called.
- The Media type is NOT Worm.
- The Logical Volume must NOT be write protected (soft OR hard).
- The number of file sets found must exactly equal one.
POST-CONDS:
ERRORS:
error_
NOTES:
This should be called after markOpenIntegrity() on rewritable
media. It overwrites the FSD with a TD, so that all knowledge of a
fileset is destroyed on the supplied volume.
Note that it, like markOpenIntegrity(), requires that the archive
object be open, with a complete volume set.
This returns an error if the media is WORM, and if there is no
file set descriptor?.
----------------------------------------------------------------------
void
NSR::Archive::destroyFileSet( void )
{
---------------------------------------------------------------------
METHOD: Archive::destroyVolumeLabel --DVM
Nukes NSR information from supplied surface.
This overwrites the AVDPs on the supplied surface, if any
exist. This essentially makes the disk non-NSR, removing enough
information that it is no longer recognizable by
getVolumeInfo().
ARGS:
sid IN surface identifier
RETURNS:
NONE
PRE-CONDS:
The archive object must be OPEN, and no exports or imports may be
in process. Also, the media must not be WORM.
POST-CONDS:
Volume can now only be added to a volume set via
addUnlabeledVolume().
ERRORS:
error_Invalid_function
error_Wrong_media_type
error_Wrong_sector_size
error_Invalid_function_for_media
NOTES:
This overwrites the AVDPs on the supplied surface, if any
exist. This essentially makes the disk non-NSR.
This returns an error if the media is WORM.
This must be used with extreme care, in order to prevent
destroying existing volumeSets. Also note that this is required
since the addUnlabeledVolume() function requires that a disk be
non-NSR if it is to label it.
----------------------------------------------------------------------
void
NSR::Archive::destroyVolumeLabel ( sid_t sid )
{
---------------------------------------------------------------------
METHOD: Archive::getWriteProtect --DVM
Returns the write protect status from the current volume.
ARGS: none.
RETURNS:
Write protect status of current LogicalVolume. Returns Hard
protect if there are any errors. Thus, should case on error if
this is the case.
PRE-CONDS: archive must be open.
POST-CONDS: error state may be set.
ERRORS:
error_Not_root_volume - either unlabelled or non-root volume.
error_Volume_set_not_supported - Can't handle non-HP??
NOTES:
Note that this will only work on the currently loaded volume set.
HOWEVER, this may be called on an incomplete volume set.
----------------------------------------------------------------------
NSR::WriteProtectType
NSR::Archive::getWriteProtect(void)
{
---------------------------------------------------------------------
METHOD: Archive::setWriteProtect --DVM
This sets the LogicalVolume's write protect to the supplied value.
setWriteProtect() enforces the limitations OSTA places on
hardWriteProtect never being altered, returning an appropriate
error if requests cannot be satisfied.
ARGS:
wp IN desired write protect status
RETURNS:
NONE.
PRE-CONDS: archive object must be open.
POST-CONDS: error state may be set.
ERRORS:
error_
error_
error_
NOTES:
Note that this operates upon the current volume set, which must
have its root volume loaded. It may or may not work unless all
volumes are loaded into the volume set.
----------------------------------------------------------------------
void
NSR::Archive::setWriteProtect( WriteProtectType wp )
{
---------------------------------------------------------------------
METHOD: Archive::beginGrow --DVM
This initiates the volume set growth process.
Complete VolSets and empty VolSets may be grown, by adding
unlabeled volumes to them. This must be called beforehand. See
completeGrow() also.
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
A complete volume set must be loaded, and the Archive object must
not be importing or exporting. The current volume set may be
either open or closed, as completeGrow() will propagate that state
onto the grown volume set. See markOpenIntegrity() and
checkOpenIntegrity().
POST-CONDITIONS:
The volume table is cleaned out of any empty entries and the
volume set is in groth mode, or an error state may be set.
ERRORS:
error_
error_
error_
NOTES:
This holds the current root information, so that the copying of
the fileset information may be performed by completeGrow().
----------------------------------------------------------------------
void
NSR::Archive::beginGrow( void )
{
---------------------------------------------------------------------
METHOD: Archive::addUnlabeledVolume
Labels a volume and adds it to the volume set.
Labels the supplied volume with the supplied name, and adds it
to the current volume set. The next available vid is assigned to
it, as is the current volume set name. Note that it must have
the same sectorSize and media type as the current volume set in
order to be added. Thus, it grows the volume set by one volume.
The volume name must be unique within the volume set, so if it
is not unique, an error will be returned.
The label contains free space information also, so the initial
free space must be supplied to this method as well. Note that
the free space information is resupplied to the Archive object
on every export, but also note that this is the free space
information which will be returned on getVolumeInfo() and
getVolSetInfo() until an export is performed.
The limit for how many sectors may be used by the label
information at the beginning of media must also be
supplied. The labeling process itself will not necessarily use
all of the available space, but rather round this limit down to
where the difference between it and 257 is a multiple of
four. This number must be greater than or equal to 297, or an
error will be returned.
For example:
labelLimit = 296 => ERROR
labelLimit = 297 => used = 297
labelLimit = 298 => used = 297
labelLimit = 299 => used = 297
labelLimit = 300 => used = 297
labelLimit = 301 => used = 301
ARGS:
sid_t sid IN surface identifier
char *volName IN volume name
UINT32 labelLimit IN Maximum number of sectors allowed
for label information at beginning
of media.
ExtentList unerasedSpace IN Free space after numLabeledSectors
ExtentList erasedSpace IN Free space after numLabeledSectors
RETURNS:
void
PRE-CONDS:
beginGrow() must have been called before this is called.
POST-CONDS:
The volume set is grown by one, but the root information has not
yet been copied to it.
ERRORS:
Any of several device errors may be set, plus the following:
error_Invalid_function
error_Wrong_media_type
error_Wrong_sector_size
error_Volume_already_labeled
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addUnlabeledVolume ( sid_t sid,
const char *volName,
UINT32 labelLimit,
const ExtentList & unerasedSpace,
const ExtentList & erasedSpace )
{
---------------------------------------------------------------------
METHOD: Archive::completeGrow --DVM
This completes the volume set growth process.
This writes root volume information on the current
highest-numbered volume, including copying any fileset history
from the prior root to the new root. This must be called before
performing import or export, once beginGrow() has been
called. The grown volume set is marked the same as the volume set
was marked during beginGrow().
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
beginGrow() must have been called.
POST-CONDITIONS:
The Volume Set how has a valid root volume, although its integrity
is still OPEN.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::completeGrow( void )
{
---------------------------------------------------------------------
METHOD: Archive::overflowSectors(noExtents)
Calculates the number of sectors required in addition to a file
ICB in order to record all its extents, or its path information.
Called during export to determine the number of overflow sectors
required when writing an FE. It is a f(number of extents) used in
storing the file data. The alternate form is an f(pathlist) used
in storing a symbolic link.
ARGS:
UINT32 noExtents IN The number of extents associated with
this file.
PathElementList pList IN The path for the symbolic link.
RETURNS:
The number of additional sectors required for the file/symlink.
PRE-CONDS:
POST-CONDS:
ERRORS:
error_Invalid_function
error_No_free_store
NOTES:
----------------------------------------------------------------------
NSR::UINT32
NSR::Archive::overflowSectors(UINT32 noExtents)
{
NSR::UINT32
NSR::Archive::overflowSectors( const PathElementList &pList )
{
---------------------------------------------------------------------
METHOD: Archive::sizeICBTable
ARGS:
UINT32 nDirs IN number of directories, including root
UINT32 nFiles IN number of files
UINT32 ovf IN number of overflow sectors
RETURNS:
number of sectors required to write the icb's (fileEntries).
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
Used during export.
Calculations are valid, regardless of mode.
ISSUE: should figure in some amount for the icb table ea in the
root ICB. It is a non-embedded EA, so for now, assume it is
2 sectors. That gives 1 sector for the EAFE and 1 sector for
the EA. Worst case for 512 byte media:
512
- 24 ea header
- 48 impl use ea fields
====
440 bytes for icb table
Each extent (long_ad) is 16 bytes, so there is room for
440/16 = 27 extents. This should be enough.
----------------------------------------------------------------------
NSR::UINT32
NSR::Archive::sizeICBTable( UINT32 nDirs, UINT32 nFiles, UINT32 nOvfl )
{
---------------------------------------------------------------------
METHOD: Archive::sizeDirectory
Calculated sectors required to write a directory.
ARGS:
UINT32 nentries, IN number of files and dirs in this directory
UINT32 sum_name_len IN sum of strlen() over all entries
RETURNS:
number of sectors required to write the directory
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES: export
----------------------------------------------------------------------
NSR::UINT32
NSR::Archive::sizeDirectory( UINT32 nEntries, UINT32 sumNameLen )
{
---------------------------------------------------------------------
METHOD: Archive::setAvailSpace --DVM
Supplies partition parameters to the Archive object (for Export)
This must be called for all volumes in the set, before
allocateICBTable() are called. may be called immediately after a
labeled or unlabeled volume is added, if desired.
ARGS:
sid IN Surface Identifier
unerased IN list of unerased space (after labelLimit)
erased IN list of erased space (after labelLimit)
RETURNS:
PRE-CONDS: (E.g., assumes)
List_preconds
POST-CONDS: (E.g., changes to class data members)
List_postconds
ERRORS:
error_
error_
error_
NOTES:
The PDs/USEs are not written until each volume is visited later in
the export process. This is because the USEs cannot be written
until after space used by NSR has been removed first.
----------------------------------------------------------------------
void
NSR::Archive::setAvailSpace ( sid_t sid,
ExtentList &unerased,
ExtentList &erased )
{
---------------------------------------------------------------------
METHOD: Archive::allocateSeqSectors
Allocates extents to be used during the export process for
extending sequences into the partition space.
This may be used for extending the USE sequence or the file set
descriptor sequence. Space is allocated here and used later, as
needed, when writing the USE or FSD sequence.
ARGS:
RETURNS:
The total amount of free space left on all the volumes.
PRE-CONDS:
POST-CONDS:
ERRORS:
error_End_of_Sequence_space
NOTES: export
----------------------------------------------------------------------
NSR::UINT32
NSR::Archive::allocateSeqSectors()
{
---------------------------------------------------------------------
METHOD: Archive::allocateICBTable
Allocate space from the volume for use in writing the icb information.
ARGS:
UINT32 nodirs IN number of directories to export (incl root)
UINT32 files IN number of files to export
UINT32 ovf IN number of overflow sectors calculated
RETURNS: none.
PRE-CONDS:
POST-CONDS: error may be set.
ERRORS:
NOTES:
Also allocates space for use in writing an "icb extent" table.
If there is any netware information associated with the root
icb, space for it is also calculated.
Allocates space for the ICB table. The total amount of space
equals the number directories + files + overflow sectors + one
for each extent allocated for the ICB table. For WORM, a
verification is done on the extents allocated to ensure that the
icb's will be located properly.
----------------------------------------------------------------------
void
NSR::Archive::allocateICBTable( UINT32 nodirs, UINT32 files, UINT32 ovf)
{
---------------------------------------------------------------------
METHOD: Archive::beginExport --DVM
This begins the export process, naming the fileset.
ARGS:
fsname IN File Set Name
RETURNS:
NONE.
PRE-CONDS:
- A complete volume set must be loaded.
- The Logical Volume must not be write-protected (soft OR hard).
- markOpenIntegrity() must have been called.
- setAvailSpace() must have been called for all vols with space.
- WORM - All file sets are hard write-protected.
- else - No file sets exist.
POST-CONDS:
Either the operation is successful, placing the Archive object
into export mode, or an error state will be set.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::beginExport( const char *fsname )
{
---------------------------------------------------------------------
METHOD: Archive::createDirectory
Creates a directory.
Creates the subdirectory specified by dname for the current
directory. The entry for the subdirectory must already exist by
using addDirectory(). Also, the current directory must already
have been written to disk.
If no current Directory exists, and no value is given for dname,
the root directory is created.
ARGS:
char *dname IN The name of the directory.
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: newly created directory.
directoryStack: | currentDirectory (prev) |<-- top of stack
|---------------------------|
| currentDirectory (prev-1) |<-- top of stack - 1
ERRORS:
error_Directory_not_found: Directory to be created not found in
currentDirectory.
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::createDirectory( char *dname )
{
---------------------------------------------------------------------
METHOD: Archive::addDirEntry
Add a file or subdirectory to the contents of currentDirectory.
ARGS:
Boolean isSubDir IN Whether is a subdirectory or a file.
char *name IN name of file or subdirectory
UINT32 ovf IN overflow sectors for file or subdirectory
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_Name_not_unique
NOTES:
Overflow sectors are normally only for files, but if
extendedAttributes are attached to a directory, ovfl will be
non-zero.
----------------------------------------------------------------------
void
NSR::Archive::addDirEntry( Boolean isSubDir, char *name, UINT32 ovf )
{
---------------------------------------------------------------------
METHOD: Archive::writeDirectory
Write currentDirectory to disk.
Dumps info about current directory, the sets current directory to
parent.
ARGS:
Extent *ext OUT Location where currentDirectory was written.
Used in writing the ICB.
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: marked clean
ERRORS:
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::writeDirectory( Extent *ext )
{
---------------------------------------------------------------------
METHOD: Archive::closeDirectory
User is done with this directory. Pop the directory stack.
ARGS:
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: directoryStack.pop();
directoryStack: | currentDirectory (prev-1) |<-- top of stack
|---------------------------|
| currentDirectory (prev-2) |<-- top of stack - 1
ERRORS:
error_Directory_dirty
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::closeDirectory()
{
---------------------------------------------------------------------
METHOD: Archive::writeRootICB
Write the ICB for the root directory.
This will also write the ICB table - the list of extents used
in writing the meta-data information for this volume set. This
set of locations is later read during import of the volume set.
Writes the ICB for the root directory at the first
location on the ICB table. It then sets the ICB pointer
to the next ICB.
ARGS:
Attributes rootAttr IN Attributes for the root directory.
Extent rootExt IN Where the root directory is located.
RETURNS: none.
PRE-CONDS:
POST-CONDS:
icbTable is bumped by 1 + #sectors used in writing the EA for the
Root ICB.
ERRORS:
error_Invalid_function
error_No_free_store
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::writeRootICB( Attributes &rootAttr,
const Extent &rootExt )
{
---------------------------------------------------------------------
METHOD: Archive::writeNextICB
Write a non-root ICB.
Verifies that the file id matches next ICB to be written. Writes
the next ICB and any required overflow sectors at the ICB pointer
location on the ICB table. It then increments the ICB pointer to
the next available ICB.
ARGS:
Attributes &attr IN Attributes for this file or dir.
const ExtentList &extList IN Locations of file data or directory.
PathElementList pList IN The symbolic link information.
Extent EAICBAddr IN Location of ICB for EAs associated
with file or directory.
RETURNS:
PRE-CONDS:
POST-CONDS:
The icb table address is bumped the appropriate amount.
endICBTable: may be set.
ERRORS:
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::writeNextICB( Attributes &attr,
const ExtentList &extList )
{
void
NSR::Archive::writeNextICB( Attributes attr,
PathElementList pList )
{
void
NSR::Archive::writeNextICB( Attributes &attr,
const ExtentList &extList,
const Extent &EAICBAddr )
{
void
NSR::Archive::writeNextICB( const Attributes &attr,
const PathElementList &pList,
const Extent &EAICBAddr )
{
---------------------------------------------------------------------
METHOD: Archive::completeExport
Performs all actions appropriate for end of export.
Writes nsr volume information on all volumes. Writes a closed
integrity entry.
ARGS: none.
RETURNS: none.
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
Updates each volume still marked dirty with space
information. Then, writes FSD, LVID on root, and closes the
logical volume.
----------------------------------------------------------------------
void
NSR::Archive::completeExport()
{
---------------------------------------------------------------------
METHOD: Archive::getImplementInfo --DVM
This reads the ImplementationRegID from the root ICB, and returns
that information, so that the user may know for sure which user of
this code wrote the file set.
If fsNum is not supplied, the default file set information is
provided.
ARGS:
fsNum IN Which file set being checked.
implementationInfo OUT Information about implementation
RETURNS:
void
PRE-CONDS:
Must have a complete volume set
POST-CONDS:
NONE
ERRORS:
error_Invalid_function - not in proper mode.
various device errors are possible as well.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::getImplementInfo( ImplementationInfo * implInfo )
void
NSR::Archive::getImplementInfo( INT32 fsnum, ImplementationInfo * implInfo )
{
---------------------------------------------------------------------
METHOD: Archive::beginImport
Begin the import process.
ARGS:
UINT16 fsnum IN Import this file set number. If this is
not supplied, the last fileSet found
will be imported. Note that File sets
are numbered 0,1,2,...
ExtentList *icbSpace OUT The space occupied by the fileset's
ICBs. This may be spread over many
volumes. This is made available, so
that in the case of Rewritable, this
space may be reclaimed. This does NOT
include extents used in writing the
directories.
RETURNS: none
PRE-CONDS: A valid complete volume set is loaded.
POST-CONDS: The error state may be set.
ERRORS:
error_
NOTES: import
----------------------------------------------------------------------
void
NSR::Archive::beginImport( ExtentList *icbSpace )
{
void
NSR::Archive::beginImport( INT32 fsnum )
{
void
NSR::Archive::beginImport( void )
---------------------------------------------------------------------
METHOD: Archive::readRootICB
Read the root ICB.
This must be the first ICB read, as the icb table is located here.
ARGS:
Attributes *rootDirAttr OUT Attributes for root directory.
Extent *rootDirExt OUT Location of root directory.
ImplementationInfo *implInfo OUT Implementation Information.
ExtentList *EAExtList OUT Locations holding EAs.
RETURNS:
PRE-CONDS:
rootICB must be set to the location of the root ICB. This is done in
beginImport().
POST-CONDS:
Sets the ICB pointer to the next ICB.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::readRootICB( Attributes *rootDirAttr,
Extent *rootDirExt )
{
---------------------------------------------------------------------
METHOD: Archive::readNextICB
Read the next ICB.
Reads the next ICB from the ICB table. Also increments the
ICB pointer to the next ICB.
If extList returns NULL, the next ICB was not on the current
volume. The next volume is then specified by addr.
ARGS:
Attributes *attr OUT Attributes for next directory.
ExtentList *extList OUT Location of next directory.
Extent *EAICBAddr OUT Location of ICB for EAs.
RETURNS:
-1 The end of the ICB table has been reached.
0 The end of the ICB table has not been reached.
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
int
NSR::Archive::readNextICB( Address *addr,
Attributes *attr,
ExtentList *extList )
{
int
NSR::Archive::readNextICB( Address *addr,
Attributes *attr,
ExtentList *extList,
Extent *EAICBAddr )
{
---------------------------------------------------------------------
METHOD: Archive::endOfICBTable --AP
Returns True if at end of ICB Table.
ARGS:
NONE
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::endOfICBTable()
{
---------------------------------------------------------------------
METHOD: Archive::readPath
Read the path information for a symbolic link.
ARGS:
ExtentList &elist, IN Locations for path information
PathElementList *pList OUT The path information.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readPath( ExtentList &elist,
PathElementList *pList )
{
---------------------------------------------------------------------
METHOD: Archive::locateDirectory
Attempts to find the specified directory on the current volume in
the device.
If found, sets the current directory to that specified
ARGS:
Extent ext IN Location of the directory.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
Locates a directory and populates currentDirectory with its
contents.
----------------------------------------------------------------------
void
NSR::Archive::locateDirectory( Extent ext )
{
---------------------------------------------------------------------
METHOD: Archive::numDirEntries --AP
Returns the number of entries in the current directory.
ARGS:
NONE
RETURNS:
See above.
PRE-CONDS:
Assumes that a directory has been properly found using
locateDirectory().
POST-CONDS:
NONE.
ERRORS:
error_
error_
NOTES:
----------------------------------------------------------------------
NSR::UINT32
NSR::Archive::numDirEntries()
{
---------------------------------------------------------------------
METHOD: Archive::getFirstDirEntry
Reads the first entry in the current directory. Sets the entry
pointer to the next directory entry.
ARGS:
Boolean *dir OUT Entry is a subdirectory
char *name OUT name of the dir entry.
Address *addr OUT ICB addr of the entry.
RETURNS:
void
PRE-CONDS:
Assumes that a directory has been properly found using
locateDirectory().
POST-CONDS:
Pointer set to second entry, ready for getNextDirEntry().
ERRORS:
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::getFirstDirEntry( Boolean *dir,
char *name,
Address *addr )
{
---------------------------------------------------------------------
METHOD: Archive::getNextDirEntry
Reads the next entry in the current directory. Sets the entry
pointer to the next directory entry.
ARGS:
Boolean *dir OUT Entry is a subdirectory
char *name OUT name of the dir entry.
Address *addr OUT ICB addr of the entry.
RETURNS:
The return value should probably be ignored. Look instead at the
error() return value after calling this.
PRE-CONDS:
Assumes that a directory has been properly found using
locateDirectory().
POST-CONDS:
Pointer set to next entry.
ERRORS:
error_
error_
NOTES:
----------------------------------------------------------------------
int
NSR::Archive::getNextDirEntry( Boolean *dir,
char *name,
Address *addr )
{
---------------------------------------------------------------------
METHOD: Archive::getDirEntry
Reads the specified entry in the current directory. Sets the entry
pointer to the next directory entry.
ARGS:
Boolean *dir OUT Entry is a subdirectory
char *name OUT name of the dir entry.
Address *addr OUT ICB addr of the entry.
RETURNS:
void
PRE-CONDS:
Assumes that a directory has been properly found using
locateDirectory().
POST-CONDS:
Pointer set to next entry.???
ERRORS:
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::getDirEntry( unsigned i,
Boolean *dir,
char *name,
Address *addr )
{
---------------------------------------------------------------------
METHOD: Archive::endOfDirectory -- AP
Returns True if all entries in the current directory are
exhausted.
ARGS:
RETURNS:
See above.
PRE-CONDS:
Assumes that a directory has been properly found using
locateDirectory().
POST-CONDS:
NONE.
ERRORS:
error_
error_
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::endOfDirectory()
{
---------------------------------------------------------------------
METHOD: Archive::completeImport
Cleans up the state of the archive object.
ARGS:
NONE.
RETURNS:
void
PRE-CONDS:
NONE.
POST-CONDS:
The archive object is left ready to grow a volume group, export,
or import.
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::completeImport()
{
---------------------------------------------------------------------
METHOD: Archive::logFile --DVM
Sets the file to send logging output to.
ARGS:
FILE * lf IN File pointer.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Any logging will go to the supplied file.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getVolumeInfo() Unerased Space :\n");
unerasedSpace->fprint(Trace::logFile());
fprintf(Trace::logFile(),"getVolumeInfo() Erased Space :\n");
erasedSpace->fprint(Trace::logFile());
}
Now determine dataStart
if (dataStart) {
Calculate from USEs whether root or not.
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
*dataStart = partAreas.fileDataStart();
}
Restore prior values.
media = savedMT ;
logicalSectorSize = savedLSS;
logicalBlockSize = savedLBS;
return True;
}
----------------------------------------------------------------------
METHOD: Archive::addLabeledVolume
Adds a volume to the Archive if, after checking its blockSize
and mediaType, as well as its vsname and its volume number, it
finds that it fits in the open VolumeSet.
Its mediaType, sectorSize, and volume set name must exactly
match that of the current volume set, and the volume number must
be less than or equal to the maxNumLabeledVols parameter
supplied in the openArchive() method.
ARGS:
sid IN surface identifier
RETURNS:
void
PRE-CONDS:
POST-CONDS:
ERRORS:
This clears out any existent error before doing anything.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addLabeledVolume( sid_t sid )
fprintf(Trace::logFile(),"getVolumeInfo() Unerased Space :\n");
unerasedSpace->fprint(Trace::logFile());
fprintf(Trace::logFile(),"getVolumeInfo() Erased Space :\n");
erasedSpace->fprint(Trace::logFile());
}
Now determine dataStart
if (dataStart) {
Calculate from USEs whether root or not.
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
*dataStart = partAreas.fileDataStart();
}
Restore prior values.
media = savedMT ;
logicalSectorSize = savedLSS;
logicalBlockSize = savedLBS;
return True;
}
----------------------------------------------------------------------
METHOD: Archive::addLabeledVolume
Adds a volume to the Archive if, after checking its blockSize
and mediaType, as well as its vsname and its volume number, it
finds that it fits in the open VolumeSet.
Its mediaType, sectorSize, and volume set name must exactly
match that of the current volume set, and the volume number must
be less than or equal to the maxNumLabeledVols parameter
supplied in the openArchive() method.
ARGS:
sid IN surface identifier
RETURNS:
void
PRE-CONDS:
POST-CONDS:
ERRORS:
This clears out any existent error before doing anything.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addLabeledVolume( sid_t sid )
unerasedSpace->fprint(Trace::logFile());
fprintf(Trace::logFile(),"getVolumeInfo() Erased Space :\n");
erasedSpace->fprint(Trace::logFile());
}
Now determine dataStart
if (dataStart) {
Calculate from USEs whether root or not.
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
*dataStart = partAreas.fileDataStart();
}
Restore prior values.
media = savedMT ;
logicalSectorSize = savedLSS;
logicalBlockSize = savedLBS;
return True;
}
----------------------------------------------------------------------
METHOD: Archive::addLabeledVolume
Adds a volume to the Archive if, after checking its blockSize
and mediaType, as well as its vsname and its volume number, it
finds that it fits in the open VolumeSet.
Its mediaType, sectorSize, and volume set name must exactly
match that of the current volume set, and the volume number must
be less than or equal to the maxNumLabeledVols parameter
supplied in the openArchive() method.
ARGS:
sid IN surface identifier
RETURNS:
void
PRE-CONDS:
POST-CONDS:
ERRORS:
This clears out any existent error before doing anything.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addLabeledVolume( sid_t sid )
fprintf(Trace::logFile(),"getVolumeInfo() Erased Space :\n");
erasedSpace->fprint(Trace::logFile());
}
Now determine dataStart
if (dataStart) {
Calculate from USEs whether root or not.
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
*dataStart = partAreas.fileDataStart();
}
Restore prior values.
media = savedMT ;
logicalSectorSize = savedLSS;
logicalBlockSize = savedLBS;
return True;
}
----------------------------------------------------------------------
METHOD: Archive::addLabeledVolume
Adds a volume to the Archive if, after checking its blockSize
and mediaType, as well as its vsname and its volume number, it
finds that it fits in the open VolumeSet.
Its mediaType, sectorSize, and volume set name must exactly
match that of the current volume set, and the volume number must
be less than or equal to the maxNumLabeledVols parameter
supplied in the openArchive() method.
ARGS:
sid IN surface identifier
RETURNS:
void
PRE-CONDS:
POST-CONDS:
ERRORS:
This clears out any existent error before doing anything.
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::addLabeledVolume( sid_t sid )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"addLabeledVol() Unerased Space :\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addLabeledVol() Erased Space :\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Now determine dataStart
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
vol.fileDataStart = partAreas.fileDataStart();
If it has an LVID Sequence, read it in.
if ( vol.lvNumVols != 0 ) {
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
Read the LVID sequence.
readLVIDSeq( vol, &lvid, &nFileSets );
if (err) {
delete lvid;
return;
}
Fill in volume fields.
vol.lvIntegrity = lvid->integrityType();
vol.lvIntegImplementID = lvid->implementID.id();
delete lvid;
}
Add the volume into the table.
volumeTable[vol.vid] = vol;
if ( err = volumeTable.error() ) {
return;
}
} else {
if (hasAVD) {
if (!err) {
volume not written by hp.
err = error_Wrong_volume_set;
}
return;
} else {
err = error_Volume_not_labeled; Use addUnlabeledVolume()
}
}
}
----------------------------------------------------------------------
METHOD: Archive::isCompleteVolSet --DVM
This returns True if all labeled volumes in the set have been
added. This means that there are no missing volumes (i.e., all
volumes up through the highest-numbered volume have been added),
and that the current highest-numbered volume is a valid root.
ARGS:
NONE.
RETURNS:
See above.
PRE-CONDS:
openArchive() must have been called.
POST-CONDS:
May set the error state.
ERRORS:
error_Empty_volume_set - Not complete if empty
error_Not_root_volume - Highest-numbered vol is not a root
error_Missing_volume - Holes in set.
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::isCompleteVolSet( void )
fprintf(Trace::logFile(),"addLabeledVol() Unerased Space :\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addLabeledVol() Erased Space :\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Now determine dataStart
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
vol.fileDataStart = partAreas.fileDataStart();
If it has an LVID Sequence, read it in.
if ( vol.lvNumVols != 0 ) {
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
Read the LVID sequence.
readLVIDSeq( vol, &lvid, &nFileSets );
if (err) {
delete lvid;
return;
}
Fill in volume fields.
vol.lvIntegrity = lvid->integrityType();
vol.lvIntegImplementID = lvid->implementID.id();
delete lvid;
}
Add the volume into the table.
volumeTable[vol.vid] = vol;
if ( err = volumeTable.error() ) {
return;
}
} else {
if (hasAVD) {
if (!err) {
volume not written by hp.
err = error_Wrong_volume_set;
}
return;
} else {
err = error_Volume_not_labeled; Use addUnlabeledVolume()
}
}
}
----------------------------------------------------------------------
METHOD: Archive::isCompleteVolSet --DVM
This returns True if all labeled volumes in the set have been
added. This means that there are no missing volumes (i.e., all
volumes up through the highest-numbered volume have been added),
and that the current highest-numbered volume is a valid root.
ARGS:
NONE.
RETURNS:
See above.
PRE-CONDS:
openArchive() must have been called.
POST-CONDS:
May set the error state.
ERRORS:
error_Empty_volume_set - Not complete if empty
error_Not_root_volume - Highest-numbered vol is not a root
error_Missing_volume - Holes in set.
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::isCompleteVolSet( void )
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addLabeledVol() Erased Space :\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Now determine dataStart
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
vol.fileDataStart = partAreas.fileDataStart();
If it has an LVID Sequence, read it in.
if ( vol.lvNumVols != 0 ) {
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
Read the LVID sequence.
readLVIDSeq( vol, &lvid, &nFileSets );
if (err) {
delete lvid;
return;
}
Fill in volume fields.
vol.lvIntegrity = lvid->integrityType();
vol.lvIntegImplementID = lvid->implementID.id();
delete lvid;
}
Add the volume into the table.
volumeTable[vol.vid] = vol;
if ( err = volumeTable.error() ) {
return;
}
} else {
if (hasAVD) {
if (!err) {
volume not written by hp.
err = error_Wrong_volume_set;
}
return;
} else {
err = error_Volume_not_labeled; Use addUnlabeledVolume()
}
}
}
----------------------------------------------------------------------
METHOD: Archive::isCompleteVolSet --DVM
This returns True if all labeled volumes in the set have been
added. This means that there are no missing volumes (i.e., all
volumes up through the highest-numbered volume have been added),
and that the current highest-numbered volume is a valid root.
ARGS:
NONE.
RETURNS:
See above.
PRE-CONDS:
openArchive() must have been called.
POST-CONDS:
May set the error state.
ERRORS:
error_Empty_volume_set - Not complete if empty
error_Not_root_volume - Highest-numbered vol is not a root
error_Missing_volume - Holes in set.
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::isCompleteVolSet( void )
fprintf(Trace::logFile(),"addLabeledVol() Erased Space :\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Now determine dataStart
PartitionAreaCalc partAreas(logicalBlockSize,
media,
uICBAddr,
eICBAddr);
vol.fileDataStart = partAreas.fileDataStart();
If it has an LVID Sequence, read it in.
if ( vol.lvNumVols != 0 ) {
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
Read the LVID sequence.
readLVIDSeq( vol, &lvid, &nFileSets );
if (err) {
delete lvid;
return;
}
Fill in volume fields.
vol.lvIntegrity = lvid->integrityType();
vol.lvIntegImplementID = lvid->implementID.id();
delete lvid;
}
Add the volume into the table.
volumeTable[vol.vid] = vol;
if ( err = volumeTable.error() ) {
return;
}
} else {
if (hasAVD) {
if (!err) {
volume not written by hp.
err = error_Wrong_volume_set;
}
return;
} else {
err = error_Volume_not_labeled; Use addUnlabeledVolume()
}
}
}
----------------------------------------------------------------------
METHOD: Archive::isCompleteVolSet --DVM
This returns True if all labeled volumes in the set have been
added. This means that there are no missing volumes (i.e., all
volumes up through the highest-numbered volume have been added),
and that the current highest-numbered volume is a valid root.
ARGS:
NONE.
RETURNS:
See above.
PRE-CONDS:
openArchive() must have been called.
POST-CONDS:
May set the error state.
ERRORS:
error_Empty_volume_set - Not complete if empty
error_Not_root_volume - Highest-numbered vol is not a root
error_Missing_volume - Holes in set.
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::isCompleteVolSet( void )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"addUnlabeledVol() Unerased Space :\n");
newVolume.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addUnlabeledVol() Erased Space :\n");
newVolume.erasedFreeSpace.fprint(Trace::logFile());
}
Add to volumeTable
volumeTable.append( newVolume );
if (err=volumeTable.error()) {
return;
}
FINALLY, place the label down onto the disk.
writeVolumeLabel( volumeTable.rootVol() );
}
----------------------------------------------------------------------
METHOD: Archive::completeGrow --DVM
This completes the volume set growth process.
This writes root volume information on the current
highest-numbered volume, including copying any fileset history
from the prior root to the new root. This must be called before
performing import or export, once beginGrow() has been
called. The grown volume set is marked the same as the volume set
was marked during beginGrow().
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
beginGrow() must have been called.
POST-CONDITIONS:
The Volume Set how has a valid root volume, although its integrity
is still OPEN.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::completeGrow( void )
fprintf(Trace::logFile(),"addUnlabeledVol() Unerased Space :\n");
newVolume.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addUnlabeledVol() Erased Space :\n");
newVolume.erasedFreeSpace.fprint(Trace::logFile());
}
Add to volumeTable
volumeTable.append( newVolume );
if (err=volumeTable.error()) {
return;
}
FINALLY, place the label down onto the disk.
writeVolumeLabel( volumeTable.rootVol() );
}
----------------------------------------------------------------------
METHOD: Archive::completeGrow --DVM
This completes the volume set growth process.
This writes root volume information on the current
highest-numbered volume, including copying any fileset history
from the prior root to the new root. This must be called before
performing import or export, once beginGrow() has been
called. The grown volume set is marked the same as the volume set
was marked during beginGrow().
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
beginGrow() must have been called.
POST-CONDITIONS:
The Volume Set how has a valid root volume, although its integrity
is still OPEN.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::completeGrow( void )
newVolume.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"addUnlabeledVol() Erased Space :\n");
newVolume.erasedFreeSpace.fprint(Trace::logFile());
}
Add to volumeTable
volumeTable.append( newVolume );
if (err=volumeTable.error()) {
return;
}
FINALLY, place the label down onto the disk.
writeVolumeLabel( volumeTable.rootVol() );
}
----------------------------------------------------------------------
METHOD: Archive::completeGrow --DVM
This completes the volume set growth process.
This writes root volume information on the current
highest-numbered volume, including copying any fileset history
from the prior root to the new root. This must be called before
performing import or export, once beginGrow() has been
called. The grown volume set is marked the same as the volume set
was marked during beginGrow().
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
beginGrow() must have been called.
POST-CONDITIONS:
The Volume Set how has a valid root volume, although its integrity
is still OPEN.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::completeGrow( void )
fprintf(Trace::logFile(),"addUnlabeledVol() Erased Space :\n");
newVolume.erasedFreeSpace.fprint(Trace::logFile());
}
Add to volumeTable
volumeTable.append( newVolume );
if (err=volumeTable.error()) {
return;
}
FINALLY, place the label down onto the disk.
writeVolumeLabel( volumeTable.rootVol() );
}
----------------------------------------------------------------------
METHOD: Archive::completeGrow --DVM
This completes the volume set growth process.
This writes root volume information on the current
highest-numbered volume, including copying any fileset history
from the prior root to the new root. This must be called before
performing import or export, once beginGrow() has been
called. The grown volume set is marked the same as the volume set
was marked during beginGrow().
ARGS: none.
RETURNS: none.
PRE-CONDITIONS:
beginGrow() must have been called.
POST-CONDITIONS:
The Volume Set how has a valid root volume, although its integrity
is still OPEN.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::completeGrow( void )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"completeGrow() Unerased Space :\n");
rootVol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"completeGrow() Erased Space :\n");
rootVol.erasedFreeSpace.fprint(Trace::logFile());
}
New volume sets start out as OPEN.
Otherwise, propagate from previous Root.
if ( preGrowthNumVols == 0 ) {
rootVol.lvIntegrity = integ_Open;
} else {
rootVol.lvIntegrity = preGrowthRootVol.lvIntegrity;
}
writeIntegrityEntry( rootVol );
if (err) { return; }
Change the mode
mode = mode_VolSet;
return;
}
----------------------------------------------------------------------
METHOD: Archive::getVolSetInfo --AP
This returns a summary of the information currently held by the
archive object about the current volume set.
Note that if the isComplete field is False, the rest of the
structure is simply zeroed out. Thus:
Always filled in appropriately:
expectedVols
sectorSize
mediaType
volSetName
volList
isComplete
Zeroed if volume set incomplete:
rootSid
integrityType
writeProtectType
fileSetList
ARGS:
VolumeSetInfo *vsip OUT all info about volume set
RETURNS: void
PRE-CONDS:
NONE
POST-CONDS:
Error may be set, based upon whether or not a valid root volume
exists. It should return the same errors as isCompleteVolSet().
ERRORS:
error_
NOTES:
volInfoList will be fill in only for those volumes which have been
added to the Archive. Thus, volInfoList.entries() returns how many
volumes have been added so far.
----------------------------------------------------------------------
void
NSR::Archive::getVolSetInfo( VolumeSetInfo *vsip )
fprintf(Trace::logFile(),"completeGrow() Unerased Space :\n");
rootVol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"completeGrow() Erased Space :\n");
rootVol.erasedFreeSpace.fprint(Trace::logFile());
}
New volume sets start out as OPEN.
Otherwise, propagate from previous Root.
if ( preGrowthNumVols == 0 ) {
rootVol.lvIntegrity = integ_Open;
} else {
rootVol.lvIntegrity = preGrowthRootVol.lvIntegrity;
}
writeIntegrityEntry( rootVol );
if (err) { return; }
Change the mode
mode = mode_VolSet;
return;
}
----------------------------------------------------------------------
METHOD: Archive::getVolSetInfo --AP
This returns a summary of the information currently held by the
archive object about the current volume set.
Note that if the isComplete field is False, the rest of the
structure is simply zeroed out. Thus:
Always filled in appropriately:
expectedVols
sectorSize
mediaType
volSetName
volList
isComplete
Zeroed if volume set incomplete:
rootSid
integrityType
writeProtectType
fileSetList
ARGS:
VolumeSetInfo *vsip OUT all info about volume set
RETURNS: void
PRE-CONDS:
NONE
POST-CONDS:
Error may be set, based upon whether or not a valid root volume
exists. It should return the same errors as isCompleteVolSet().
ERRORS:
error_
NOTES:
volInfoList will be fill in only for those volumes which have been
added to the Archive. Thus, volInfoList.entries() returns how many
volumes have been added so far.
----------------------------------------------------------------------
void
NSR::Archive::getVolSetInfo( VolumeSetInfo *vsip )
rootVol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"completeGrow() Erased Space :\n");
rootVol.erasedFreeSpace.fprint(Trace::logFile());
}
New volume sets start out as OPEN.
Otherwise, propagate from previous Root.
if ( preGrowthNumVols == 0 ) {
rootVol.lvIntegrity = integ_Open;
} else {
rootVol.lvIntegrity = preGrowthRootVol.lvIntegrity;
}
writeIntegrityEntry( rootVol );
if (err) { return; }
Change the mode
mode = mode_VolSet;
return;
}
----------------------------------------------------------------------
METHOD: Archive::getVolSetInfo --AP
This returns a summary of the information currently held by the
archive object about the current volume set.
Note that if the isComplete field is False, the rest of the
structure is simply zeroed out. Thus:
Always filled in appropriately:
expectedVols
sectorSize
mediaType
volSetName
volList
isComplete
Zeroed if volume set incomplete:
rootSid
integrityType
writeProtectType
fileSetList
ARGS:
VolumeSetInfo *vsip OUT all info about volume set
RETURNS: void
PRE-CONDS:
NONE
POST-CONDS:
Error may be set, based upon whether or not a valid root volume
exists. It should return the same errors as isCompleteVolSet().
ERRORS:
error_
NOTES:
volInfoList will be fill in only for those volumes which have been
added to the Archive. Thus, volInfoList.entries() returns how many
volumes have been added so far.
----------------------------------------------------------------------
void
NSR::Archive::getVolSetInfo( VolumeSetInfo *vsip )
fprintf(Trace::logFile(),"completeGrow() Erased Space :\n");
rootVol.erasedFreeSpace.fprint(Trace::logFile());
}
New volume sets start out as OPEN.
Otherwise, propagate from previous Root.
if ( preGrowthNumVols == 0 ) {
rootVol.lvIntegrity = integ_Open;
} else {
rootVol.lvIntegrity = preGrowthRootVol.lvIntegrity;
}
writeIntegrityEntry( rootVol );
if (err) { return; }
Change the mode
mode = mode_VolSet;
return;
}
----------------------------------------------------------------------
METHOD: Archive::getVolSetInfo --AP
This returns a summary of the information currently held by the
archive object about the current volume set.
Note that if the isComplete field is False, the rest of the
structure is simply zeroed out. Thus:
Always filled in appropriately:
expectedVols
sectorSize
mediaType
volSetName
volList
isComplete
Zeroed if volume set incomplete:
rootSid
integrityType
writeProtectType
fileSetList
ARGS:
VolumeSetInfo *vsip OUT all info about volume set
RETURNS: void
PRE-CONDS:
NONE
POST-CONDS:
Error may be set, based upon whether or not a valid root volume
exists. It should return the same errors as isCompleteVolSet().
ERRORS:
error_
NOTES:
volInfoList will be fill in only for those volumes which have been
added to the Archive. Thus, volInfoList.entries() returns how many
volumes have been added so far.
----------------------------------------------------------------------
void
NSR::Archive::getVolSetInfo( VolumeSetInfo *vsip )
for (i = 0; iverifyBlank(volumeTable[vid].sid(),
e.start.sector, B2S(e.len), &nonBlankSector ) == False) {
verified = False;
}
}
if (verified) {
elist.append( e );
if ( err = elist.error() ) { delete used; return; }
n -= B2S(e.len);
nextents++;
if (figuringEA) {
rootEAExtents++;
if ( rootEAExtents > extentsPerICB ) {
This should really never happen.
err = error_Root_EA_FileEntry_full;
delete used;
return;
}
if (rootEAExtents > maxExtraExtents) {
will need to use additional sectors for ea space
n++;
maxExtraExtents += logicalBlockSize/16;
}
}
}
if ( n <= 0 && !figuringEA) {
---------------------------------------------------
All the space has been allocated and verified.
See if any additional space is needed for the
icb table. The icb table is to be stored as an
extended attribute of the root icb.
---------------------------------------------------
figuringEA = True;
icbtea = new ICBTableEA(nextents+1);
if (!icbtea) { err = error_No_free_store; delete used; return; }
nBytesForEA += icbtea->attrLen();
nBytesForEA += (nBytesForEA % 4) ? 4 - (nBytesForEA % 4) : 0;
delete icbtea;
n += 1; one sector for the EA ICB
n += B2S(nBytesForEA); sectors for the EA
root_ovf = 1 + B2S(nBytesForEA);
maxExtraExtents = 1 + (logicalBlockSize-nBytesForEA)/16; long_ad
}
if ( n > 0 ) {
e = volumeTable[vid].alloc( n, False );
}
}
used[ vid ] = True;
if ( n > 0 ) {
pick next volume
valid_ID = False; totalFree = 0;
for ( i=0; i totalFree ) {
vid = i; totalFree = t; valid_ID = True;
}
}
}
e = volumeTable[vid].alloc( n, False );
}
}
delete [] used;
if (!valid_ID) {
err = error_No_free_space;
return;
}
icbTable = new ICB_Table( elist, logicalBlockSize );
if (!icbTable) {
err = error_No_free_store;
return;
}
endICBTable = False;
vidCurrent = vid;
}
----------------------------------------------------------------------
METHOD: Archive::beginExport --DVM
This begins the export process, naming the fileset.
ARGS:
fsname IN File Set Name
RETURNS:
NONE.
PRE-CONDS:
- A complete volume set must be loaded.
- The Logical Volume must not be write-protected (soft OR hard).
- markOpenIntegrity() must have been called.
- setAvailSpace() must have been called for all vols with space.
- WORM - All file sets are hard write-protected.
- else - No file sets exist.
POST-CONDS:
Either the operation is successful, placing the Archive object
into export mode, or an error state will be set.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::beginExport( const char *fsname )
fprintf(Trace::logFile(),"allocateICBTable(): verifying Extent :");
e.fprint(Trace::logFile());
}
UINT32 nonBlankSector;
if (currentDevice->verifyBlank(volumeTable[vid].sid(),
e.start.sector, B2S(e.len), &nonBlankSector ) == False) {
verified = False;
}
}
if (verified) {
elist.append( e );
if ( err = elist.error() ) { delete used; return; }
n -= B2S(e.len);
nextents++;
if (figuringEA) {
rootEAExtents++;
if ( rootEAExtents > extentsPerICB ) {
This should really never happen.
err = error_Root_EA_FileEntry_full;
delete used;
return;
}
if (rootEAExtents > maxExtraExtents) {
will need to use additional sectors for ea space
n++;
maxExtraExtents += logicalBlockSize/16;
}
}
}
if ( n <= 0 && !figuringEA) {
---------------------------------------------------
All the space has been allocated and verified.
See if any additional space is needed for the
icb table. The icb table is to be stored as an
extended attribute of the root icb.
---------------------------------------------------
figuringEA = True;
icbtea = new ICBTableEA(nextents+1);
if (!icbtea) { err = error_No_free_store; delete used; return; }
nBytesForEA += icbtea->attrLen();
nBytesForEA += (nBytesForEA % 4) ? 4 - (nBytesForEA % 4) : 0;
delete icbtea;
n += 1; one sector for the EA ICB
n += B2S(nBytesForEA); sectors for the EA
root_ovf = 1 + B2S(nBytesForEA);
maxExtraExtents = 1 + (logicalBlockSize-nBytesForEA)/16; long_ad
}
if ( n > 0 ) {
e = volumeTable[vid].alloc( n, False );
}
}
used[ vid ] = True;
if ( n > 0 ) {
pick next volume
valid_ID = False; totalFree = 0;
for ( i=0; i totalFree ) {
vid = i; totalFree = t; valid_ID = True;
}
}
}
e = volumeTable[vid].alloc( n, False );
}
}
delete [] used;
if (!valid_ID) {
err = error_No_free_space;
return;
}
icbTable = new ICB_Table( elist, logicalBlockSize );
if (!icbTable) {
err = error_No_free_store;
return;
}
endICBTable = False;
vidCurrent = vid;
}
----------------------------------------------------------------------
METHOD: Archive::beginExport --DVM
This begins the export process, naming the fileset.
ARGS:
fsname IN File Set Name
RETURNS:
NONE.
PRE-CONDS:
- A complete volume set must be loaded.
- The Logical Volume must not be write-protected (soft OR hard).
- markOpenIntegrity() must have been called.
- setAvailSpace() must have been called for all vols with space.
- WORM - All file sets are hard write-protected.
- else - No file sets exist.
POST-CONDS:
Either the operation is successful, placing the Archive object
into export mode, or an error state will be set.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::beginExport( const char *fsname )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeDirectory(): full volume");
fprintf(Trace::logFile(),"- updating space for volNum[%d]\n",
vidCurrent);
}
updateSpace( volumeTable[vidCurrent] ); Write out free space.
if (err) return;
volumeTable[vidCurrent].markClean();
Boolean valid_ID = True;
UINT32 totalFree, t;
UINT16 vid;
valid_ID = False; totalFree = 0;
for ( i=0; i totalFree ) {
vid = i; totalFree = t; valid_ID = True;
}
}
if ( valid_ID )
vidCurrent = vid;
else
err = error_No_free_space;
return;
}
allocate directory from free space
Boolean verified = False;
while (!verified)
{
*ext = volumeTable[vidCurrent].alloc( nBlocks, True );
ext->len = totalBytes;
if (!(ext->len)) { err = error_No_free_space; return; }
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeDirectory : at sid %3d sector %7d num_sectors %7d\n",
ext->start.sid, ext->start.sector, nBlocks);
}
verified = True;
if (media == media_Worm) {
verified = False;
UINT32 nonBlankSector;
do a verify on this extent to make sure it can be written
if (currentDevice->verifyBlank(volumeTable[vidCurrent].sid(),
ext->start.sector,B2S(ext->len),
&nonBlankSector) == True ) {
verified = True;
}
else {
fprintf(Trace::logFile(),"writeDirectory: WARNING: non-blank sector:%d\n",nonBlankSector);
}
}
}
BYTE *bp = new BYTE[S2B(nBlocks)];
if (!bp) { err = error_No_free_store; return; }
memset( bp, 0, S2B(nBlocks));
UINT32 bytePtr = 0;
for ( i=0; i < currentDirectory.contents.getCount(); i++ )
{
fid = new FileIdentifierDesc( currentDirectory.contents[i].name );
if (!fid) { err = error_No_free_store; delete [] bp; return; }
fid->icbAddr.extType ( ext_Recorded );
fid->icbAddr.logBlockNo ( currentDirectory.contents[i]
.icbAddr.sector - partStartSector );
fid->icbAddr.partRefNo ( volumeTable.vid( currentDirectory
.contents[i].icbAddr.sid ) );
fid->icbAddr.extLength ( logicalBlockSize );
if ( currentDirectory.contents[i].hidden ) fid->markHidden();
if ( currentDirectory.contents[i].dir ) fid->markDir();
if ( i == 0 ) fid->markParent(); parent is always first entry
fid->toISO( bp + bytePtr, ext->start.sector + (bytePtr/logicalBlockSize) - partStartSector );
if (err = fid->error()) { delete fid; delete [] bp; return; }
bytePtr += fid->descLen();
delete fid;
}
for ( i = 0; i < nBlocks; i++ )
{
writeBlock( volumeTable[vidCurrent].sid(), ext->start.sector + i,
bp + (S2B(i)));
}
delete [] bp;
if (err) return;
mark directory as clean
currentDirectory.markClean();
return;
}
----------------------------------------------------------------------
METHOD: Archive::closeDirectory
User is done with this directory. Pop the directory stack.
ARGS:
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: directoryStack.pop();
directoryStack: | currentDirectory (prev-1) |<-- top of stack
|---------------------------|
| currentDirectory (prev-2) |<-- top of stack - 1
ERRORS:
error_Directory_dirty
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::closeDirectory()
fprintf(Trace::logFile(),"writeDirectory(): full volume");
fprintf(Trace::logFile(),"- updating space for volNum[%d]\n",
vidCurrent);
}
updateSpace( volumeTable[vidCurrent] ); Write out free space.
if (err) return;
volumeTable[vidCurrent].markClean();
Boolean valid_ID = True;
UINT32 totalFree, t;
UINT16 vid;
valid_ID = False; totalFree = 0;
for ( i=0; i totalFree ) {
vid = i; totalFree = t; valid_ID = True;
}
}
if ( valid_ID )
vidCurrent = vid;
else
err = error_No_free_space;
return;
}
allocate directory from free space
Boolean verified = False;
while (!verified)
{
*ext = volumeTable[vidCurrent].alloc( nBlocks, True );
ext->len = totalBytes;
if (!(ext->len)) { err = error_No_free_space; return; }
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeDirectory : at sid %3d sector %7d num_sectors %7d\n",
ext->start.sid, ext->start.sector, nBlocks);
}
verified = True;
if (media == media_Worm) {
verified = False;
UINT32 nonBlankSector;
do a verify on this extent to make sure it can be written
if (currentDevice->verifyBlank(volumeTable[vidCurrent].sid(),
ext->start.sector,B2S(ext->len),
&nonBlankSector) == True ) {
verified = True;
}
else {
fprintf(Trace::logFile(),"writeDirectory: WARNING: non-blank sector:%d\n",nonBlankSector);
}
}
}
BYTE *bp = new BYTE[S2B(nBlocks)];
if (!bp) { err = error_No_free_store; return; }
memset( bp, 0, S2B(nBlocks));
UINT32 bytePtr = 0;
for ( i=0; i < currentDirectory.contents.getCount(); i++ )
{
fid = new FileIdentifierDesc( currentDirectory.contents[i].name );
if (!fid) { err = error_No_free_store; delete [] bp; return; }
fid->icbAddr.extType ( ext_Recorded );
fid->icbAddr.logBlockNo ( currentDirectory.contents[i]
.icbAddr.sector - partStartSector );
fid->icbAddr.partRefNo ( volumeTable.vid( currentDirectory
.contents[i].icbAddr.sid ) );
fid->icbAddr.extLength ( logicalBlockSize );
if ( currentDirectory.contents[i].hidden ) fid->markHidden();
if ( currentDirectory.contents[i].dir ) fid->markDir();
if ( i == 0 ) fid->markParent(); parent is always first entry
fid->toISO( bp + bytePtr, ext->start.sector + (bytePtr/logicalBlockSize) - partStartSector );
if (err = fid->error()) { delete fid; delete [] bp; return; }
bytePtr += fid->descLen();
delete fid;
}
for ( i = 0; i < nBlocks; i++ )
{
writeBlock( volumeTable[vidCurrent].sid(), ext->start.sector + i,
bp + (S2B(i)));
}
delete [] bp;
if (err) return;
mark directory as clean
currentDirectory.markClean();
return;
}
----------------------------------------------------------------------
METHOD: Archive::closeDirectory
User is done with this directory. Pop the directory stack.
ARGS:
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: directoryStack.pop();
directoryStack: | currentDirectory (prev-1) |<-- top of stack
|---------------------------|
| currentDirectory (prev-2) |<-- top of stack - 1
ERRORS:
error_Directory_dirty
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::closeDirectory()
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeDirectory : at sid %3d sector %7d num_sectors %7d\n",
ext->start.sid, ext->start.sector, nBlocks);
}
verified = True;
if (media == media_Worm) {
verified = False;
UINT32 nonBlankSector;
do a verify on this extent to make sure it can be written
if (currentDevice->verifyBlank(volumeTable[vidCurrent].sid(),
ext->start.sector,B2S(ext->len),
&nonBlankSector) == True ) {
verified = True;
}
else {
fprintf(Trace::logFile(),"writeDirectory: WARNING: non-blank sector:%d\n",nonBlankSector);
}
}
}
BYTE *bp = new BYTE[S2B(nBlocks)];
if (!bp) { err = error_No_free_store; return; }
memset( bp, 0, S2B(nBlocks));
UINT32 bytePtr = 0;
for ( i=0; i < currentDirectory.contents.getCount(); i++ )
{
fid = new FileIdentifierDesc( currentDirectory.contents[i].name );
if (!fid) { err = error_No_free_store; delete [] bp; return; }
fid->icbAddr.extType ( ext_Recorded );
fid->icbAddr.logBlockNo ( currentDirectory.contents[i]
.icbAddr.sector - partStartSector );
fid->icbAddr.partRefNo ( volumeTable.vid( currentDirectory
.contents[i].icbAddr.sid ) );
fid->icbAddr.extLength ( logicalBlockSize );
if ( currentDirectory.contents[i].hidden ) fid->markHidden();
if ( currentDirectory.contents[i].dir ) fid->markDir();
if ( i == 0 ) fid->markParent(); parent is always first entry
fid->toISO( bp + bytePtr, ext->start.sector + (bytePtr/logicalBlockSize) - partStartSector );
if (err = fid->error()) { delete fid; delete [] bp; return; }
bytePtr += fid->descLen();
delete fid;
}
for ( i = 0; i < nBlocks; i++ )
{
writeBlock( volumeTable[vidCurrent].sid(), ext->start.sector + i,
bp + (S2B(i)));
}
delete [] bp;
if (err) return;
mark directory as clean
currentDirectory.markClean();
return;
}
----------------------------------------------------------------------
METHOD: Archive::closeDirectory
User is done with this directory. Pop the directory stack.
ARGS:
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: directoryStack.pop();
directoryStack: | currentDirectory (prev-1) |<-- top of stack
|---------------------------|
| currentDirectory (prev-2) |<-- top of stack - 1
ERRORS:
error_Directory_dirty
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::closeDirectory()
else {
fprintf(Trace::logFile(),"writeDirectory: WARNING: non-blank sector:%d\n",nonBlankSector);
}
}
}
BYTE *bp = new BYTE[S2B(nBlocks)];
if (!bp) { err = error_No_free_store; return; }
memset( bp, 0, S2B(nBlocks));
UINT32 bytePtr = 0;
for ( i=0; i < currentDirectory.contents.getCount(); i++ )
{
fid = new FileIdentifierDesc( currentDirectory.contents[i].name );
if (!fid) { err = error_No_free_store; delete [] bp; return; }
fid->icbAddr.extType ( ext_Recorded );
fid->icbAddr.logBlockNo ( currentDirectory.contents[i]
.icbAddr.sector - partStartSector );
fid->icbAddr.partRefNo ( volumeTable.vid( currentDirectory
.contents[i].icbAddr.sid ) );
fid->icbAddr.extLength ( logicalBlockSize );
if ( currentDirectory.contents[i].hidden ) fid->markHidden();
if ( currentDirectory.contents[i].dir ) fid->markDir();
if ( i == 0 ) fid->markParent(); parent is always first entry
fid->toISO( bp + bytePtr, ext->start.sector + (bytePtr/logicalBlockSize) - partStartSector );
if (err = fid->error()) { delete fid; delete [] bp; return; }
bytePtr += fid->descLen();
delete fid;
}
for ( i = 0; i < nBlocks; i++ )
{
writeBlock( volumeTable[vidCurrent].sid(), ext->start.sector + i,
bp + (S2B(i)));
}
delete [] bp;
if (err) return;
mark directory as clean
currentDirectory.markClean();
return;
}
----------------------------------------------------------------------
METHOD: Archive::closeDirectory
User is done with this directory. Pop the directory stack.
ARGS:
RETURNS:
PRE-CONDS:
POST-CONDS:
currentDirectory: directoryStack.pop();
directoryStack: | currentDirectory (prev-1) |<-- top of stack
|---------------------------|
| currentDirectory (prev-2) |<-- top of stack - 1
ERRORS:
error_Directory_dirty
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::closeDirectory()
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"writeRootICB FE: at sid %3d sector %7d\n",
icbTable->currentAddr().sid, icbTable->currentAddr().sector);
writeBlock( icbTable->currentAddr().sid,
icbTable->currentAddr().sector, bp );
delete rfe;
delete [] bp;
if (err) return;
endICBTable = False;
icbTable->bumpPtr( 1 + nEASectors );
if (icbTable->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTable->error();
}
----------------------------------------------------------------------
METHOD: Archive::writeNextICB
Write a non-root ICB.
Verifies that the file id matches next ICB to be written. Writes
the next ICB and any required overflow sectors at the ICB pointer
location on the ICB table. It then increments the ICB pointer to
the next available ICB.
ARGS:
Attributes &attr IN Attributes for this file or dir.
const ExtentList &extList IN Locations of file data or directory.
PathElementList pList IN The symbolic link information.
Extent EAICBAddr IN Location of ICB for EAs associated
with file or directory.
RETURNS:
PRE-CONDS:
POST-CONDS:
The icb table address is bumped the appropriate amount.
endICBTable: may be set.
ERRORS:
NOTES: export
----------------------------------------------------------------------
void
NSR::Archive::writeNextICB( Attributes &attr,
const ExtentList &extList )
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"writeNextICB FE: at sid %3d sector %7d\n",
icbTbl->currentAddr().sid, icbTbl->currentAddr().sector);
writeBlock( icbTbl->currentAddr().sid,
icbTbl->currentAddr().sector, bp );
delete fe;
if (err) {
delete [] bp;
return;
}
icbTbl->bumpPtr( 1 );
if (!isEAfe) {
endICBTable = False;
if (icbTbl->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTbl->error();
}
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
for ( UINT32 i=0; i extentsPerBlock )
n = extentsPerBlock;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Long );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load long ads in allocation extent desc block
adt = aed->longADT();
for ( UINT32 j=0; jnextAddr().sector - partStartSector );
adt[n].partRefNo ( volumeTable.vid( icbTbl->nextAddr().sid ) );
adt[n].extLength ( logicalBlockSize );
adt[n].markContinued();
}
aed->toISO( bp, icbTbl->currentAddr().sector - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
write the AED block
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"writeNextICB AED: at sid %3d sector %7d\n",
icbTbl->currentAddr().sid, icbTbl->currentAddr().sector);
writeBlock( icbTbl->currentAddr().sid,
icbTbl->currentAddr().sector, bp );
if (err) {
delete [] bp;
return;
}
endICBTable = False;
icbTbl->bumpPtr( 1 );
if (!isEAfe) {
if (icbTbl->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTbl->error();
}
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
if (!isEAfe) {
icbTbl->bumpPtr( nEASectors );
if (icbTbl->error() == error_End_of_ICB_table) {
endICBTable = True;
}
else {
err = icbTbl->error();
}
}
}
void
NSR::Archive::writeNextICB( Attributes attr, PRIVATE
PathElementList pList,
const NetwareTrusteeInfo &trustees,
const Extent &EAICBAddr)
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"writeNextICB AED: at sid %3d sector %7d\n",
icbTbl->currentAddr().sid, icbTbl->currentAddr().sector);
writeBlock( icbTbl->currentAddr().sid,
icbTbl->currentAddr().sector, bp );
if (err) {
delete [] bp;
return;
}
endICBTable = False;
icbTbl->bumpPtr( 1 );
if (!isEAfe) {
if (icbTbl->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTbl->error();
}
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
if (!isEAfe) {
icbTbl->bumpPtr( nEASectors );
if (icbTbl->error() == error_End_of_ICB_table) {
endICBTable = True;
}
else {
err = icbTbl->error();
}
}
}
void
NSR::Archive::writeNextICB( Attributes attr, PRIVATE
PathElementList pList,
const NetwareTrusteeInfo &trustees,
const Extent &EAICBAddr)
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"writeNextICB FE: at sid %3d sector %7d\n",
feAddr.sid, feAddr.sector);
writeBlock( feAddr.sid, feAddr.sector, bp );
delete fe;
delete [] bp;
if (err)
return;
Create another buffer to hold the ISO version of the plist.
bp = new BYTE[S2B(elist.numBlocks(logicalBlockSize))];
if (!bp) {
err = error_No_free_store;
return;
}
Zero it out
memset( bp, 0, S2B(elist.numBlocks(logicalBlockSize)));
Now write the overflow sectors
For each path element, convert to pathComponent
UINT32 bytePtr = 0;
for ( i=0; itoISO( bp + bytePtr );
if (err = pc->error()) {
delete pc;
delete [] bp;
return;
}
bytePtr += pc->descLen();
delete pc;
}
for ( i=0; ibumpPtr( nEASectors );
if (err)
return;
return;
}
----------------------------------------------------------------------
METHOD: Archive::completeExport
Performs all actions appropriate for end of export.
Writes nsr volume information on all volumes. Writes a closed
integrity entry.
ARGS: none.
RETURNS: none.
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
Updates each volume still marked dirty with space
information. Then, writes FSD, LVID on root, and closes the
logical volume.
----------------------------------------------------------------------
void
NSR::Archive::completeExport()
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeNextICB path: at sid %3d sector %7d\n",
elist[i].start.sid, elist[i].start.sector);
}
writeBlock( elist[i].start.sid, elist[i].start.sector, bp + (S2B(i)));
}
delete [] bp;
icbTable->bumpPtr( nEASectors );
if (err)
return;
return;
}
----------------------------------------------------------------------
METHOD: Archive::completeExport
Performs all actions appropriate for end of export.
Writes nsr volume information on all volumes. Writes a closed
integrity entry.
ARGS: none.
RETURNS: none.
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
Updates each volume still marked dirty with space
information. Then, writes FSD, LVID on root, and closes the
logical volume.
----------------------------------------------------------------------
void
NSR::Archive::completeExport()
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"readRootICB FE: at sid %3d sector %7d\n",
rootICB.sid, rootICB.sector);
readBlock( rootICB.sid, rootICB.sector, bp);
if (err) {
delete rfe;
delete [] bp;
return;
}
rfe->fromISO( bp, rootICB.sector - partStartSector );
if (err=rfe->error()) {
delete rfe;
delete [] bp;
return;
}
First, get the Trustees
(Also fills in Archive::icbTable)
UINT32 nEASectors = 0; Needed later
loadEAs( rootICB, rfe, trustees, nEASectors);
if (err) {
delete rfe;
delete [] bp;
return;
}
If no icbTable by this point, BAD NEWS!
if (!icbTable) {
err = error_Invalid_ICB_table;
delete rfe;
delete [] bp;
return;
}
Fill in rootDirAttr
if (rootDirAttr != NULL) {
rootDirAttr-> fromFileEntry(*rfe);
}
Fill in rootDirExt
if (rootDirExt != NULL) {
LongAllocDesc *adt = rfe->longADT();
rootDirExt->start.sid = volumeTable[adt[0].partRefNo()].sid();
rootDirExt->start.sector = adt[0].logBlockNo() + partStartSector;
rootDirExt->len = adt[0].extLength();
}
Fill in implInfo
if (implInfo != NULL) {
rfe->implementID.getImplementInfo(*implInfo);
}
delete rfe;
delete [] bp;
if (! readingICBTable ) {
set the ICB pointer to the next sector after root ICB
endICBTable = False;
icbTable->bumpPtr( 1 + nEASectors );
if (icbTable->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTable->error() ;
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::readNextICB
Read the next ICB.
Reads the next ICB from the ICB table. Also increments the
ICB pointer to the next ICB.
If extList returns NULL, the next ICB was not on the current
volume. The next volume is then specified by addr.
ARGS:
Attributes *attr OUT Attributes for next directory.
ExtentList *extList OUT Location of next directory.
Extent *EAICBAddr OUT Location of ICB for EAs.
RETURNS:
-1 The end of the ICB table has been reached.
0 The end of the ICB table has not been reached.
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
int
NSR::Archive::readNextICB( Address *addr,
Attributes *attr,
ExtentList *extList )
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"readNextICB FE: at sid %3d sector %7d\n",
icbTable->currentAddr().sid,
icbTable->currentAddr().sector);
readBlock( icbTable->currentAddr().sid,
icbTable->currentAddr().sector,
bp );
if (err) {
delete [] bp;
return 0;
}
fe = new FileEntry;
if (!fe) {
err = error_No_free_store;
delete [] bp;
return 0;
}
fe->fromISO( bp, icbTable->currentAddr().sector - partStartSector );
if (err = fe->error()) {
delete fe;
delete [] bp;
return 0;
}
load attributes
attr->fromFileEntry(*fe); was *attr = fe->getAttributes();
check - should not be ea !
if (attr->fileType() == file_ExtendedAttributes) {
err = error_Unexpected_EA_icb;
delete fe;
delete [] bp;
return 0;
}
getICBExtents( fe, extList );
if (err) {
delete fe;
delete [] bp;
return 0;
}
Fill in EAICBAddr
if (EAICBAddr != NULL) {
const LongAllocDesc & eaicba = fe->extendedAttrICB;
EAICBAddr->start.sid = volumeTable[eaicba.partRefNo()].sid();
EAICBAddr->start.sector = eaicba.logBlockNo() + partStartSector;
EAICBAddr->len = eaicba.extLength();
}
load extended attributes
UINT32 nEASectors = 0;
#ifdef TRUSTEES
loadEAs( icbTable->currentAddr(),
fe,
trustees,
nEASectors);
if (err) {
delete fe;
delete [] bp;
return 0;
}
#endif TRUSTEES
delete fe;
delete [] bp;
set the ICB pointer to the next ICB
endICBTable = False;
icbTable->bumpPtr(1 + nEASectors);
if (attr->fileType() == file_SymbolicLink) {
UINT32 nBlocks = B2S(extList->totalBytes());
icbTable->bumpPtr( nBlocks );
}
if (icbTable->error() == error_End_of_ICB_table)
endICBTable = True;
else
err = icbTable->error();
return (endICBTable) ? -1 : 0;
}
----------------------------------------------------------------------
METHOD: Archive::readPath
Read the path information for a symbolic link.
ARGS:
ExtentList &elist, IN Locations for path information
PathElementList *pList OUT The path information.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readPath( ExtentList &elist,
PathElementList *pList )
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"readNextICB path: at sid %3d sector %7d\n",
elist[i].start.sid, elist[i].start.sector);
readBlock( elist[i].start.sid, elist[i].start.sector, bp + (S2B(i)));
}
PathElement pe;
PathComponent *pc;
pList->clear();
while ( bytePtr < elist.totalBytes() ) {
pc = new PathComponent();
if (!pc) {
err = error_No_free_store;
delete [] bp;
return;
}
pc->fromISO( bp + bytePtr );
if (err = pc->error()) {
delete pc;
delete [] bp;
return;
}
pe = PathElement(*pc);
bytePtr += pc->descLen();
delete pc;
pList->append( pe );
if (err = pList->error()) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::endOfICBTable --AP
Returns True if at end of ICB Table.
ARGS:
NONE
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::endOfICBTable()
void
NSR::Archive::logFile(FILE * lf) {
Trace::logFile(lf);
}
----------------------------------------------------------------------
METHOD: Archive::logErrors --DVM
Enables or disables the logging of the Archive Object's error
state. Whenever a public method is exited, the error, if set, will
be printed to the log, if a logFile has been specified.
ARGS:
Boolean le IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Errors will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logErrors(Boolean le) {
if (le) {
Trace::defaultError(err);
}
Trace::logErrors(le);
}
----------------------------------------------------------------------
METHOD: Archive::logAlgorithms --DVM
Enables or disables the logging of the Archive Object's
miscellaneous algorithmic output.
ARGS:
Boolean la IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Miscellaneous printf()s will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logAlgorithms(Boolean la) {
Trace::logAlgorithms(la);
}
----------------------------------------------------------------------
METHOD: Archive::logCalls --DVM
Enables or disables the logging of the entry and exit of all of
the Archive Object's public methods.
ARGS:
Boolean lc IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Entries and Exits to/from Archive Object's public methods will or
will not be logged to the logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)
NSR::Archive::logFile(FILE * lf) {
Trace::logFile(lf);
}
----------------------------------------------------------------------
METHOD: Archive::logErrors --DVM
Enables or disables the logging of the Archive Object's error
state. Whenever a public method is exited, the error, if set, will
be printed to the log, if a logFile has been specified.
ARGS:
Boolean le IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Errors will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logErrors(Boolean le) {
if (le) {
Trace::defaultError(err);
}
Trace::logErrors(le);
}
----------------------------------------------------------------------
METHOD: Archive::logAlgorithms --DVM
Enables or disables the logging of the Archive Object's
miscellaneous algorithmic output.
ARGS:
Boolean la IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Miscellaneous printf()s will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logAlgorithms(Boolean la) {
Trace::logAlgorithms(la);
}
----------------------------------------------------------------------
METHOD: Archive::logCalls --DVM
Enables or disables the logging of the entry and exit of all of
the Archive Object's public methods.
ARGS:
Boolean lc IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Entries and Exits to/from Archive Object's public methods will or
will not be logged to the logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"getICBExtents AED: at sid %3d sector %7d\n",
icbTable->currentAddr().sid,
icbTable->currentAddr().sector);
readBlock( icbTable->currentAddr().sid,
icbTable->currentAddr().sector, bp );
if (err) {
delete [] bp;
return;
}
delete aed;
aed = new AllocExtentDesc( 1, ad_Long);
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
aed->fromISO( bp, icbTable->currentAddr().sector - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
noExtents = aed->numADTEnts();
adt = aed->longADT();
i = 0;
} else {
ext.start.sid = volumeTable[adt[i].partRefNo()].sid();
ext.start.sector = adt[i].logBlockNo() + partStartSector;
ext.len = adt[i].extLength();
extList->append( ext );
if (err = extList->error()) {
delete aed;
delete [] bp;
return;
}
i++;
}
}
}
delete aed;
delete [] bp;
}
void
NSR::Archive::readSector( sid_t sid, UINT32 a, BYTE *bp )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"can't write indirect entry icb at 0x%x\n",indirectEntryAddress);
}
}
delete ie;
delete [] bp;
}
----------------------------------------------------------------------
METHOD: Archive::getSeqExtent
Get an extent for use in extending a USE or FSD sequence.
Use up the previously allocated space. The allocation had to occur
before the areas for the icb's was allocated so that the check for
available space was accurate.
ISSUE: this should be an extent list ??
ARGS:
sid_t sid, IN Surface ID.
UINT32 nSectors, IN Number of sectors.
Extent &newExtent OUT The extent.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
used only for WORM and only if sequences can grow > fileDataStart
----------------------------------------------------------------------
void
NSR::Archive::getSeqExtent(sid_t sid, UINT32 nSectors, Extent &newExtent)
else {
fprintf(Trace::logFile(),"checkRootVolumeSpace: aed's for use won't be written\n");
}
}
-------------------------------------------------------------
check space for FSD. FSD is always one sector.
-------------------------------------------------------------
nSectors = 1;
nRead = 0;
lastDescNum = 0;
nextBlankAddr = 0;
lastRecordedAddr = 0;
needsIndirect = False;
getNextSeqAddress(rootSid,
volumeTable.rootVol().fsdsExt,
nSectors,&nRead,&nextBlankAddr,&lastDescNum,
&lastRecordedAddr,&needsIndirect,&bogusICBInfo);
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if (needsIndirect) {
if (!partitionSeqAllowed) {err = error_End_of_Sequence_space; return;}
neededSectors += incrementalSeqSectors;
}
err = error_None;
}
NSR::UINT32
NSR::Archive::writeExtents(sid_t sid, ICB_Table *icbTbl, UINT32 n, BYTE *bp)
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"write extent:%d\n",icbTbl->currentAddr().sector);
writeSector(sid, icbTbl->currentAddr().sector, bp);
bp += logicalBlockSize;
icbTbl->bumpPtr(1);
nwritten++;
}
return nwritten;
}
NSR::UINT32
NSR::Archive::readExtent(const Extent &e, BYTE *bp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): prevRootFSD:\n");
prevRootFSD.fprint(Trace::logFile());
}
if ( media == media_Worm ) {
-----------------------------------------------------------------
Must find how long the previous FSD is. It must be moved to the
new root. This will dictate the space requirements on new root
volume for the old FSDS.
----------------------------------------------------------------
Extent fsdHistoryExt; Where new copies go.
Extent lastFsdNextExt; For chaining algorithm
UINT32 nFSDSectors = 0;
UINT32 nSectors = 1;
UINT32 nextBlankAddr = 0;
UINT32 lastRecordedAddr = 0;
UINT32 lastDescNum = 0;
Boolean needsIndirect = False;
getNextSeqAddress(prevRootSid,prevRootFSD,nSectors,&nFSDSectors,
&nextBlankAddr,&lastDescNum,
&lastRecordedAddr,&needsIndirect,&bogusICBInfo);
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: fsd sequence length: %d\n",nFSDSectors);
fprintf(Trace::logFile(),"copyFSDS: last fsd number: %d\n",lastDescNum);
fprintf(Trace::logFile(),"copyFSDS: lastRecordedAddr:: %d\n",lastRecordedAddr);
}
------------------------------------------------------------
Allocate space for previous fsd's. Also verify it is blank.
If there is not enough space, the whole export will fail.
------------------------------------------------------------
Boolean verified = False;
UINT32 nonBlankSector;
while ( !verified )
{
Allocate it.
fsdHistoryExt = newRootVol.alloc( nFSDSectors, True );
Error if not enough room
if (!(fsdHistoryExt.len)) {
err = error_No_free_space;
delete fsd;
return;
}
Verify that it is blank
if (currentDevice->
verifyBlank( newRootSid,
fsdHistoryExt.start.sector,
B2S(fsdHistoryExt.len),
&nonBlankSector) == True) {
verified = True;
}
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"copyFSDS(): prevRootFSD:\n");
prevRootFSD.fprint(Trace::logFile());
}
if ( media == media_Worm ) {
-----------------------------------------------------------------
Must find how long the previous FSD is. It must be moved to the
new root. This will dictate the space requirements on new root
volume for the old FSDS.
----------------------------------------------------------------
Extent fsdHistoryExt; Where new copies go.
Extent lastFsdNextExt; For chaining algorithm
UINT32 nFSDSectors = 0;
UINT32 nSectors = 1;
UINT32 nextBlankAddr = 0;
UINT32 lastRecordedAddr = 0;
UINT32 lastDescNum = 0;
Boolean needsIndirect = False;
getNextSeqAddress(prevRootSid,prevRootFSD,nSectors,&nFSDSectors,
&nextBlankAddr,&lastDescNum,
&lastRecordedAddr,&needsIndirect,&bogusICBInfo);
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: fsd sequence length: %d\n",nFSDSectors);
fprintf(Trace::logFile(),"copyFSDS: last fsd number: %d\n",lastDescNum);
fprintf(Trace::logFile(),"copyFSDS: lastRecordedAddr:: %d\n",lastRecordedAddr);
}
------------------------------------------------------------
Allocate space for previous fsd's. Also verify it is blank.
If there is not enough space, the whole export will fail.
------------------------------------------------------------
Boolean verified = False;
UINT32 nonBlankSector;
while ( !verified )
{
Allocate it.
fsdHistoryExt = newRootVol.alloc( nFSDSectors, True );
Error if not enough room
if (!(fsdHistoryExt.len)) {
err = error_No_free_space;
delete fsd;
return;
}
Verify that it is blank
if (currentDevice->
verifyBlank( newRootSid,
fsdHistoryExt.start.sector,
B2S(fsdHistoryExt.len),
&nonBlankSector) == True) {
verified = True;
}
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: fsd sequence length: %d\n",nFSDSectors);
fprintf(Trace::logFile(),"copyFSDS: last fsd number: %d\n",lastDescNum);
fprintf(Trace::logFile(),"copyFSDS: lastRecordedAddr:: %d\n",lastRecordedAddr);
}
------------------------------------------------------------
Allocate space for previous fsd's. Also verify it is blank.
If there is not enough space, the whole export will fail.
------------------------------------------------------------
Boolean verified = False;
UINT32 nonBlankSector;
while ( !verified )
{
Allocate it.
fsdHistoryExt = newRootVol.alloc( nFSDSectors, True );
Error if not enough room
if (!(fsdHistoryExt.len)) {
err = error_No_free_space;
delete fsd;
return;
}
Verify that it is blank
if (currentDevice->
verifyBlank( newRootSid,
fsdHistoryExt.start.sector,
B2S(fsdHistoryExt.len),
&nonBlankSector) == True) {
verified = True;
}
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"copyFSDS: fsd sequence length: %d\n",nFSDSectors);
fprintf(Trace::logFile(),"copyFSDS: last fsd number: %d\n",lastDescNum);
fprintf(Trace::logFile(),"copyFSDS: lastRecordedAddr:: %d\n",lastRecordedAddr);
}
------------------------------------------------------------
Allocate space for previous fsd's. Also verify it is blank.
If there is not enough space, the whole export will fail.
------------------------------------------------------------
Boolean verified = False;
UINT32 nonBlankSector;
while ( !verified )
{
Allocate it.
fsdHistoryExt = newRootVol.alloc( nFSDSectors, True );
Error if not enough room
if (!(fsdHistoryExt.len)) {
err = error_No_free_space;
delete fsd;
return;
}
Verify that it is blank
if (currentDevice->
verifyBlank( newRootSid,
fsdHistoryExt.start.sector,
B2S(fsdHistoryExt.len),
&nonBlankSector) == True) {
verified = True;
}
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"copyFSDS: last fsd number: %d\n",lastDescNum);
fprintf(Trace::logFile(),"copyFSDS: lastRecordedAddr:: %d\n",lastRecordedAddr);
}
------------------------------------------------------------
Allocate space for previous fsd's. Also verify it is blank.
If there is not enough space, the whole export will fail.
------------------------------------------------------------
Boolean verified = False;
UINT32 nonBlankSector;
while ( !verified )
{
Allocate it.
fsdHistoryExt = newRootVol.alloc( nFSDSectors, True );
Error if not enough room
if (!(fsdHistoryExt.len)) {
err = error_No_free_space;
delete fsd;
return;
}
Verify that it is blank
if (currentDevice->
verifyBlank( newRootSid,
fsdHistoryExt.start.sector,
B2S(fsdHistoryExt.len),
&nonBlankSector) == True) {
verified = True;
}
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
else {
fprintf(Trace::logFile(),"copyFSDS: WARNING: non-blank sector %d\n",
nonBlankSector);
}
}
------------------------------------------------------------
Move previous fsd's, in chunks for efficiency.
Each extent of old FSDS is read, and then copied to the new
root.
------------------------------------------------------------
UINT32 nSectorsRead;
UINT32 nWritten = 0;
Extent prevfsde = prevRootFSD;
Boolean done = False;
while (!done)
{
-------------------------------------------
Allocate a buffer for the extent.
-------------------------------------------
bp = new BYTE[prevfsde.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
-------------------------------------------
Read in the extent.
-------------------------------------------
nSectorsRead = readExtent(prevfsde, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
done = True;
}
else {
delete fsd;
delete [] bp;
return;
}
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS:read %d sectors of old sequence\n",
nSectorsRead);
}
-------------------------------------------
write the extent (to the new volume).
-------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
-------------------------------------------
First, convert to a valid FSD
-------------------------------------------
fsd->fromISO( bp + (j*logicalSectorSize),
prevfsde.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
if (j == (nSectorsRead - 1)) {
lastFsdNextExt.start.sector = (fsd->nextExtent.logBlockNo() +
partStartSector );
lastFsdNextExt.len = fsd->nextExtent.extLength();
}
If this was last extent of FSDS, set to continue in
normal FSDS location (held in newRootFSD).
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if (done && (j == (nSectorsRead - 1))) {
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"setting fsd->nextExtent\n"); }
fsd->nextExtent.partRefNo(volumeTable.rootVid());
fsd->nextExtent.logBlockNo(newRootFSD.start.sector
-partStartSector);
fsd->nextExtent.extLength( newRootFSD.len );
} else {
Otherwise, set nextExtent field to zeros,
indicating that the sequence continues with the
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
next sector (normal FSDS).
if(Trace::logAlgorithms()) { fprintf(Trace::logFile(),"fsd->nextExtent len = 0\n"); }
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
}
-------------------------------------------
Translate FSD back to ISO in buffer.
-------------------------------------------
fsd->toISO( bp + (j*logicalSectorSize),
fsdHistoryExt.start.sector + nWritten
- partStartSector );
writeSector(newRootSid,
fsdHistoryExt.start.sector + nWritten,
bp + (j*logicalSectorSize));
if (err) {
delete fsd;
delete [] bp;
return;
}
nWritten++;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"wrote new fsd at sid:%d\n",newRootSid);
fprintf(Trace::logFile()," sector:%d\n",fsdHistoryExt.start.sector+j);
}
}
-----------------------------------------------------------
Extent was full - no blank sectors, so look at nextExtent
field of last FSD for where to continue.
-----------------------------------------------------------
if (!done) {
-----------------------------------------------------------
look for possible next extent identified in last fsd read
-----------------------------------------------------------
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"lastFsdNextExt.len:%d\n",
lastFsdNextExt.len);
}
prevfsde = lastFsdNextExt;
-----------------------------------------------------------
If there was no continuation, then it was the last FSD
that exists. Therefore, copy is complete. NOTE that
nextExtent field of FSD was already filled in inside
the loop.
-----------------------------------------------------------
if (prevfsde.len == 0) {
done = True;
}
}
}
Update information in root volume.
newRootFSD = fsdHistoryExt;
Delete buffer
delete [] bp;
} else { media_Rewritable
Simply need to copy the single FSD from previous root to
new root.
Error if a longer FSDS than a single sector
if ( (prevRootFSD.len != logicalBlockSize) ||
(newRootFSD.len != logicalBlockSize) ) {
err = error_Wrong_FSDS_extent_length;
delete fsd;
return;
}
Allocate a buffer for the extent.
bp = new BYTE[prevRootFSD.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return;
}
Read in the extent.
readExtent(prevRootFSD, bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where read.
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"copyFSDS: read old FSDS at ");
prevRootFSD.fprint(Trace::logFile());
}
Translate the FSD to match new address, etc.
fsd->fromISO( bp, (prevRootFSD.start.sector
- partStartSector));
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
Set nextExtent field to zeros, indicating that the sequence
continues with the next sector (normal FSDS).
These should already be set, but...
fsd->nextExtent.partRefNo(0);
fsd->nextExtent.logBlockNo(0);
fsd->nextExtent.extLength(0);
Translate FSD back to ISO in buffer.
fsd->toISO( bp, (newRootFSD.start.sector
- partStartSector ));
Write it out.
writeSector(newRootSid,
newRootFSD.start.sector,
bp);
if (err) {
delete fsd;
delete [] bp;
return;
}
Dump out where written
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
fprintf(Trace::logFile(),"copyFSDS(): wrote new fsd at: ");
newRootFSD.fprint(Trace::logFile());
}
#ifdef _FSDS_TD_
Write a single TD to terminate sequence
writeTD( newRootSid,
newRootVol.fsdsExt.start.sector - partStartSector +1,
newRootVol.fsdsExt.start.sector +1 );
No check for errors, because this is the last action
#endif _FSDS_TD_
newRootFSD remains unchanged.
Delete buffer
delete [] bp;
}
delete FSD
delete fsd;
}
----------------------------------------------------------------------
METHOD: Archive::readBlind
This method reads a sector at the supplied address, and then if
the sector contains a valid descriptor, reallocates the supplied
buffer and then reads in the entire descriptor. The
passed-in-by-reference SearchDescriptor is left reflecting the
state of what it found on the disk.
ARGS:
sid_t sid, IN Surface ID
UINT32 addr, IN Sector
SearchDescriptor & sd IN Search Descriptor
BYTE **bpp IN/OUT Pointer to data
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::readBlind(sid_t sid,
UINT32 addr,
SearchDescriptor & sd,
BYTE **bpp)
if ( e.start.sector + ovf > e.start.sector + B2S(e.len) ) {
fprintf(Trace::logFile(),"writeSpaceEntry: no room to write all extents: truncating\n");
ovf = B2S(e.len) - 1;
N = extentsPerUSE + (ovf * extentsPerAED);
}
}
UINT32 n;
if ( ovf > 0 ) {
n = extentsPerUSE - 1;
}
else {
n = N;
}
use = new UnallocatedSpaceEntry(n + (ovf > 0));
if (!use) {
err = error_No_free_store;
delete [] bp;
return;
}
N -= n;
Initialize lastUSEICBInfo for getNextSeqAddress()
lastUSEICBInfo.priNoDirectEntries = 0;
lastUSEICBInfo.maxEntries = (B2S(e.len))/(ovf+1);
lastUSEICBInfo.strategyParm = (B2S(e.len))/(ovf+1) - 1;
if (media == media_Worm) {
extent.start.sector = e.start.sector;
extent.len = e.len;
nRead = 0;
lastDescNum = 0;
lastRecordedAddr = 0;
nextBlankAddr = 0;
needsIndirect = False;
getNextSeqAddress(sid,extent,1,&nRead,&nextBlankAddr,&lastDescNum,
&lastRecordedAddr,&needsIndirect,&lastUSEICBInfo);
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): nextBlankAddr = %d;lastRecordedAddr = %d.\n",
nextBlankAddr,lastRecordedAddr);
}
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if (needsIndirect) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeSpaceEntry(): needs Indirect\n");
}
if (partitionSeqAllowed) {
getSeqExtent(sid,incrementalSeqSectors,extent);
if (err) {
delete [] bp;
delete use;
return;
}
UINT16 strategyParm = incrementalSeqSectors - 1;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing Indirect at %d.\n",
nextBlankAddr);
}
writeIndirectEntry(sid, nextBlankAddr,extent,lastDescNum,
incrementalSeqSectors,strategyParm);
if (err) {
delete [] bp;
delete use;
return;
}
nextBlankAddr = extent.start.sector;
}
else {
if (vid == volumeTable.rootVid()) {
need new root volume
err = error_End_of_Sequence_space;
delete [] bp;
delete use;
return;
}
else {
non-root volume - write a use indicating no space left.
N = 0;
n = 0;
ovf = 0;
}
}
}
addr = nextBlankAddr;
}
use->icbTag.icbType(icb_UnallocatedSpaceEntry); never changes
!!! The following logic may not be correct. It ensures that MO
conforms, but has not been checked for WORM conformance.
- DVM 4/30/96
if (media == media_Worm) {
if (use->icbTag.priNoDirectEntries) {
use->icbTag.priNoDirectEntries =
lastUSEICBInfo.priNoDirectEntries + 1;
}
use->icbTag.strategyType = 2;
use->icbTag.maxEntries = lastUSEICBInfo.maxEntries;
use->icbTag.strategyParm = lastUSEICBInfo.strategyParm;
use->icbTag.parentICB.logicalBlockNo = e.start.sector - partStartSector;
use->icbTag.parentICB.partitionRefNo = vid;
} else {
use->icbTag.priNoDirectEntries = 0;
use->icbTag.strategyType = 4;
use->icbTag.maxEntries = 1;
use->icbTag.strategyParm = 0;
use->icbTag.parentICB.logicalBlockNo = 0;
use->icbTag.parentICB.partitionRefNo = 0;
}
ShortAllocDesc *adt = use->shortADT();
for ( j=0; j 0 ) {
if (media != media_Worm) {
adt[n].extType ( ext_Recorded );
adt[n].logBlockNo ( addr + 1 - partStartSector );
adt[n].extLength ( logicalBlockSize );
adt[n].markContinued();
}
else {
if (partitionSeqAllowed) {
get space for aed's
getSeqExtent(sid,ovf,extent);
if (err) {
delete use;
delete [] bp;
return;
}
addr = extent.start.sector;
}
else {
fprintf(Trace::logFile(),"writeSpace: aed's can't be written\n");
adt[index].extType ( spcType );
adt[index].logBlockNo ( space[index].start.sector - partStartSector );
adt[index].extLength ( space[index].len );
ovf = 0;
}
}
}
write the unallocated space entry
memset( bp, 0, logicalBlockSize );
use->toISO( bp, addr - partStartSector );
if (err = use->error()) {
delete use;
delete [] bp;
return;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): nextBlankAddr = %d;lastRecordedAddr = %d.\n",
nextBlankAddr,lastRecordedAddr);
}
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if (needsIndirect) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeSpaceEntry(): needs Indirect\n");
}
if (partitionSeqAllowed) {
getSeqExtent(sid,incrementalSeqSectors,extent);
if (err) {
delete [] bp;
delete use;
return;
}
UINT16 strategyParm = incrementalSeqSectors - 1;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing Indirect at %d.\n",
nextBlankAddr);
}
writeIndirectEntry(sid, nextBlankAddr,extent,lastDescNum,
incrementalSeqSectors,strategyParm);
if (err) {
delete [] bp;
delete use;
return;
}
nextBlankAddr = extent.start.sector;
}
else {
if (vid == volumeTable.rootVid()) {
need new root volume
err = error_End_of_Sequence_space;
delete [] bp;
delete use;
return;
}
else {
non-root volume - write a use indicating no space left.
N = 0;
n = 0;
ovf = 0;
}
}
}
addr = nextBlankAddr;
}
use->icbTag.icbType(icb_UnallocatedSpaceEntry); never changes
!!! The following logic may not be correct. It ensures that MO
conforms, but has not been checked for WORM conformance.
- DVM 4/30/96
if (media == media_Worm) {
if (use->icbTag.priNoDirectEntries) {
use->icbTag.priNoDirectEntries =
lastUSEICBInfo.priNoDirectEntries + 1;
}
use->icbTag.strategyType = 2;
use->icbTag.maxEntries = lastUSEICBInfo.maxEntries;
use->icbTag.strategyParm = lastUSEICBInfo.strategyParm;
use->icbTag.parentICB.logicalBlockNo = e.start.sector - partStartSector;
use->icbTag.parentICB.partitionRefNo = vid;
} else {
use->icbTag.priNoDirectEntries = 0;
use->icbTag.strategyType = 4;
use->icbTag.maxEntries = 1;
use->icbTag.strategyParm = 0;
use->icbTag.parentICB.logicalBlockNo = 0;
use->icbTag.parentICB.partitionRefNo = 0;
}
ShortAllocDesc *adt = use->shortADT();
for ( j=0; j 0 ) {
if (media != media_Worm) {
adt[n].extType ( ext_Recorded );
adt[n].logBlockNo ( addr + 1 - partStartSector );
adt[n].extLength ( logicalBlockSize );
adt[n].markContinued();
}
else {
if (partitionSeqAllowed) {
get space for aed's
getSeqExtent(sid,ovf,extent);
if (err) {
delete use;
delete [] bp;
return;
}
addr = extent.start.sector;
}
else {
fprintf(Trace::logFile(),"writeSpace: aed's can't be written\n");
adt[index].extType ( spcType );
adt[index].logBlockNo ( space[index].start.sector - partStartSector );
adt[index].extLength ( space[index].len );
ovf = 0;
}
}
}
write the unallocated space entry
memset( bp, 0, logicalBlockSize );
use->toISO( bp, addr - partStartSector );
if (err = use->error()) {
delete use;
delete [] bp;
return;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeSpaceEntry(): needs Indirect\n");
}
if (partitionSeqAllowed) {
getSeqExtent(sid,incrementalSeqSectors,extent);
if (err) {
delete [] bp;
delete use;
return;
}
UINT16 strategyParm = incrementalSeqSectors - 1;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing Indirect at %d.\n",
nextBlankAddr);
}
writeIndirectEntry(sid, nextBlankAddr,extent,lastDescNum,
incrementalSeqSectors,strategyParm);
if (err) {
delete [] bp;
delete use;
return;
}
nextBlankAddr = extent.start.sector;
}
else {
if (vid == volumeTable.rootVid()) {
need new root volume
err = error_End_of_Sequence_space;
delete [] bp;
delete use;
return;
}
else {
non-root volume - write a use indicating no space left.
N = 0;
n = 0;
ovf = 0;
}
}
}
addr = nextBlankAddr;
}
use->icbTag.icbType(icb_UnallocatedSpaceEntry); never changes
!!! The following logic may not be correct. It ensures that MO
conforms, but has not been checked for WORM conformance.
- DVM 4/30/96
if (media == media_Worm) {
if (use->icbTag.priNoDirectEntries) {
use->icbTag.priNoDirectEntries =
lastUSEICBInfo.priNoDirectEntries + 1;
}
use->icbTag.strategyType = 2;
use->icbTag.maxEntries = lastUSEICBInfo.maxEntries;
use->icbTag.strategyParm = lastUSEICBInfo.strategyParm;
use->icbTag.parentICB.logicalBlockNo = e.start.sector - partStartSector;
use->icbTag.parentICB.partitionRefNo = vid;
} else {
use->icbTag.priNoDirectEntries = 0;
use->icbTag.strategyType = 4;
use->icbTag.maxEntries = 1;
use->icbTag.strategyParm = 0;
use->icbTag.parentICB.logicalBlockNo = 0;
use->icbTag.parentICB.partitionRefNo = 0;
}
ShortAllocDesc *adt = use->shortADT();
for ( j=0; j 0 ) {
if (media != media_Worm) {
adt[n].extType ( ext_Recorded );
adt[n].logBlockNo ( addr + 1 - partStartSector );
adt[n].extLength ( logicalBlockSize );
adt[n].markContinued();
}
else {
if (partitionSeqAllowed) {
get space for aed's
getSeqExtent(sid,ovf,extent);
if (err) {
delete use;
delete [] bp;
return;
}
addr = extent.start.sector;
}
else {
fprintf(Trace::logFile(),"writeSpace: aed's can't be written\n");
adt[index].extType ( spcType );
adt[index].logBlockNo ( space[index].start.sector - partStartSector );
adt[index].extLength ( space[index].len );
ovf = 0;
}
}
}
write the unallocated space entry
memset( bp, 0, logicalBlockSize );
use->toISO( bp, addr - partStartSector );
if (err = use->error()) {
delete use;
delete [] bp;
return;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing Indirect at %d.\n",
nextBlankAddr);
}
writeIndirectEntry(sid, nextBlankAddr,extent,lastDescNum,
incrementalSeqSectors,strategyParm);
if (err) {
delete [] bp;
delete use;
return;
}
nextBlankAddr = extent.start.sector;
}
else {
if (vid == volumeTable.rootVid()) {
need new root volume
err = error_End_of_Sequence_space;
delete [] bp;
delete use;
return;
}
else {
non-root volume - write a use indicating no space left.
N = 0;
n = 0;
ovf = 0;
}
}
}
addr = nextBlankAddr;
}
use->icbTag.icbType(icb_UnallocatedSpaceEntry); never changes
!!! The following logic may not be correct. It ensures that MO
conforms, but has not been checked for WORM conformance.
- DVM 4/30/96
if (media == media_Worm) {
if (use->icbTag.priNoDirectEntries) {
use->icbTag.priNoDirectEntries =
lastUSEICBInfo.priNoDirectEntries + 1;
}
use->icbTag.strategyType = 2;
use->icbTag.maxEntries = lastUSEICBInfo.maxEntries;
use->icbTag.strategyParm = lastUSEICBInfo.strategyParm;
use->icbTag.parentICB.logicalBlockNo = e.start.sector - partStartSector;
use->icbTag.parentICB.partitionRefNo = vid;
} else {
use->icbTag.priNoDirectEntries = 0;
use->icbTag.strategyType = 4;
use->icbTag.maxEntries = 1;
use->icbTag.strategyParm = 0;
use->icbTag.parentICB.logicalBlockNo = 0;
use->icbTag.parentICB.partitionRefNo = 0;
}
ShortAllocDesc *adt = use->shortADT();
for ( j=0; j 0 ) {
if (media != media_Worm) {
adt[n].extType ( ext_Recorded );
adt[n].logBlockNo ( addr + 1 - partStartSector );
adt[n].extLength ( logicalBlockSize );
adt[n].markContinued();
}
else {
if (partitionSeqAllowed) {
get space for aed's
getSeqExtent(sid,ovf,extent);
if (err) {
delete use;
delete [] bp;
return;
}
addr = extent.start.sector;
}
else {
fprintf(Trace::logFile(),"writeSpace: aed's can't be written\n");
adt[index].extType ( spcType );
adt[index].logBlockNo ( space[index].start.sector - partStartSector );
adt[index].extLength ( space[index].len );
ovf = 0;
}
}
}
write the unallocated space entry
memset( bp, 0, logicalBlockSize );
use->toISO( bp, addr - partStartSector );
if (err = use->error()) {
delete use;
delete [] bp;
return;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
else {
fprintf(Trace::logFile(),"writeSpace: aed's can't be written\n");
adt[index].extType ( spcType );
adt[index].logBlockNo ( space[index].start.sector - partStartSector );
adt[index].extLength ( space[index].len );
ovf = 0;
}
}
}
write the unallocated space entry
memset( bp, 0, logicalBlockSize );
use->toISO( bp, addr - partStartSector );
if (err = use->error()) {
delete use;
delete [] bp;
return;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing USE to sid %d sector %d\n",
sid,addr);
}
writeBlock( sid, addr, bp );
delete use;
if (err) {
delete [] bp;
return;
}
write required AEDs to hold remaining extents
if (media != media_Worm) {
addr++;
}
else {
addr = extent.start.sector;
}
for ( UINT32 i=0; i extentsPerAED )
n = extentsPerAED - 1;
else
n = N;
N -= n;
aed = new AllocExtentDesc( (n + ( ovf != (i+1) )), ad_Short );
if (!aed) {
err = error_No_free_store;
delete [] bp;
return;
}
memset( bp, 0, logicalBlockSize );
load short ads in allocation extent desc block
adt = aed->shortADT();
for ( j=0; jtoISO( bp, addr - partStartSector );
if (err = aed->error()) {
delete aed;
delete [] bp;
return;
}
delete aed;
Dump it out if tracing
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeSpaceEntry(): writing AED to sid %d sector %d\n",
sid,addr);
}
write the AED block
writeBlock( sid, addr, bp );
if (err) {
delete [] bp;
return;
}
}
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::searchForDesc --DVM
Searches a single VDS for a specific descriptor type.
If the descriptor is found, the vdsNum is returned, along with a
modified extent. The address of the extent where the descriptor
was found.
ARGS:
TagType descrType IN Descriptor to search for
Extent seqExtent IN/OUT Location to be searched
UINT32 vdsNum OUT Volume Descriptor Sequence Number
RETURNS:
True if found; False if not.
PRE-CONDITIONS: open archive object.
POST-CONDITIONS:
ERRORS:
error_No_free_store
misc device or fromISO errors
NOTES:
Does not currently follow VDS continuations. Could be added later.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::searchForDesc( TagType searchDescType,
Extent & seqExtent,
UINT32 & vdsNum )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeVDS(): calling writeSpaceEntry() on UnerasedSpace.\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
if (media != media_Worm) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeVDS(): calling writeSpaceEntry() on ErasedSpace.\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeVolumeLabel
Writes the nsr volume information.
This does NOT check to see if the volume has a label. This should
not be called if the volume is already labeled.
This information is recorded below "fileDataStart". The information
consists of anchor volume descriptors, main and reserve volume
descriptor sequences, and free space information.
This does NOT write the root volume label information, and ALWAYS
uses hard-coded addresses for the locations of its descriptors,
etc.
ARGS:
Volume vol IN the volume to write nsr information to.
RETURNS: none.
PRE-CONDS: open archive object, and volumeTable[vid].fileDataStart
must be filled in.
POST-CONDS: error state may be set.
ERRORS:
error_
NOTES:
This is used solely by addUnlabeledVolume().
LEGACY DOCUMENTATION:
If this volume is the root, an integrity descriptor sequence and
file set descriptor sequence will be written. In addition, the
volume descriptor sequence will have a logical volume descriptor.
----------------------------------------------------------------------
void
NSR::Archive::writeVolumeLabel( Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeVDS(): calling writeSpaceEntry() on ErasedSpace.\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeVolumeLabel
Writes the nsr volume information.
This does NOT check to see if the volume has a label. This should
not be called if the volume is already labeled.
This information is recorded below "fileDataStart". The information
consists of anchor volume descriptors, main and reserve volume
descriptor sequences, and free space information.
This does NOT write the root volume label information, and ALWAYS
uses hard-coded addresses for the locations of its descriptors,
etc.
ARGS:
Volume vol IN the volume to write nsr information to.
RETURNS: none.
PRE-CONDS: open archive object, and volumeTable[vid].fileDataStart
must be filled in.
POST-CONDS: error state may be set.
ERRORS:
error_
NOTES:
This is used solely by addUnlabeledVolume().
LEGACY DOCUMENTATION:
If this volume is the root, an integrity descriptor sequence and
file set descriptor sequence will be written. In addition, the
volume descriptor sequence will have a logical volume descriptor.
----------------------------------------------------------------------
void
NSR::Archive::writeVolumeLabel( Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"writeFSD: fsd search at %d len:%d\n",fsdsExt.start.sector,fsdsExt.len);
}
getNextSeqAddress(vol.sid(),fsdsExt,1,&nRead,&nextBlankAddr,&lastDescNum,
&lastRecordedAddr,&needsIndirect,&bogusICBInfo);
if (err) {
if (err == error_Drive_blank_check && media == media_Worm) {
err = error_None;
}
}
if (needsIndirect) {
if (!partitionSeqAllowed) {
err = error_End_of_Sequence_space;
delete fsd;
delete [] bp;
return;
}
else {
getSeqExtent(vol.sid(),incrementalSeqSectors,fsdsExt);
if (err) {
delete fsd;
delete [] bp;
return;
}
fsd->nextExtent.extLength(fsdsExt.len);
fsd->nextExtent.logBlockNo(fsdsExt.start.sector - partStartSector);
}
}
address = nextBlankAddr;
fsd->fileSetNo = lastDescNum;
fsd->fileSetDescNo = lastDescNum + 1;
fsd->writeProtect(wrprot_Hard);
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeFSD(): writing to address %d, fileSetNo %d, fileSetDescNum %d\n",
address, (UINT32)fsd->fileSetNo, (UINT32)fsd->fileSetDescNo);
}
Write FSD
fsd->toISO( bp, address - partStartSector );
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
writeBlock( vol.sid(), address, bp );
if (err) {
delete fsd;
delete [] bp;
return;
}
Nuke in-core FSD
delete fsd;
#ifdef _FSDS_TD_
!!! Shouldn't need this, since fsdsExt is only one sector long on Rewritable.
Write a Terminating Descriptor
if (media != media_Worm) {
address++;
writeTD( vol.sid(),
address - partStartSector,
address );
if (err) {
delete [] bp;
return;
}
}
#endif _FSDS_TD_
Free buffer.
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::updateSpace --DVM
This updates the free space information on the supplied volume.
ARGS:
Volume vol IN The volume to have its space updated.
RETURNS: none.
PRE-CONDITIONS: The media must be already labeled. This is only
valid in export mode.
POST-CONDITIONS: This may set the error state.
ERRORS:
error_
error_
error_
NOTES:
This does NOT close the logical volume at all. It ONLY updates the
free space on the surface.
----------------------------------------------------------------------
void
NSR::Archive::updateSpace( const Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"writeFSD(): writing to address %d, fileSetNo %d, fileSetDescNum %d\n",
address, (UINT32)fsd->fileSetNo, (UINT32)fsd->fileSetDescNo);
}
Write FSD
fsd->toISO( bp, address - partStartSector );
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return;
}
writeBlock( vol.sid(), address, bp );
if (err) {
delete fsd;
delete [] bp;
return;
}
Nuke in-core FSD
delete fsd;
#ifdef _FSDS_TD_
!!! Shouldn't need this, since fsdsExt is only one sector long on Rewritable.
Write a Terminating Descriptor
if (media != media_Worm) {
address++;
writeTD( vol.sid(),
address - partStartSector,
address );
if (err) {
delete [] bp;
return;
}
}
#endif _FSDS_TD_
Free buffer.
delete [] bp;
return;
}
----------------------------------------------------------------------
METHOD: Archive::updateSpace --DVM
This updates the free space information on the supplied volume.
ARGS:
Volume vol IN The volume to have its space updated.
RETURNS: none.
PRE-CONDITIONS: The media must be already labeled. This is only
valid in export mode.
POST-CONDITIONS: This may set the error state.
ERRORS:
error_
error_
error_
NOTES:
This does NOT close the logical volume at all. It ONLY updates the
free space on the surface.
----------------------------------------------------------------------
void
NSR::Archive::updateSpace( const Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"updateSpace() Unerased Space (on disk):\n");
unerasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Unerased Space (in memory):\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
fprintf(Trace::logFile(),"updateSpace() Unerased Space (on disk):\n");
unerasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Unerased Space (in memory):\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
unerasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Unerased Space (in memory):\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
fprintf(Trace::logFile(),"updateSpace() Unerased Space (in memory):\n");
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
vol.freeSpace.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
fprintf(Trace::logFile(),"updateSpace() Erased Space (on disk):\n");
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
erasedOnDisk.fprint(Trace::logFile());
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
fprintf(Trace::logFile(),"updateSpace() Erased Space (in memory):\n");
vol.erasedFreeSpace.fprint(Trace::logFile());
}
Write out space table entries only if they have changed.
if ( vol.freeSpace != unerasedOnDisk ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Unerased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.freeSpace,
partAreas.unerasedSpcTblArea());
}
if ( (media != media_Worm) &&
(vol.erasedFreeSpace != erasedOnDisk) ) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"Erased space changed -- calling writeSpaceEntry()\n");
}
writeSpaceEntry(vol.sid(),ext_Allocated,
vol.erasedFreeSpace,
partAreas.erasedSpcTblArea());
}
return;
}
----------------------------------------------------------------------
METHOD: Archive::writeIntegrityEntry
Writes an integrity entry to the specified volume.
IntegrityEntries are only valid for root volumes. This is offered
to write to any volume because as volume sets are grown, the old
roots may be marked CLOSED, and should be marked as OPEN as soon
as the new root is marked as OPEN.
LVIDs vary in size based on how many partitions are in their
logical volume. This code sets the appropriate size, so that it
matches the logical volume which references it.
ARGS:
Volume & vol IN Volume to write integrity entry to.
RETURNS: none.
PRE-CONDS:
The volume must have a valid lvidsExt for this to work.
POST-CONDS:
An error may be set.
ERRORS:
error_
NOTES:
----------------------------------------------------------------------
void
NSR::Archive::writeIntegrityEntry( Volume & vol )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"icb table elist[%d] partRefNo:%d logBlockNo:%d sectors:%d\n",
i, volumeTable.vid( icbTblelist[i].start.sid),
icbTblelist[i].start.sector - partStartSector,
B2S(icbTblelist[i].len));
}
}
}
nBytesForEA += (nBytesForEA % 4) ? 4 - (nBytesForEA % 4) : 0;
eahd->applAttrLocation(nBytesForEA);
if (embeddedEAs && !isRootICB && (nBytesForEA <= fe->unusedBytes(logicalBlockSize))) {
embeddedEA = True;
if (err = fe->setEALen(logicalBlockSize,nBytesForEA)) {
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete icbea;
delete eahd;
return;
}
}
else {
embeddedEA = False;
nEASectors = 1 + B2S(nBytesForEA);
get an extent to be used in writing the eafe
getICBExtentList(eafe_offset, elist, logicalBlockSize, True);
get an extent list to be used in writing the easpace
getICBExtentList(eafe_offset+1, elistea, nBytesForEA, True);
for (int idx = 0; idx < elistea.getCount(); idx++)
{
elist.append(elistea[idx]);
}
if (elist.error()) {
err = error_Invalid_extentlist;
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete icbea;
delete eahd;
return;
}
eaicbtbl = new ICB_Table( elist, logicalBlockSize );
if (!eaicbtbl) {
err = error_No_free_store;
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete icbea;
delete eahd;
return;
}
eaicbtbl->resetPtr();
eafe = new FileEntry(elistea.getCount());
if (!eafe) {
err = error_No_free_store;
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
fill in fe->extendedAttrICB field (LongAllocDesc)
fe->extendedAttrICB.partRefNo(volumeTable.vid(sid));
fe->extendedAttrICB.logBlockNo(eaicbtbl->currentAddr().sector - partStartSector);
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"fe->extendedAttrICB.logBlockNo:%d\n",fe->extendedAttrICB.logBlockNo());
fe->extendedAttrICB.extLength(logicalBlockSize);
fe->extendedAttrICB.extType(ext_Recorded);
attr.fileType(file_ExtendedAttributes);
write the eafe (recursion - be careful)
side effects of this call:
- the eaicbtbl->bumpPtr() will be called as necessary
Extent nullExtent; Constructor makes it all empty
writeNextICB(attr,elistea,emptyTrustees,nullExtent,eaicbtbl,True);
if (err) {
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
}
set up pointer to the EA space
if (embeddedEA) {
eabp = (BYTE *)fe->embeddedEAp();
}
else {
eabp = new BYTE[S2B(B2S(nBytesForEA))];
if (!eabp) {
err = error_No_free_store;
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
memset( eabp, 0, S2B(B2S(nBytesForEA)));
}
eap = eabp;
fill in the extended attribute header descriptor
if (embeddedEA) {
eahd->toISO( eap, icbTable->currentAddr().sector - partStartSector );
}
else {
eahd->toISO( eap, eaicbtbl->currentAddr().sector - partStartSector );
}
eap += eahd->descLen();
if (icbea) {
icbea->toISO( eap );
eap += icbea->attrLen();
}
#ifdef TRUSTEES
if (ntea) {
ntea->toISO( eap );
eap += ntea->attrLen();
}
#endif TRUSTEES
if (!embeddedEA) {
writeExtents( sid, eaicbtbl, nEASectors-1, eabp);
}
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete [] eabp;
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
----------------------------------------------------------------------
METHOD: Archive::readLVIDSeq
Reads the logical volume integrity descriptor sequence.
ARGS:
Volume & vol IN volume to be checked
LogicalVolumeIntegrityDesc **lvidpp,
OUT Holds last recorded lvid.
int *nFileSets OUT Number of open->close transitions.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import & export
----------------------------------------------------------------------
void
NSR::Archive::readLVIDSeq(const Volume & vol,
LogicalVolumeIntegrityDesc **lvidpp,
int *nFileSets)
if(Trace::logAlgorithms())
fprintf(Trace::logFile(),"fe->extendedAttrICB.logBlockNo:%d\n",fe->extendedAttrICB.logBlockNo());
fe->extendedAttrICB.extLength(logicalBlockSize);
fe->extendedAttrICB.extType(ext_Recorded);
attr.fileType(file_ExtendedAttributes);
write the eafe (recursion - be careful)
side effects of this call:
- the eaicbtbl->bumpPtr() will be called as necessary
Extent nullExtent; Constructor makes it all empty
writeNextICB(attr,elistea,emptyTrustees,nullExtent,eaicbtbl,True);
if (err) {
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
}
set up pointer to the EA space
if (embeddedEA) {
eabp = (BYTE *)fe->embeddedEAp();
}
else {
eabp = new BYTE[S2B(B2S(nBytesForEA))];
if (!eabp) {
err = error_No_free_store;
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
memset( eabp, 0, S2B(B2S(nBytesForEA)));
}
eap = eabp;
fill in the extended attribute header descriptor
if (embeddedEA) {
eahd->toISO( eap, icbTable->currentAddr().sector - partStartSector );
}
else {
eahd->toISO( eap, eaicbtbl->currentAddr().sector - partStartSector );
}
eap += eahd->descLen();
if (icbea) {
icbea->toISO( eap );
eap += icbea->attrLen();
}
#ifdef TRUSTEES
if (ntea) {
ntea->toISO( eap );
eap += ntea->attrLen();
}
#endif TRUSTEES
if (!embeddedEA) {
writeExtents( sid, eaicbtbl, nEASectors-1, eabp);
}
#ifdef TRUSTEES
delete ntea;
#endif TRUSTEES
delete [] eabp;
delete eaicbtbl;
delete icbea;
delete eahd;
return;
}
----------------------------------------------------------------------
METHOD: Archive::readLVIDSeq
Reads the logical volume integrity descriptor sequence.
ARGS:
Volume & vol IN volume to be checked
LogicalVolumeIntegrityDesc **lvidpp,
OUT Holds last recorded lvid.
int *nFileSets OUT Number of open->close transitions.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import & export
----------------------------------------------------------------------
void
NSR::Archive::readLVIDSeq(const Volume & vol,
LogicalVolumeIntegrityDesc **lvidpp,
int *nFileSets)
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"readvds: sid: %d\n fsdsExt:\n",sid);
fsdsExt->fprint(Trace::logFile());
}
}
Only valid if we wrote it.
if ( (lvd->implementID.id() != NSR::ImplRegID::HPID ) &&
(lvd->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
validLVD = False;
}
Grab whether the volume is write protected or not.
if (lvWriteProtect) {
*lvWriteProtect = lvd->writeProtect();
}
delete lvd;
break;
case tag_IUVD:
iuvd = new OSTAVolumeDesc();
if (!iuvd) {
err = error_No_free_store;
delete [] bp;
return False;
}
iuvd->fromISO( bp, volDescSeqLoc + i );
if (err=iuvd->error()) {
delete iuvd;
delete [] bp;
return False;
}
if ( (iuvd->implementID.id() != NSR::ImplRegID::HPID ) &&
(iuvd->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
validIUVD = False;
}
delete iuvd;
break;
case tag_TD:
validTD = True;
break;
default:
Simply ignore any descriptors of other types.
NOT being picky -- e.g., even an FSD in the sequence
would not cause any problems
break;
}
if ( sd.type() == tag_TD ) {
break;
}
}
delete [] bp;
isHP_NSR = ( validAVD
&& validPVD
&& validPD
&& validLVD
&& validIUVD
&& validTD ) ? True : False;
return isHP_NSR;
}
----------------------------------------------------------------------
METHOD: Archive::getICBTableFromLVID --DVM
Returns True if the LVID has an ICBTable.
Sets the Archive object's error ONLY if it has trouble reading or
constructing objects.
ARGS: none
RETURNS: True if LVID has a valid ICBTable in it.
PRE-CONDITIONS: Must have a complete volume set loaded.
POST-CONDITIONS: error state may be set.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getICBTableFromLVID(void) {
Clear out any errors.
err = error_None;
Not there if on Worm (we never supported it.)
if (media == media_Worm) {
return False;
}
Create an LVID.
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
readLVIDSeq( volumeTable.rootVol(),&lvid, &nFileSets );
if (err) {
delete lvid;
return False;
}
Only closed ones count
if (lvid->integrityType() != integ_Closed) {
delete lvid;
return False;
}
Only HP LVIDs count
if ( ( lvid->implementID.id() != NSR::ImplRegID::HPID ) &&
( lvid->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
delete lvid;
return False;
}
Fill in the ICB Table if present in LVID.
Boolean foundIt( lvid->hasICBTable() );
if ( foundIt ) {
if(Trace::logAlgorithms()) fprintf(Trace::logFile(),"lvid icb table\n");
ExtentList elist;
Extent ext;
LongAllocDesc *icbt = lvid->icbTbl();
for (int j=0; j<(int)lvid->numEnts(); j++)
{
ext.start.sid = volumeTable[icbt[j].partRefNo()].sid();
ext.start.sector = icbt[j].logBlockNo() + partStartSector;
ext.len = icbt[j].extLength();
elist.append( ext );
if (err=elist.error()) {
delete lvid;
return False;
}
}
Reallocate ICBTable
delete icbTable;
icbTable = new ICB_Table( elist, logicalBlockSize );
Error if out of memory.
if (!icbTable) {
err = error_No_free_store;
delete lvid;
return foundIt;
}
Error if icbTable in error.
if (err=icbTable->error()) {
delete lvid;
return foundIt;
}
}
delete lvid;
return foundIt;
}
----------------------------------------------------------------------
METHOD: Archive::getRootICB
Gets the location of the root ICB. This works for Worm and
Rewritable
ARGS:
INT32 fsnum IN File set number to find the root ICB of.
File sets are numbered 0,1,2,...
Address &rootICB OUT Location of root ICB for fsnum.
RETURNS: False if unable to obtain a valid address.
PRE-CONDS:
POST-CONDS:
ERRORS:
The Archive::err state variable will be set if false, and NOT if
True.
NOTES:
import only. Could leave out the return value if we wanted,
since it is NOT checked, and always sets the error.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getRootICB( INT32 fsnum,Address &rootICB )
fprintf(Trace::logFile(),"readvds: sid: %d\n fsdsExt:\n",sid);
fsdsExt->fprint(Trace::logFile());
}
}
Only valid if we wrote it.
if ( (lvd->implementID.id() != NSR::ImplRegID::HPID ) &&
(lvd->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
validLVD = False;
}
Grab whether the volume is write protected or not.
if (lvWriteProtect) {
*lvWriteProtect = lvd->writeProtect();
}
delete lvd;
break;
case tag_IUVD:
iuvd = new OSTAVolumeDesc();
if (!iuvd) {
err = error_No_free_store;
delete [] bp;
return False;
}
iuvd->fromISO( bp, volDescSeqLoc + i );
if (err=iuvd->error()) {
delete iuvd;
delete [] bp;
return False;
}
if ( (iuvd->implementID.id() != NSR::ImplRegID::HPID ) &&
(iuvd->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
validIUVD = False;
}
delete iuvd;
break;
case tag_TD:
validTD = True;
break;
default:
Simply ignore any descriptors of other types.
NOT being picky -- e.g., even an FSD in the sequence
would not cause any problems
break;
}
if ( sd.type() == tag_TD ) {
break;
}
}
delete [] bp;
isHP_NSR = ( validAVD
&& validPVD
&& validPD
&& validLVD
&& validIUVD
&& validTD ) ? True : False;
return isHP_NSR;
}
----------------------------------------------------------------------
METHOD: Archive::getICBTableFromLVID --DVM
Returns True if the LVID has an ICBTable.
Sets the Archive object's error ONLY if it has trouble reading or
constructing objects.
ARGS: none
RETURNS: True if LVID has a valid ICBTable in it.
PRE-CONDITIONS: Must have a complete volume set loaded.
POST-CONDITIONS: error state may be set.
ERRORS:
error_
error_
error_
NOTES:
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getICBTableFromLVID(void) {
Clear out any errors.
err = error_None;
Not there if on Worm (we never supported it.)
if (media == media_Worm) {
return False;
}
Create an LVID.
LogicalVolumeIntegrityDesc *lvid = NULL;
int nFileSets = 0;
readLVIDSeq( volumeTable.rootVol(),&lvid, &nFileSets );
if (err) {
delete lvid;
return False;
}
Only closed ones count
if (lvid->integrityType() != integ_Closed) {
delete lvid;
return False;
}
Only HP LVIDs count
if ( ( lvid->implementID.id() != NSR::ImplRegID::HPID ) &&
( lvid->implementID.id() != NSR::ImplRegID::HPEarlyID ) ) {
delete lvid;
return False;
}
Fill in the ICB Table if present in LVID.
Boolean foundIt( lvid->hasICBTable() );
if ( foundIt ) {
if(Trace::logAlgorithms()) fprintf(Trace::logFile(),"lvid icb table\n");
ExtentList elist;
Extent ext;
LongAllocDesc *icbt = lvid->icbTbl();
for (int j=0; j<(int)lvid->numEnts(); j++)
{
ext.start.sid = volumeTable[icbt[j].partRefNo()].sid();
ext.start.sector = icbt[j].logBlockNo() + partStartSector;
ext.len = icbt[j].extLength();
elist.append( ext );
if (err=elist.error()) {
delete lvid;
return False;
}
}
Reallocate ICBTable
delete icbTable;
icbTable = new ICB_Table( elist, logicalBlockSize );
Error if out of memory.
if (!icbTable) {
err = error_No_free_store;
delete lvid;
return foundIt;
}
Error if icbTable in error.
if (err=icbTable->error()) {
delete lvid;
return foundIt;
}
}
delete lvid;
return foundIt;
}
----------------------------------------------------------------------
METHOD: Archive::getRootICB
Gets the location of the root ICB. This works for Worm and
Rewritable
ARGS:
INT32 fsnum IN File set number to find the root ICB of.
File sets are numbered 0,1,2,...
Address &rootICB OUT Location of root ICB for fsnum.
RETURNS: False if unable to obtain a valid address.
PRE-CONDS:
POST-CONDS:
ERRORS:
The Archive::err state variable will be set if false, and NOT if
True.
NOTES:
import only. Could leave out the return value if we wanted,
since it is NOT checked, and always sets the error.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getRootICB( INT32 fsnum,Address &rootICB )
if ( foundIt ) {
if(Trace::logAlgorithms()) fprintf(Trace::logFile(),"lvid icb table\n");
ExtentList elist;
Extent ext;
LongAllocDesc *icbt = lvid->icbTbl();
for (int j=0; j<(int)lvid->numEnts(); j++)
{
ext.start.sid = volumeTable[icbt[j].partRefNo()].sid();
ext.start.sector = icbt[j].logBlockNo() + partStartSector;
ext.len = icbt[j].extLength();
elist.append( ext );
if (err=elist.error()) {
delete lvid;
return False;
}
}
Reallocate ICBTable
delete icbTable;
icbTable = new ICB_Table( elist, logicalBlockSize );
Error if out of memory.
if (!icbTable) {
err = error_No_free_store;
delete lvid;
return foundIt;
}
Error if icbTable in error.
if (err=icbTable->error()) {
delete lvid;
return foundIt;
}
}
delete lvid;
return foundIt;
}
----------------------------------------------------------------------
METHOD: Archive::getRootICB
Gets the location of the root ICB. This works for Worm and
Rewritable
ARGS:
INT32 fsnum IN File set number to find the root ICB of.
File sets are numbered 0,1,2,...
Address &rootICB OUT Location of root ICB for fsnum.
RETURNS: False if unable to obtain a valid address.
PRE-CONDS:
POST-CONDS:
ERRORS:
The Archive::err state variable will be set if false, and NOT if
True.
NOTES:
import only. Could leave out the return value if we wanted,
since it is NOT checked, and always sets the error.
----------------------------------------------------------------------
NSR::Boolean
NSR::Archive::getRootICB( INT32 fsnum,Address &rootICB )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(fsnum = %d)\n",fsnum);
}
Use a local variable for return value
Boolean foundRootICB(False);
Instantiate some local variables
fsdsExt NEEDS to be value, since it will be changed.
Extent fsdsExt = volumeTable.rootVol().fsdsExt;
BYTE *bp;
Allocate the FSD
FileSetDesc *fsd = new FileSetDesc;
if (!fsd) {
return False;
}
if (media != media_Worm) {
Allocate sector-size buffer
bp = new BYTE[logicalBlockSize];
if (!bp) {
err = error_No_free_store;
delete fsd;
return False;
}
Read the fsds extent
readBlock( fsdsExt.start.sid,
fsdsExt.start.sector,
bp );
if (err) {
delete fsd;
delete [] bp;
return False;
}
Translate it from ISO.
fsd->fromISO( bp, fsdsExt.start.sector - partStartSector );
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
Save off GLOBAL state:
Set character set to be used by FIDs and PCs
(NOTE that WORM need not do this, since it never used OCU)
NSR::FileIdentifierDesc::readCSType(fsd->fileSetCharSet.charSetType());
NSR::PathComponent::readCSType(fsd->fileSetCharSet.charSetType());
Set rootICB, to be used by readRootICB()
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
Set the return value:
foundRootICB = True;
Free the buffer.
delete [] bp;
} else { Now for WORM:
Used to test for valid address at end
rootICB.sector = 0;
Need to hold the rootICB in case default fsnum is used.
Address lastRootICB;
lastRootICB.sector = 0;
----------------------------------------------
Read previous fsd's, in chunks for efficiency
----------------------------------------------
UINT32 nSectorsRead;
Boolean done = False;
while (!done)
{
---------------------------------------------
Read an extent worth of FSD Sequence
---------------------------------------------
bp = new BYTE[fsdsExt.len];
if (!bp) {
err = error_No_free_store;
delete fsd;
return False;
}
nSectorsRead = readExtent(fsdsExt, bp);
if (err) {
if ( err == error_Drive_blank_check ) {
err = error_None;
done = True;
}
else {
delete fsd;
delete [] bp;
return False;
}
}
---------------------------------------------
convert fsd's, looking for match with fsnum
---------------------------------------------
for (int j = 0; j < nSectorsRead; j++)
{
fsd->fromISO( bp + (j*logicalSectorSize),
fsdsExt.start.sector + j - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): saw fsnum=%d at sid=%d, sector=%d\n",
(UINT32)fsd->fileSetNo,
fsdsExt.start.sid,
fsdsExt.start.sector + j - partStartSector);
}
Hold on to rootICB if default fileSetNo chosen (-1)
if ( fsnum == -1) {
lastRootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
lastRootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Held-root ICB at sid=%d; sect=%d\n",
(UINT32)lastRootICB.sid,
(UINT32)lastRootICB.sector);
}
} else if (fsnum == fsd->fileSetNo) {
Break out with done==True if match
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FOUND-root ICB at sid=%d; sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
Break out with done==False if Continued
if (fsd->nextExtent.extLength()) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): Continues");
}
done = False;
break;
}
Break out with done==True if end of FSDSExtent
if ( done && (fsnum == -1) && (j==(nSectorsRead-1))) {
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): saw fsnum=%d at sid=%d, sector=%d\n",
(UINT32)fsd->fileSetNo,
fsdsExt.start.sid,
fsdsExt.start.sector + j - partStartSector);
}
Hold on to rootICB if default fileSetNo chosen (-1)
if ( fsnum == -1) {
lastRootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
lastRootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Held-root ICB at sid=%d; sect=%d\n",
(UINT32)lastRootICB.sid,
(UINT32)lastRootICB.sector);
}
} else if (fsnum == fsd->fileSetNo) {
Break out with done==True if match
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FOUND-root ICB at sid=%d; sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
Break out with done==False if Continued
if (fsd->nextExtent.extLength()) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): Continues");
}
done = False;
break;
}
Break out with done==True if end of FSDSExtent
if ( done && (fsnum == -1) && (j==(nSectorsRead-1))) {
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Held-root ICB at sid=%d; sect=%d\n",
(UINT32)lastRootICB.sid,
(UINT32)lastRootICB.sector);
}
} else if (fsnum == fsd->fileSetNo) {
Break out with done==True if match
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FOUND-root ICB at sid=%d; sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
Break out with done==False if Continued
if (fsd->nextExtent.extLength()) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): Continues");
}
done = False;
break;
}
Break out with done==True if end of FSDSExtent
if ( done && (fsnum == -1) && (j==(nSectorsRead-1))) {
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FOUND-root ICB at sid=%d; sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
Break out with done==False if Continued
if (fsd->nextExtent.extLength()) {
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): Continues");
}
done = False;
break;
}
Break out with done==True if end of FSDSExtent
if ( done && (fsnum == -1) && (j==(nSectorsRead-1))) {
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),"getRootICB(): Continues");
}
done = False;
break;
}
Break out with done==True if end of FSDSExtent
if ( done && (fsnum == -1) && (j==(nSectorsRead-1))) {
rootICB.sid = volumeTable[fsd->rootDirICB.partRefNo()].sid();
rootICB.sector = fsd->rootDirICB.logBlockNo() + partStartSector;
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): FSDSEnd-rootICB at sid=%d,sect=%d\n",
(UINT32)rootICB.sid,
(UINT32)rootICB.sector);
}
done = True;
break;
}
}
If Not done, then grab continuation extent.
if (!done) {
------------------------------
look for possible next extent
------------------------------
!!! This is a faulty algorithm -- doesn't support
!!! non-zero nextExtents in middle of sequence.
fsd->fromISO( bp + ((nSectorsRead-1)*logicalSectorSize),
fsdsExt.start.sector + nSectorsRead - 1 - partStartSector);
if (err=fsd->error()) {
delete fsd;
delete [] bp;
return False;
}
Error if not UDF or HP near-UDF
if ( ! fsd->domainID.isUDF() &&
! fsd->domainID.isEarlyHP() ) {
err = error_Non_UDF_volume_set;
delete fsd;
delete [] bp;
return False;
}
fsdsExt.start.sid = volumeTable[fsd->nextExtent.partRefNo()].sid();
fsdsExt.start.sector = fsd->nextExtent.logBlockNo() + partStartSector;
fsdsExt.len = fsd->nextExtent.extLength();
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
if(Trace::logAlgorithms()) {
fprintf(Trace::logFile(),
"getRootICB(): Continuing at sid=%d, sector=%d, len=%d\n",
(UINT32)fsdsExt.start.sid,
(UINT32)fsdsExt.start.sector,
(UINT32)fsdsExt.len);
}
if (!fsdsExt.len) {
done = True;
}
}
delete [] bp;
}
if (fsnum == -1) {
rootICB = lastRootICB;
}
foundRootICB = (rootICB.sector == 0) ? False : True;
}
Free the FSD
delete fsd;
Set the proper error if no other error encountered, but file
set not found...
if ( !foundRootICB && !err ) {
err = error_File_set_not_found;
}
Return
return foundRootICB;
}
Misc utilities to sort out volume sets...
Returns the size of the volume set, independent of how many are
missing.
NSR::UINT16
NSR::Archive::sizeVolSet( VolumeTable & vt )
---------------------------------------------------------------------
METHOD: Archive::logErrors --DVM
Enables or disables the logging of the Archive Object's error
state. Whenever a public method is exited, the error, if set, will
be printed to the log, if a logFile has been specified.
ARGS:
Boolean le IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Errors will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
void
NSR::Archive::logErrors(Boolean le) {
if (le) {
Trace::defaultError(err);
}
Trace::logErrors(le);
}
----------------------------------------------------------------------
METHOD: Archive::logAlgorithms --DVM
Enables or disables the logging of the Archive Object's
miscellaneous algorithmic output.
ARGS:
Boolean la IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Miscellaneous printf()s will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logAlgorithms(Boolean la) {
Trace::logAlgorithms(la);
}
----------------------------------------------------------------------
METHOD: Archive::logCalls --DVM
Enables or disables the logging of the entry and exit of all of
the Archive Object's public methods.
ARGS:
Boolean lc IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Entries and Exits to/from Archive Object's public methods will or
will not be logged to the logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)
}
Trace::logErrors(le);
}
----------------------------------------------------------------------
METHOD: Archive::logAlgorithms --DVM
Enables or disables the logging of the Archive Object's
miscellaneous algorithmic output.
ARGS:
Boolean la IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Miscellaneous printf()s will or will not be logged to logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logAlgorithms(Boolean la) {
Trace::logAlgorithms(la);
}
----------------------------------------------------------------------
METHOD: Archive::logCalls --DVM
Enables or disables the logging of the entry and exit of all of
the Archive Object's public methods.
ARGS:
Boolean lc IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Entries and Exits to/from Archive Object's public methods will or
will not be logged to the logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
Private comments go here - will not be extracted into HTML.
----------------------------------------------------------------------
void
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)
---------------------------------------------------------------------
METHOD: Archive::logCalls --DVM
Enables or disables the logging of the entry and exit of all of
the Archive Object's public methods.
ARGS:
Boolean lc IN True -> enables; False -> disables.
RETURNS:
void
PRE-CONDITIONS:
none.
POST-CONDITIONS:
Entries and Exits to/from Archive Object's public methods will or
will not be logged to the logFile.
ERRORS:
none.
NOTES:
This affects the static members of Trace.
----------------------------------------------------------------------
void
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)
NSR::Archive::logCalls(Boolean lc) {
Trace::logCalls(lc);
}
_PRIVATE_ Methods
----------------------------------------------------------------------
METHOD: Archive::parseEA
Decode any extended attributes associated with an ICB.
ARGS:
UINT32 eaLogicalSector, IN Logical block address of this EA.
Needed in fromISO().
UINT32 nBytesInEA, IN Number of bytes in EA.
BYTE *ea, IN Buffer containing ea info.
trustees, OUT Where to place ea info.
RETURNS:
PRE-CONDS:
POST-CONDS:
ERRORS:
error_
NOTES:
import
----------------------------------------------------------------------
void
NSR::Archive::parseEA( UINT32 eaLogicalSector, UINT32 nBytesInEA, BYTE *ea,
NetwareTrusteeInfo &trustees)