usr/src/uts/common/fs/zfs/vdev_disk.c
author ek110237
Thu, 26 Oct 2006 14:05:48 -0700
changeset 2986 c782fcf7a319
parent 2885 c0259887ebbc
child 4451 24fbf2d7a5d7
permissions -rw-r--r--
6485204 more tuneable tweakin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
     5
 * Common Development and Distribution License (the "License").
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/vdev_disk.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/zio.h>
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    34
#include <sys/sunldi.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
 * Virtual device vector for disks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
extern ldi_ident_t zfs_li;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
typedef struct vdev_disk_buf {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
	buf_t	vdb_buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
	zio_t	*vdb_io;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
} vdev_disk_buf_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	vdev_disk_t *dvd;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    51
	struct dk_minfo dkm;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	 * We must have a pathname, and it must be absolute.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
	dvd = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_disk_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	 * When opening a disk device, we want to preserve the user's original
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	 * intent.  We always want to open the device by the path the user gave
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	 * us, even if it is one of multiple paths to the save device.  But we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
	 * also want to be able to survive disks being removed/recabled.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	 * Therefore the sequence of opening devices is:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
	 *
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    71
	 * 1. Try opening the device by path.  For legacy pools without the
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    72
	 *    'whole_disk' property, attempt to fix the path by appending 's0'.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	 * 2. If the devid of the device matches the stored value, return
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	 *    success.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	 * 3. Otherwise, the device may have moved.  Try opening the device
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
	 *    by the devid instead.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
	if (vd->vdev_devid != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
		if (ddi_devid_str_decode(vd->vdev_devid, &dvd->vd_devid,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
		    &dvd->vd_minor) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
			vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	error = EINVAL;		/* presume failure */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	if (vd->vdev_path != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
		ddi_devid_t devid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    94
		if (vd->vdev_wholedisk == -1ULL) {
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    95
			size_t len = strlen(vd->vdev_path) + 3;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    96
			char *buf = kmem_alloc(len, KM_SLEEP);
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    97
			ldi_handle_t lh;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    98
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
    99
			(void) snprintf(buf, len, "%ss0", vd->vdev_path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   101
			if (ldi_open_by_name(buf, spa_mode, kcred,
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   102
			    &lh, zfs_li) == 0) {
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   103
				spa_strfree(vd->vdev_path);
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   104
				vd->vdev_path = buf;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   105
				vd->vdev_wholedisk = 1ULL;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   106
				(void) ldi_close(lh, spa_mode, kcred);
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   107
			} else {
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   108
				kmem_free(buf, len);
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   109
			}
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   110
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   112
		error = ldi_open_by_name(vd->vdev_path, spa_mode, kcred,
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   113
		    &dvd->vd_lh, zfs_li);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
		 * Compare the devid to the stored value.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
		if (error == 0 && vd->vdev_devid != NULL &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
		    ldi_get_devid(dvd->vd_lh, &devid) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
			if (ddi_devid_compare(devid, dvd->vd_devid) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
				error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
				(void) ldi_close(dvd->vd_lh, spa_mode, kcred);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
				dvd->vd_lh = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
			ddi_devid_free(devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
		}
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   127
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   128
		/*
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   129
		 * If we succeeded in opening the device, but 'vdev_wholedisk'
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   130
		 * is not yet set, then this must be a slice.
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   131
		 */
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   132
		if (error == 0 && vd->vdev_wholedisk == -1ULL)
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   133
			vd->vdev_wholedisk = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	 * If we were unable to open by path, or the devid check fails, open by
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	 * devid instead.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	if (error != 0 && vd->vdev_devid != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		error = ldi_open_by_devid(dvd->vd_devid, dvd->vd_minor,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
		    spa_mode, kcred, &dvd->vd_lh, zfs_li);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
	 * Determine the actual size of the device.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	if (ldi_get_size(dvd->vd_lh, psize) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   157
	/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   158
	 * If we own the whole disk, try to enable disk write caching.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   159
	 * We ignore errors because it's OK if we can't do it.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   160
	 */
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
   161
	if (vd->vdev_wholedisk == 1) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   162
		int wce = 1;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   163
		(void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   164
		    FKIOCTL, kcred, NULL);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   165
	}
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
   166
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   167
	/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   168
	 * Determine the device's minimum transfer size.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   169
	 * If the ioctl isn't supported, assume DEV_BSIZE.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   170
	 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   171
	if (ldi_ioctl(dvd->vd_lh, DKIOCGMEDIAINFO, (intptr_t)&dkm,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   172
	    FKIOCTL, kcred, NULL) != 0)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   173
		dkm.dki_lbsize = DEV_BSIZE;
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
   174
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   175
	*ashift = highbit(MAX(dkm.dki_lbsize, SPA_MINBLOCKSIZE)) - 1;
1489
fa842259660e 6322205 Enable disk write cache if ZFS owns the disk
webaker
parents: 1171
diff changeset
   176
1773
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   177
	/*
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   178
	 * Clear the nowritecache bit, so that on a vdev_reopen() we will
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   179
	 * try again.
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   180
	 */
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   181
	vd->vdev_nowritecache = B_FALSE;
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   182
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
vdev_disk_close(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	vdev_disk_t *dvd = vd->vdev_tsd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	if (dvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
	dprintf("removing disk %s, devid %s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	    vd->vdev_path ? vd->vdev_path : "<none>",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	    vd->vdev_devid ? vd->vdev_devid : "<none>");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	if (dvd->vd_minor != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
		ddi_devid_str_free(dvd->vd_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
	if (dvd->vd_devid != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
		ddi_devid_free(dvd->vd_devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
	if (dvd->vd_lh != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
		(void) ldi_close(dvd->vd_lh, spa_mode, kcred);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	kmem_free(dvd, sizeof (vdev_disk_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
	vd->vdev_tsd = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
vdev_disk_io_intr(buf_t *bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
	vdev_disk_buf_t *vdb = (vdev_disk_buf_t *)bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	zio_t *zio = vdb->vdb_io;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	if ((zio->io_error = geterror(bp)) == 0 && bp->b_resid != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
		zio->io_error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	kmem_free(vdb, sizeof (vdev_disk_buf_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
vdev_disk_ioctl_done(void *zio_arg, int error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	zio_t *zio = zio_arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
	zio->io_error = error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
	zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
vdev_disk_io_start(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	vdev_disk_t *dvd = vd->vdev_tsd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	vdev_disk_buf_t *vdb;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	buf_t *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	int flags, error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	if (zio->io_type == ZIO_TYPE_IOCTL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
		zio_vdev_io_bypass(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
		/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
		if (vdev_is_dead(vd)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
			zio->io_error = ENXIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
			zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
		switch (zio->io_cmd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
		case DKIOCFLUSHWRITECACHE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 1773
diff changeset
   258
			if (zfs_nocacheflush)
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 1773
diff changeset
   259
				break;
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 1773
diff changeset
   260
1773
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   261
			if (vd->vdev_nowritecache) {
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   262
				zio->io_error = ENOTSUP;
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   263
				break;
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   264
			}
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   265
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
			zio->io_dk_callback.dkc_callback = vdev_disk_ioctl_done;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
			zio->io_dk_callback.dkc_cookie = zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
			error = ldi_ioctl(dvd->vd_lh, zio->io_cmd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
			    (uintptr_t)&zio->io_dk_callback,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
			    FKIOCTL, kcred, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
			if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
				 * The ioctl will be done asychronously,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
				 * and will call vdev_disk_ioctl_done()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
				 * upon completion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
				return;
1773
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   280
			} else if (error == ENOTSUP) {
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   281
				/*
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   282
				 * If we get ENOTSUP, we know that no future
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   283
				 * attempts will ever succeed.  In this case we
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   284
				 * set a persistent bit so that we don't bother
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   285
				 * with the ioctl in the future.
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   286
				 */
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   287
				vd->vdev_nowritecache = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
			zio->io_error = error;
1773
d6e4f2855c14 6407791 bringover into ZFS results in s. files newer than extracted source
eschrock
parents: 1732
diff changeset
   290
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
		default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
			zio->io_error = ENOTSUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
		zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
	if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
	if ((zio = vdev_queue_io(zio)) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	flags = (zio->io_type == ZIO_TYPE_READ ? B_READ : B_WRITE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	flags |= B_BUSY | B_NOCACHE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	if (zio->io_flags & ZIO_FLAG_FAILFAST)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
		flags |= B_FAILFAST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	vdb = kmem_alloc(sizeof (vdev_disk_buf_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	vdb->vdb_io = zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	bp = &vdb->vdb_buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	bioinit(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	bp->b_flags = flags;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	bp->b_bcount = zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
	bp->b_un.b_addr = zio->io_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	bp->b_lblkno = lbtodb(zio->io_offset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	bp->b_bufsize = zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	bp->b_iodone = (int (*)())vdev_disk_io_intr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	error = vdev_is_dead(vd) ? ENXIO : vdev_error_inject(vd, zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		zio->io_error = error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
		bioerror(bp, error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
		bp->b_resid = bp->b_bcount;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
		bp->b_iodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	error = ldi_strategy(dvd->vd_lh, bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	/* ldi_strategy() will return non-zero only on programming errors */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
vdev_disk_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	vdev_queue_io_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	if (zio->io_type == ZIO_TYPE_WRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
		vdev_cache_write(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1489
diff changeset
   348
	if (zio_injection_enabled && zio->io_error == 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1489
diff changeset
   349
		zio->io_error = zio_handle_device_injection(zio->io_vd, EIO);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1489
diff changeset
   350
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
vdev_ops_t vdev_disk_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	vdev_disk_open,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	vdev_disk_close,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	vdev_default_asize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	vdev_disk_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	vdev_disk_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	NULL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
	VDEV_TYPE_DISK,		/* name of this vdev type */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	B_TRUE			/* leaf vdev */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
};