vdev_disk.c revision f4565e39fe75b2c28258c16bc697741760935002
1N/A * The contents of this file are subject to the terms of the 1N/A * Common Development and Distribution License (the "License"). 1N/A * You may not use this file except in compliance with the License. 1N/A * See the License for the specific language governing permissions 1N/A * and limitations under the License. 1N/A * When distributing Covered Code, include this CDDL HEADER in each 1N/A * If applicable, add the following below this CDDL HEADER, with the 1N/A * fields enclosed by brackets "[]" replaced with your own identifying 1N/A * information: Portions Copyright [yyyy] [name of copyright owner] 1N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 1N/A * Use is subject to license terms. 1N/A * Virtual device vector for disks. 1N/A * We must have a pathname, and it must be absolute. 1N/A * When opening a disk device, we want to preserve the user's original 1N/A * intent. We always want to open the device by the path the user gave 1N/A * us, even if it is one of multiple paths to the save device. But we 1N/A * Therefore the sequence of opening devices is: 1N/A * 1. Try opening the device by path. For legacy pools without the 1N/A * 'whole_disk' property, attempt to fix the path by appending 's0'. * 2. If the devid of the device matches the stored value, return * 3. Otherwise, the device may have moved. Try opening the device * If the vdev is part of the root pool, we avoid opening it by path. * We do this because there is no /dev path available early in boot, * and if we try to open the device by path at a later point, we can * deadlock when devfsadm attempts to open the underlying backing store * Compare the devid to the stored value. * If we succeeded in opening the device, but 'vdev_wholedisk' * is not yet set, then this must be a slice. * If we were unable to open by path, or the devid check fails, open by * If all else fails, then try opening by physical path (if available) * or the logical path (if we failed due to the devid check). While not * as reliable as the devid, this will give us something, and the higher * level vdev validation will prevent us from opening the wrong device. * Note that we don't support the legacy auto-wholedisk support * as above. This hasn't been used in a very long time and we * don't need to propagate its oddities to this edge condition. * Once a device is opened, verify that the physical device path (if * available) is up to date. * Determine the actual size of the device. * If we own the whole disk, try to enable disk write caching. * We ignore errors because it's OK if we can't do it. * Determine the device's minimum transfer size. * If the ioctl isn't supported, assume DEV_BSIZE. * Clear the nowritecache bit, so that on a vdev_reopen() we will * Determine if the underlying device is accessible by reading and writing * to a known location. We must be able to do this during syncing context * and thus we cannot set the vdev state directly. /* Hijack the current vdev */ * Pick a random label to rewrite. * Try to read and write to a special location on the * label. We use the existing vdev initially and only * try to create and reopen it if we encounter a failure. /* Clean up if we allocated a new vdev */ /* Reset the failing flag */ * The rest of the zio stack only deals with EIO, ECKSUM, and ENXIO. * Rather than teach the rest of the stack about other error * possibilities (EFAULT, etc), we normalize the error value here. * The ioctl will be done asychronously, * and will call vdev_disk_ioctl_done() * If we get ENOTSUP or ENOTTY, we know that * no future attempts will ever succeed. * In this case we set a persistent bit so * that we don't bother with the ioctl in the /* ldi_strategy() will return non-zero only on programming errors */ * If the device returned EIO, then attempt a DKIOCSTATE ioctl to see if * the device has been removed. If this is the case, then we trigger an * asynchronous removal of the device. Otherwise, probe the device and * make sure it's still accessible. * Given the root disk device devid or pathname, read the label from * the device, and construct a configuration nvlist. * Read the device label and build the nvlist.