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 _APPLELVMGROUP_H
25#define _APPLELVMGROUP_H
26
27#define kAppleRAIDLevelNameLVG "LVG"
28
29// The LVG TOC is part of the primary meta data and is duplicated across all disks.
30// The primary meta data has a sequence number as do the logical volume enties
31// and the raid header.  The order of writing these out should be first the logical
32// volume entry, then the table of contents and finally the raid header.  Any structure
33// with sequence number that is higher than a raid header sequence number can be
34// assumed to be part of a failed update to the logical volume group.
35
36typedef struct AppleLVGTOCEntryOnDisk {
37
38    char			lveUUID[64];		// XXX lve -> toc
39    UInt64			lveVolumeSize;
40    UInt64			lveEntryOffset;
41    UInt64			lveEntrySize;
42    char			reserved[40];		// 64 + 8 + 8 + 8 + 40 = 128
43
44} AppleLVGTOCEntryOnDisk;
45
46#define AppleLVGTOCEntrySanityCheck()	assert(sizeof(AppleLVGTOCEntryOnDisk) == 128);
47
48#define ByteSwapLVGTOCEntry(entry) \
49{ \
50        (entry)->lveVolumeSize		= OSSwapBigToHostInt64((entry)->lveVolumeSize); \
51        (entry)->lveEntryOffset		= OSSwapBigToHostInt64((entry)->lveEntryOffset); \
52        (entry)->lveEntrySize		= OSSwapBigToHostInt32((entry)->lveEntrySize); \
53}
54
55#ifdef KERNEL
56
57
58class AppleLVMGroup : public AppleRAIDSet
59{
60    OSDeclareDefaultStructors(AppleLVMGroup);
61
62    friend class AppleRAIDStorageRequest;
63
64 private:
65    UInt64 *				arMemberBlockCounts;
66    UInt64 *				arMemberStartingOffset;
67    AppleLVMVolume **			arMetaDataVolumes;
68    UInt32				arExpectingLiveAdd;
69
70    bool				arPrimaryNeedsUpdate;
71    IOBufferMemoryDescriptor *		arPrimaryBuffer;
72    UInt32				arLogicalVolumeCount;
73    UInt32				arLogicalVolumeActiveCount;
74    AppleLVMVolume **			arLogicalVolumes;
75
76    UInt64				arExtentCount;
77    AppleLVMLogicalExtent *		arExtents;
78
79 protected:
80    virtual bool init();
81    virtual void free();
82
83    virtual void unpauseSet(void);
84    virtual bool updateLVGTOC(void);
85    virtual UInt64 findFreeLVEOffset(AppleLVMVolume * newLV);
86
87 public:
88    static AppleRAIDSet * createRAIDSet(AppleRAIDMember * firstMember);
89    virtual bool addSpare(AppleRAIDMember * member);
90    virtual bool addMember(AppleRAIDMember * member);
91    virtual bool removeMember(AppleRAIDMember * member, IOOptionBits options);
92
93    virtual bool resizeSet(UInt32 newMemberCount);
94    virtual bool startSet(void);
95    virtual bool publishSet(void);
96    virtual bool unpublishSet(void);
97    virtual bool handleOpen(IOService * client, IOOptionBits options, void * access);
98
99    virtual UInt32 getMaxRequestCount(void) const { return 16; };   // XXX 32bit / min lv size + 1
100
101    virtual UInt64 getMemberSize(UInt32 memberIndex) const;
102    virtual UInt64 getMemberStartingOffset(UInt32 memberIndex) const;
103    virtual UInt32 getMemberIndexFromOffset(UInt64 offset) const;
104    virtual bool memberOffsetFromLVGOffset(UInt64 lvgOffset, AppleRAIDMember ** member, UInt64 * memberOffset);
105    virtual OSDictionary * getSetProperties(void);
106
107    virtual AppleRAIDMemoryDescriptor * allocateMemoryDescriptor(AppleRAIDStorageRequest *storageRequest, UInt32 memberIndex);
108
109    // LVG stuff
110
111    virtual IOBufferMemoryDescriptor * readPrimaryMetaData(AppleRAIDMember * member);
112    virtual IOReturn writePrimaryMetaData(IOBufferMemoryDescriptor * primaryBuffer);
113
114    virtual IOBufferMemoryDescriptor * readLogicalVolumeEntry(UInt64 offset, UInt32 size);
115    virtual IOReturn writeLogicalVolumeEntry(IOBufferMemoryDescriptor * lveBuffer, UInt64 offset);
116    virtual bool clearLogicalVolumeEntry(UInt64 offset, UInt32 size);
117
118    virtual bool initializeSecondary(void);
119    virtual bool addExtentToLVG(AppleLVMLogicalExtent * newExtent);
120    virtual bool removeExtentFromLVG(AppleLVMLogicalExtent * extent);
121    virtual bool buildExtentList(AppleRAIDExtentOnDisk * onDiskExtent);
122    virtual UInt64 calculateFreeSpace(void);
123
124    inline UInt64 getExtentCount(void) const	{ return arExtentCount; };
125
126    virtual bool addLogicalVolumeToTOC(AppleLVMVolume * lv);
127    virtual bool removeLogicalVolumeFromTOC(AppleLVMVolume * lv);
128    virtual OSArray * buildLogicalVolumeListFromTOC(AppleRAIDMember * member);
129    virtual bool initializeVolumes(AppleRAIDPrimaryOnDisk * primary);
130
131    virtual IOReturn createLogicalVolume(OSDictionary * lveProps, AppleLVMVolumeOnDisk * lvOnDisk);
132    virtual IOReturn updateLogicalVolume(AppleLVMVolume * lv, OSDictionary * lveProps, AppleLVMVolumeOnDisk * lve);
133    virtual IOReturn destroyLogicalVolume(AppleLVMVolume * lv);
134
135    virtual bool publishVolume(AppleLVMVolume * lv);
136    virtual bool unpublishVolume(AppleLVMVolume * lv);
137
138    virtual void completeRAIDRequest(AppleRAIDStorageRequest * storageRequest);
139};
140
141
142
143class AppleLVMMemoryDescriptor : public AppleRAIDMemoryDescriptor
144{
145    OSDeclareDefaultStructors(AppleLVMMemoryDescriptor);
146
147    friend class AppleRAIDEventSource;		// XXX remove this
148    friend class AppleLVMGroup;			// XXX remove this
149
150 private:
151    UInt64		mdRequestIndex;
152    IOByteCount		mdRequestOffset;
153
154 protected:
155    virtual bool initWithStorageRequest(AppleRAIDStorageRequest * storageRequest, UInt32 requestIndex);
156    virtual bool configureForMemoryDescriptor(IOMemoryDescriptor * memoryDescriptor, UInt64 requestStart, UInt64 requestSize, AppleLVMVolume * lv);
157
158 public:
159    static AppleRAIDMemoryDescriptor * withStorageRequest(AppleRAIDStorageRequest * storageRequest, UInt32 memberIndex);
160    virtual addr64_t getPhysicalSegment(IOByteCount offset, IOByteCount * length, IOOptionBits options = 0);
161};
162
163
164#endif KERNEL
165
166#endif /* ! _APPLELVMGROUP_H */
167