// IfsBackupUtil.bcpl -- Utilities for backup process // Copyright Xerox Corporation 1979, 1981, 1982 // Last modified September 17, 1982 10:47 AM by Taft get "Ifs.decl" get "IfsFiles.decl" get "IfsBackup.decl" get "IfsDirs.decl" get "BTree.decl" external [ // outgoing procedures BackupIFSDir // incoming procedures CopyFile; EmptiestFreePages; GetDiskFromFD; GetBufferForFD LookupIFSFile; LookupFD; CreateFD; NextFD; DestroyFD; UnlockDirFD TransferLeaderPage; CreateIFSFile; IFSDeleteOldVersions FlushBTreeState; FlushBuffers; IFSError SysAllocate; SysFree ] //--------------------------------------------------------------------------- let BackupIFSDir(fs, backupFS) = valof //--------------------------------------------------------------------------- // Backs up IFS.Dir from fs onto the next higher version of // BackupIFS.Dir on backupFS, then deletes all previous versions. // Returns true normally and false if the backup file system is full. [ let ec = nil // Lookup IFS.Dir in fs and read-lock the directory // so it can't change out from under us. let fd = LookupIFSFile("IFS.Dir!1", 0, lv ec, fs) if fd eq 0 then IFSError(ecCantFindIFSDir, ec) LookupFD(fd, lockRead) FlushBTreeState() //ensure disk state is consistent FlushBuffers(true) // Ensure there is enough room in the backup file system. let pages = fs>>IFS.dirBTree>>TREE.GreatestPage+2 if EmptiestFreePages(backupFS) uls pages+100 then [ UnlockDirFD(fd); DestroyFD(fd); resultis false ] // Create next higher version of backup directory file let backupName = "BackupIFS.Dir" let backupFD = CreateFD(backupName, lcVNext+lcCreate, lv ec, backupFS) if backupFD ne 0 then ec = LookupFD(backupFD, lockWrite) if ec ne 0 then IFSError(ecBackupLookupFile, ec) let buf = GetBufferForFD(backupFD) TransferLeaderPage(fd, buf) buf>>ILD.undeletable = false ec = CreateIFSFile(backupFD, buf) if ec ne 0 then IFSError(ecBackupCreateFile, ec) UnlockDirFD(backupFD) SysFree(buf) //don't hold on to buf across CopyFile call // Actually copy the file to the backup disk CopyFile(GetDiskFromFD(backupFD), lv backupFD>>FD.dr>>DR.fp, GetDiskFromFD(fd), lv fd>>FD.dr>>DR.fp, 0, pages, true) // Unlock primary directory and clean up UnlockDirFD(fd) DestroyFD(fd) DestroyFD(backupFD) // Delete obsolete versions of BackupIFS.Dir IFSDeleteOldVersions(backupName, 0, backupFS) resultis true ]