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#include "AppleRAID.h" 24 25#define super AppleRAIDStorageRequest 26OSDefineMetaClassAndStructors(AppleLVMStorageRequest, AppleRAIDStorageRequest); 27 28 29AppleLVMStorageRequest * AppleLVMStorageRequest::withAppleRAIDSet(AppleRAIDSet *set) 30{ 31 AppleLVMStorageRequest *storageRequest = new AppleLVMStorageRequest; 32 33 if (storageRequest != 0) { 34 if (!storageRequest->initWithAppleRAIDSet(set)) { 35 storageRequest->release(); 36 storageRequest = 0; 37 } 38 } 39 40 return storageRequest; 41} 42 43 44void AppleLVMStorageRequest::read(IOService *client, UInt64 byteStart, IOMemoryDescriptor *buffer, 45 IOStorageAttributes *attributes, IOStorageCompletion *completion) 46{ 47 AppleRAIDMember *member; 48 IOStorageCompletion storageCompletion; 49 AppleRAIDMemoryDescriptor *memoryDescriptor; 50 51 srClient = client; 52 srClientsCompletion = *completion; 53 srCompletedCount = 0; 54 srMemoryDescriptor = buffer; 55 srMemoryDescriptorDirection = buffer->getDirection(); 56 srByteCount = buffer->getLength(); 57 srByteStart = byteStart; 58 59 storageCompletion.target = srEventSource; 60 storageCompletion.action = srEventSource->getStorageCompletionActionLVG(); 61 62 // only handle lv 63 AppleLVMVolume * lv = OSDynamicCast(AppleLVMVolume, client); 64 if (!lv) { 65 IOLog("AppleLVMStorageRequest::read() received a non-lvm request?\n"); 66 IOStorage::complete(completion, kIOReturnInternalError, 0); 67 return; 68 } 69 70 // XXXSNAP 71 if (lv->getTypeID() == kLVMTypeSnapRO) { 72 lv = lv->parentVolume(); // XXX hack 73 assert(lv); 74 } 75 76 /* 77 each storage request has a fixed number of descriptors, if we need more than 78 that just recycle the current storage request (this) 79 */ 80 81 UInt64 requestSize = srByteCount; 82 UInt64 requestStart = srByteStart; 83 UInt32 requestCountMax = srRAIDSet->getMaxRequestCount(); 84 srRequestCount = 0; 85 86 IOLogRW(" lvm read (%u) requestStart %llu requestSize %llu\n", (uint32_t)srRequestCount, requestStart, requestSize); 87 88 while (requestSize && srRequestCount < requestCountMax) { 89 90 memoryDescriptor = srMemoryDescriptors[srRequestCount]; 91 assert(memoryDescriptor); 92 93 if (!memoryDescriptor->configureForMemoryDescriptor(buffer, requestStart, requestSize, lv)) { 94 95 IOLog(" lvm read configure failed\n"); 96 97 // XXX set length to zero? 98 99 break; 100 } 101 102 requestStart += memoryDescriptor->getLength(); 103 requestSize -= memoryDescriptor->getLength(); 104 srRequestCount++; 105 106 IOLogRW(" lvm read (%u) requestStart %llu requestSize %llu\n", (uint32_t)srRequestCount, requestStart, requestSize); 107 } 108 109 if (requestSize) { 110 111 if (srRequestCount < requestCountMax) { 112 113 // XXX something went very wrong 114 115 IOLog(" lvm read failed #1, srByteStart %llu srByteCount %llu srRequestCount %u requestStart %llu requestSize %llu\n", 116 srByteStart, srByteCount, (uint32_t)srRequestCount, requestStart, requestSize); 117 118 IOStorage::complete(completion, kIOReturnInternalError, 0); 119 return; 120 } 121 122 // XXX set storageCompletion to reschedule more i/o; 123 // srBytesScheduled ?? 124 125 IOLog(" lvm read failed #2, srByteStart %llu srByteCount %llu srRequestCount %u requestStart %llu requestSize %llu\n", 126 srByteStart, srByteCount, (uint32_t)srRequestCount, requestStart, requestSize); 127 128 IOStorage::complete(completion, kIOReturnInternalError, 0); 129 return; 130 } 131 132 assert(srMemberBaseOffset == 0); 133 134 // second pass, kick off the i/o's if device exists 135 136 UInt32 i; 137 for (i=0; i < srRequestCount; i++) { 138 139 memoryDescriptor = srMemoryDescriptors[i]; 140 storageCompletion.parameter = memoryDescriptor; 141 142 member = srRAIDSet->arMembers[memoryDescriptor->mdMemberIndex]; 143 144 if (member) { 145 storageCompletion.parameter = memoryDescriptor; 146 member->read(srRAIDSet, memoryDescriptor->mdMemberByteStart, memoryDescriptor, attributes, &storageCompletion); 147 } else { 148 srEventSource->completeRequest(memoryDescriptor, kIOReturnSuccess, 0); // no bytes & no error in completion 149 } 150 } 151} 152 153 154// XXX the read and write code is almost the same, could merge them together? 155 156 157void AppleLVMStorageRequest::write(IOService * client, UInt64 byteStart, IOMemoryDescriptor *buffer, 158 IOStorageAttributes *attributes, IOStorageCompletion *completion) 159{ 160 AppleRAIDMember *member; 161 IOStorageCompletion storageCompletion; 162 AppleRAIDMemoryDescriptor *memoryDescriptor; 163 164 srClient = client; 165 srClientsCompletion = *completion; 166 srCompletedCount = 0; 167 srMemoryDescriptor = buffer; 168 srMemoryDescriptorDirection = buffer->getDirection(); 169 srByteCount = buffer->getLength(); 170 srByteStart = byteStart; 171 172 storageCompletion.target = srEventSource; 173 storageCompletion.action = srEventSource->getStorageCompletionActionLVG(); 174 175 // only handle lv 176 AppleLVMVolume * lv = OSDynamicCast(AppleLVMVolume, client); 177 if (!lv) { 178 IOLog("AppleLVMStorageRequest::write() received a non-lvm request?\n"); 179 IOStorage::complete(completion, kIOReturnInternalError, 0); 180 return; 181 } 182 183 // XXXSNAP 184 if (lv->getTypeID() == kLVMTypeSnapRO) { 185 lv = lv->parentVolume(); // XXX hack 186 assert(lv); 187 } 188 189 /* 190 each storage request has a fixed number of descriptors, if we need more than 191 that just recycle the current storage request (this) 192 */ 193 194 UInt64 requestSize = srByteCount; 195 UInt64 requestStart = srByteStart; 196 UInt32 requestCountMax = srRAIDSet->getMaxRequestCount(); 197 srRequestCount = 0; 198 199 IOLogRW(" lvm write (%u) requestStart %llu requestSize %llu\n", (uint32_t)srRequestCount, requestStart, requestSize); 200 201 while (requestSize && srRequestCount < requestCountMax) { 202 203 memoryDescriptor = srMemoryDescriptors[srRequestCount]; 204 assert(memoryDescriptor); 205 206 if (!memoryDescriptor->configureForMemoryDescriptor(buffer, requestStart, requestSize, lv)) { 207 208 IOLog(" lvm write configure failed\n"); 209 210 // XXX set length to zero? 211 212 break; 213 } 214 215 requestStart += memoryDescriptor->getLength(); 216 requestSize -= memoryDescriptor->getLength(); 217 srRequestCount++; 218 219 IOLogRW(" lvm write (%u) requestStart %llu requestSize %llu\n", (uint32_t)srRequestCount, requestStart, requestSize); 220 } 221 222 if (requestSize) { 223 224 if (srRequestCount < requestCountMax) { 225 226 // XXX something went very wrong 227 228 IOLog(" lvm write failed #1, srByteStart %llu srByteCount %llu srRequestCount %u requestStart %llu requestSize %llu\n", 229 srByteStart, srByteCount, (uint32_t)srRequestCount, requestStart, requestSize); 230 231 IOStorage::complete(completion, kIOReturnInternalError, 0); 232 return; 233 } 234 235 // XXX set storageCompletion to reschedule more i/o; 236 // srBytesScheduled ?? 237 238 IOLog(" lvm write failed #2, srByteStart %llu srByteCount %llu srRequestCount %u requestStart %llu requestSize %llu\n", 239 srByteStart, srByteCount, (uint32_t)srRequestCount, requestStart, requestSize); 240 241 IOStorage::complete(completion, kIOReturnInternalError, 0); 242 return; 243 } 244 245// IOLog(" lvm write extent %p offset %llu byteStart %llu\n", extent, extent->lvExtentGroupOffset, srByteStart); 246 247 assert(srMemberBaseOffset == 0); 248 249 // second pass, kick off the i/o's if device exists 250 251 UInt32 i; 252 for (i=0; i < srRequestCount; i++) { 253 254 memoryDescriptor = srMemoryDescriptors[i]; 255 storageCompletion.parameter = memoryDescriptor; 256 257 member = srRAIDSet->arMembers[memoryDescriptor->mdMemberIndex]; 258 259 if (member) { 260 storageCompletion.parameter = memoryDescriptor; 261 member->write(srRAIDSet, memoryDescriptor->mdMemberByteStart, memoryDescriptor, attributes, &storageCompletion); 262 } else { 263 srEventSource->completeRequest(memoryDescriptor, kIOReturnSuccess, 0); // no bytes & no error in completion 264 } 265 } 266} 267