📄 volume.hxx
字号:
#ifndef __VOLUME_HXX__#define __VOLUME_HXX__/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <disk/LowVolume.hxx>#include <disk/ErosTypes.h>#include <disk/DiskCkpt.hxx>#include <disk/PagePot.hxx>#include <erosimg/Intern.hxx>#include <eros/Reserve.h>/* EROS volume structure. EROS volumes contain: * * 1. A Boot Page (Page 0: must be error free) * 2. A Division Table (Page 1: must be error free) * 3. A spare sector region * 3. Other divisions as defined by the user *//* In principle, these classes probably ought to live in distinct * header files. In practice, there is essentially nothing you can do * with a volume unless you have the division table and the bad map * table. Rather than keep the relationships in multiple files, it * seemed better to put them all in one place. */class DiskNode;class DiskKey;class BigNum;class PagePot;class DiskDescrip;class ExecImage;struct DiskCheckpoint;struct CkptDirent;class Volume { int working_fd; int target_fd; VolHdr volHdr; int needSyncHdr; int needSyncCkptLog; Division divTable[NDIVENT]; int topDiv; lid_t topLogLid; lid_t lastAvailLogLid; lid_t firstAvailLogLid; /* Managing the volume's checkpoint directory is a pain in the * butt. The current logic works fine for creating new volumes and * for post-morten examination of existing volumes, and can be used * to rewrite the content of an existing page or cgroup on an * existing volume. Unless we want to do a lot more bookkeeping, * though, adding a new cgroup or page to an existing ckpt log won't * work. */ bool rewriting; DiskCheckpoint *dskCkptHdr0; DiskCheckpoint *dskCkptHdr1;public: DiskCheckpoint *curDskCkpt; DiskCheckpoint *oldDskCkpt;private: struct CpuReserveInfo *reserveTable; ThreadDirent* threadDir; uint32_t nThreadDirent; uint32_t maxThreadDirent; CkptDirent* ckptDir; uint32_t maxCkptDirent; uint32_t nCkptDirent; void LoadLogHeaders(); void LoadLogDirectory(); void GrowCkptDir(); void GrowThreadDir(); void AddDirent(OID oid, ObCount count, lid_t lid, uint8_t ckObType); ThreadDirent *LookupThread(OID oid); CkptDirent *LookupObject(OID oid); lid_t curLogPotLid; lid_t AllocLogPage(); lid_t AllocLogDirPage(); bool divNeedsInit[NDIVENT]; bool needDivInit; bool needSyncDivisions; /* volume read/write routines: */ bool Read(uint32_t pos, void *buf, uint32_t sz); bool Write(uint32_t pos, const void *buf, uint32_t sz); /* Each of these operates within the given division, and returns the * BYTE offset IN THE VOLUME of the page in that division. It is * the caller's responsibility to have already determined if the * division is of suitable type and contains the requested OID. */ bool ValidOid(int ndx, const OID& oid); uint32_t GetLogFrameVolOffset(int div, const OID& loc); uint32_t GetOidFrameVolOffset(int div, const OID& oid); uint32_t GetOidPagePotVolOffset(int div, const OID& oid); uint32_t GetOidVolOffset(int div, const OID& oid); /* Compressed volume support functions: */ uint32_t fill_input(struct z_stream_s& z, int fd, uint32_t len); void flush_output(struct z_stream_s& z, int fd); int DecompressTarget(); int CompressTarget();public: void WriteBootImage(const char*);private: void WriteVolHdr(); void SyncHdr(); void SyncDivTables(); void SyncCkptLog(); bool FormatNodeFrame(int div, OID oid); bool FormatProcessFrame(int div, OID oid); void ZeroDivision(int ndx); void FormatObjectDivision(int ndx); void FormatLogDivision(int ndx); void InitDivisions(); void InitVolume(); int AddAdjustableDivision(DivType, uint32_t sz); int AddFixedDivision(DivType, uint32_t start, uint32_t sz); int DoAddDivision(DivType, uint32_t start, uint32_t sz); /* offset is in bytes relative to start of division */ void WriteImageAtDivisionOffset(int div, const ExecImage& image, uint32_t offset); bool WriteNodeToLog(const OID& oid, const DiskNode& node);public: Volume(); ~Volume(); int Create(const char* filename, const char* bootImage); int Open(const char* filename, bool forRewriting); void Close(); /* For use by sysgen: */ void ResetVolume(); /* Division management logic: */ int AddDivision(DivType, uint32_t sz); int AddDivision(DivType, uint32_t sz, const OID& startOid);#if 0 int AddFailStart(OID& oid);#endif void DelDivision(int ndx); uint32_t DivisionSetFlags(int ndx, uint32_t flags); uint32_t DivisionClearFlags(int ndx, uint32_t flags); uint32_t GetDivisionFlags(int ndx); void WriteKernelImage(int div, const ExecImage& image); int MaxDiv() { return topDiv; }#ifdef DEAD_BAD_MAP int MaxBadEnt() { return topBadEnt; }#endif const Division& GetDivision(int i) { return divTable[i]; } const VolHdr& GetVolHdr() { return volHdr; }#ifdef DEAD_BAD_MAP const BadEnt& GetBadEnt(int i) { return badmap[i]; }#endif bool ReadLogPage(const lid_t lid, uint8_t* buf); bool WriteLogPage(const lid_t lid, const uint8_t* buf); /* object I/O. All of this assumes allocation/call count of 0! */ bool ReadDataPage(const OID& oid, uint8_t* buf); bool WriteDataPage(const OID& oid, const uint8_t* buf); bool ReadNode(const OID& oid, DiskNode& node); bool WriteNode(const OID& oid, const DiskNode& node); struct VolPagePot { ObCount count; uint8_t type; }; bool GetPagePotInfo(const OID& oid, VolPagePot&);private: bool ReadPagePotEntry(const OID& oid, VolPagePot&); bool WritePagePotEntry(const OID& oid, const VolPagePot&);public: bool ContainsPage(const OID& oid); bool ContainsNode(const OID& oid); void SetVolFlag(VolHdr::Flags); void ClearVolFlag(VolHdr::Flags); void SetIplSysId(uint64_t dw); void SetIplKey(const DiskKey& key); bool AddThread(const OID& oid, ObCount count, uint16_t rsrvNdx); void SetReserve(const CpuReserveInfo& rsrv); CpuReserveInfo GetReserve(uint32_t ndx); uint32_t NumDirent() { return nCkptDirent; } uint32_t NumThread() { return nThreadDirent; } uint32_t NumReserve() { return MAX_CPU_RESERVE; } CkptDirent GetDirent(uint32_t ndx) { return ckptDir[ndx]; } ThreadDirent GetThread(uint32_t ndx) { return threadDir[ndx]; }};#endif /* __VOLUME_HXX__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -