1/*
2 * Copyright (c) 2001-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23
24#ifndef _APPLELVMVOLUME_H
25#define _APPLELVMVOLUME_H
26
27#define kAppleLVMVolumeMagic		"AppleLVMVolume"
28#define kAppleLVMVolumeNextMagic	"AppleLVMVolumeNext"
29#define kAppleLVMVolumeFreeMagic	"AppleLVMVolumeFree"
30
31#define kAppleLVMVolumeOnDiskMinSize	0x1000			// 4K
32
33typedef struct AppleLVMVolumeOnDisk
34{
35    char				lvMagic[32];		// Logical Volume { Header, Next, Free }
36    UInt32				lvHeaderSize;		// total structure size 4k
37    UInt32				lvExtentsStart;		// offset to first extent (after plist)
38    UInt32				lvExtentsCount;		// number of extents (also in plist)
39    char				reserved[20];		// 32 + 4 + 4 + 4 + 20 = 64
40    char				plist[];
41} AppleLVMVolumeOnDisk;
42
43#define AppleLVMVolumeOnDiskSanityCheck()	assert(sizeof(AppleLVMVolumeOnDisk) == 64);
44
45#define ByteSwapLVMVolumeHeader(header) \
46{ \
47        (header)->lvHeaderSize		= OSSwapBigToHostInt32((header)->lvHeaderSize); \
48        (header)->lvExtentsStart	= OSSwapBigToHostInt32((header)->lvExtentsStart); \
49        (header)->lvExtentsCount	= OSSwapBigToHostInt32((header)->lvExtentsCount); \
50}	// also need to swap extents
51
52#ifdef KERNEL
53
54#define kAppleLVMSkipListSize 4		// keep even for alignment
55
56typedef struct AppleLVMLogicalExtent
57{
58    AppleLVMLogicalExtent *	skip[kAppleLVMSkipListSize];	// skip list next pointers
59    AppleLVMLogicalExtent *	lvgNext;			// global (within lvg) list
60    UInt64			lvExtentVolumeOffset;		// offset within the logical volume
61    UInt64			lvExtentSize;			// size of the extent
62
63    UInt64			lvExtentGroupOffset;		// offset within the logical volume group
64    UInt64			lvExtentMemberOffset;		// offset within the member
65    UInt32			lvMemberIndex;			// member that holds this logical extent
66} AppleLVMLogicalExtent;
67
68enum {
69    kLVMTypeConcat		=	0x1,
70    kLVMTypeStripe		=	0x2,
71    kLVMTypeMirror		=	0x4,
72    kLVMTypeIsAVolume		=	0x7,
73
74    kLVMTypeSnapRO		=	0x10,
75    kLVMTypeSnapRW		=	0x20,
76    kLVMTypeIsASnapShot		=	0x30,
77    kLVMTypeBitMap		=	0x40,
78    kLVMTypeMaster		=	0x80
79};
80
81class AppleLVMGroup;
82
83class AppleLVMVolume : public IOMedia
84{
85    OSDeclareDefaultStructors(AppleLVMVolume)
86
87 protected:
88
89    UInt32				lvIndex;		// index in LVG TOC
90    OSString *				lvUUID;
91    UInt32				lvSequenceNumber;	// must be less than lvg sequence number
92    UInt64				lvClaimedSize;		// size in header
93    UInt64				lvCalculatedSize;	// sum of extents
94    UInt32				lvTypeID;
95    UInt64				lvEntryOffset;
96    UInt32				lvEntrySize;
97
98    OSDictionary *			lvProps;
99
100    UInt64				lvExtentCount;		// how many extents
101    AppleLVMLogicalExtent *		lvExtent[kAppleLVMSkipListSize];
102
103    bool				lvPublished;
104
105    AppleLVMVolume *			lvParent;
106    AppleLVMVolume *			lvSnapShot;
107    AppleLVMVolume *			lvBitMap;
108
109 protected:
110    virtual bool init(void);
111
112    virtual AppleLVMLogicalExtent * addExtent(AppleLVMGroup * lvg, AppleRAIDExtentOnDisk * extent);
113
114 public:
115    using IOMedia::init;   // why?
116
117    static OSDictionary *   propsFromHeader(AppleLVMVolumeOnDisk * lve);
118    static AppleLVMVolume * withHeader(AppleLVMVolumeOnDisk * lve, OSDictionary * lveProps = 0);
119    virtual bool initWithHeader(OSDictionary * lveProps);
120    virtual void free();
121
122    virtual OSDictionary * getVolumeProperties(void);
123
124    // from disk only set from user space
125    virtual const OSString * getVolumeUUID(void);
126    virtual const char * getVolumeUUIDString(void);
127    virtual const OSString * getGroupUUID(void);
128    virtual const OSString * getParentUUID(void);
129    virtual const OSString * getHint(void);
130
131    inline UInt64 getClaimedSize(void)		{ return lvClaimedSize; };
132    inline UInt64 getExtentCount(void) const	{ return lvExtentCount; };
133    inline UInt32 getSequenceNumber(void) const { return lvSequenceNumber; };
134    inline UInt32 getEntrySize(void) const	{ return lvEntrySize; };
135
136    // not in lv disk properties
137    virtual const OSString * getDiskName(void);
138    inline UInt32 getIndex(void) const		{ return lvIndex; };
139    inline void setIndex(UInt32 index)		{ lvIndex = index; };
140    inline UInt64 getEntryOffset(void) const	{ return lvEntryOffset; };
141    inline void setEntryOffset(UInt64 offset)	{ lvEntryOffset = offset; };
142    inline bool isPublished(void) const		{ return lvPublished; };
143    inline void setPublished(bool published)	{ lvPublished = published; };
144
145    virtual bool addExtents(AppleLVMGroup * lvg, AppleLVMVolumeOnDisk * lve);
146    virtual bool removeExtents(AppleLVMGroup * lvg);
147    virtual AppleLVMLogicalExtent * findExtent(UInt64 offset);
148    virtual bool hasExtentsOnMember(AppleRAIDMember * member);
149    virtual bool buildExtentList(AppleRAIDExtentOnDisk * extents);
150
151    // snapshots
152
153    inline bool isAVolume(void) const		{ return (lvTypeID & kLVMTypeIsAVolume) != 0; };
154    inline bool isASnapShot(void) const		{ return (lvTypeID & kLVMTypeIsASnapShot) != 0; };
155    inline bool isABitMap(void) const		{ return (lvTypeID & kLVMTypeBitMap) != 0; };
156    inline UInt32 getTypeID(void) const		{ return lvTypeID; };
157
158    inline AppleLVMVolume * parentVolume(void) const	{ return lvParent; };
159    inline AppleLVMVolume * snapShotVolume(void) const	{ return lvSnapShot; };
160    inline AppleLVMVolume * bitMapVolume(void) const	{ return lvBitMap; };
161    virtual bool setParent(AppleLVMVolume * parent);
162    virtual bool setSnapShot(AppleLVMVolume * snapshot);
163    virtual bool setBitMap(AppleLVMVolume * bitmap);
164
165    virtual bool zeroVolume(void);
166};
167
168#endif KERNEL
169
170#endif _APPLELVMVOLUME_H
171