AppleLVMVolume.h   [plain text]


/*
 * Copyright (c) 2001-2007 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 *
 * The contents of this file constitute Original Code as defined in and
 * are subject to the Apple Public Source License Version 1.1 (the
 * "License").  You may not use this file except in compliance with the
 * License.  Please obtain a copy of the License at
 * http://www.apple.com/publicsource and read it before using this file.
 *
 * This Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * @APPLE_LICENSE_HEADER_END@
 */


#ifndef _APPLELVMVOLUME_H
#define _APPLELVMVOLUME_H

#define kAppleLVMVolumeMagic		"AppleLVMVolume"
#define kAppleLVMVolumeNextMagic	"AppleLVMVolumeNext"
#define kAppleLVMVolumeFreeMagic	"AppleLVMVolumeFree"

#define kAppleLVMVolumeOnDiskMinSize	0x1000			// 4K

typedef struct AppleLVMVolumeOnDisk
{
    char				lvMagic[32];		// Logical Volume { Header, Next, Free }
    UInt32				lvHeaderSize;		// total structure size 4k
    UInt32				lvExtentsStart;		// offset to first extent (after plist)
    UInt32				lvExtentsCount;		// number of extents (also in plist)
    char				reserved[20];		// 32 + 4 + 4 + 4 + 20 = 64
    char				plist[];
} AppleLVMVolumeOnDisk;

#define AppleLVMVolumeOnDiskSanityCheck()	assert(sizeof(AppleLVMVolumeOnDisk) == 64);

#define ByteSwapLVMVolumeHeader(header) \
{ \
        (header)->lvHeaderSize		= OSSwapBigToHostInt32((header)->lvHeaderSize); \
        (header)->lvExtentsStart	= OSSwapBigToHostInt32((header)->lvExtentsStart); \
        (header)->lvExtentsCount	= OSSwapBigToHostInt32((header)->lvExtentsCount); \
}	// also need to swap extents

#ifdef KERNEL

#define kAppleLVMSkipListSize 4		// keep even for alignment

typedef struct AppleLVMLogicalExtent
{
    AppleLVMLogicalExtent *	skip[kAppleLVMSkipListSize];	// skip list next pointers
    AppleLVMLogicalExtent *	lvgNext;			// global (within lvg) list
    UInt64			lvExtentVolumeOffset;		// offset within the logical volume
    UInt64			lvExtentSize;			// size of the extent

    UInt64			lvExtentGroupOffset;		// offset within the logical volume group
    UInt64			lvExtentMemberOffset;		// offset within the member
    UInt32			lvMemberIndex;			// member that holds this logical extent
} AppleLVMLogicalExtent;

enum {
    kLVMTypeConcat		=	0x1,
    kLVMTypeStripe		=	0x2,
    kLVMTypeMirror		=	0x4,
    kLVMTypeIsAVolume		=	0x7,
    
    kLVMTypeSnapRO		=	0x10,
    kLVMTypeSnapRW		=	0x20,
    kLVMTypeIsASnapShot		=	0x30,
    kLVMTypeBitMap		=	0x40,
    kLVMTypeMaster		=	0x80
};

class AppleLVMGroup;

class AppleLVMVolume : public IOMedia
{
    OSDeclareDefaultStructors(AppleLVMVolume)
	
 protected:

    UInt32				lvIndex;		// index in LVG TOC
    OSString *				lvUUID;			
    UInt32				lvSequenceNumber;	// must be less than lvg sequence number
    UInt64				lvClaimedSize;		// size in header
    UInt64				lvCalculatedSize;	// sum of extents
    UInt32				lvTypeID;
    UInt64				lvEntryOffset;
    UInt32				lvEntrySize;

    OSDictionary *			lvProps;

    UInt64				lvExtentCount;		// how many extents
    AppleLVMLogicalExtent *		lvExtent[kAppleLVMSkipListSize];

    bool				lvPublished;

    AppleLVMVolume *			lvParent;
    AppleLVMVolume *			lvSnapShot;
    AppleLVMVolume *			lvBitMap;
    
 protected:
    virtual bool init(void);

    virtual AppleLVMLogicalExtent * addExtent(AppleLVMGroup * lvg, AppleRAIDExtentOnDisk * extent);

 public:
    using IOMedia::init;   // why?  
    
    static OSDictionary *   propsFromHeader(AppleLVMVolumeOnDisk * lve);
    static AppleLVMVolume * withHeader(AppleLVMVolumeOnDisk * lve, OSDictionary * lveProps = 0);
    virtual bool initWithHeader(OSDictionary * lveProps);
    virtual void free();

    virtual OSDictionary * getVolumeProperties(void);
    
    // from disk only set from user space
    virtual const OSString * getVolumeUUID(void);
    virtual const char * getVolumeUUIDString(void);
    virtual const OSString * getGroupUUID(void);
    virtual const OSString * getParentUUID(void);
    virtual const OSString * getHint(void);

    inline UInt64 getClaimedSize(void)		{ return lvClaimedSize; };
    inline UInt64 getExtentCount(void) const	{ return lvExtentCount; };
    inline UInt32 getSequenceNumber(void) const { return lvSequenceNumber; };
    inline UInt32 getEntrySize(void) const	{ return lvEntrySize; };

    // not in lv disk properties
    virtual const OSString * getDiskName(void);
    inline UInt32 getIndex(void) const		{ return lvIndex; };
    inline void setIndex(UInt32 index)		{ lvIndex = index; };
    inline UInt64 getEntryOffset(void) const	{ return lvEntryOffset; };
    inline void setEntryOffset(UInt64 offset)	{ lvEntryOffset = offset; };
    inline bool isPublished(void) const		{ return lvPublished; };
    inline void setPublished(bool published)	{ lvPublished = published; };

    virtual bool addExtents(AppleLVMGroup * lvg, AppleLVMVolumeOnDisk * lve);
    virtual bool removeExtents(AppleLVMGroup * lvg);
    virtual AppleLVMLogicalExtent * findExtent(UInt64 offset);
    virtual bool hasExtentsOnMember(AppleRAIDMember * member);
    virtual bool buildExtentList(AppleRAIDExtentOnDisk * extents);

    // snapshots

    inline bool isAVolume(void) const		{ return (lvTypeID & kLVMTypeIsAVolume) != 0; };
    inline bool isASnapShot(void) const		{ return (lvTypeID & kLVMTypeIsASnapShot) != 0; };
    inline bool isABitMap(void) const		{ return (lvTypeID & kLVMTypeBitMap) != 0; };
    inline UInt32 getTypeID(void) const		{ return lvTypeID; };

    inline AppleLVMVolume * parentVolume(void) const	{ return lvParent; };
    inline AppleLVMVolume * snapShotVolume(void) const	{ return lvSnapShot; };
    inline AppleLVMVolume * bitMapVolume(void) const	{ return lvBitMap; };
    virtual bool setParent(AppleLVMVolume * parent);
    virtual bool setSnapShot(AppleLVMVolume * snapshot);
    virtual bool setBitMap(AppleLVMVolume * bitmap);

    virtual bool zeroVolume(void);
};

#endif KERNEL

#endif _APPLELVMVOLUME_H