usr/src/uts/common/fs/zfs/zio.c
author eschrock
Tue, 05 Sep 2006 11:37:36 -0700
changeset 2676 5cee47eddab6
parent 2082 76b439ec3ac1
child 2856 6f4d5ee1906a
permissions -rw-r--r--
PSARC 2006/486 ZFS canmount property PSARC 2006/497 ZFS create time properties PSARC 2006/502 ZFS get all datasets PSARC 2006/504 ZFS user properties 6269805 properties should be set via an nvlist. 6281585 user defined properties 6349494 'zfs list' output annoying for even moderately long dataset names 6366244 'canmount' option for container-like functionality 6367103 create-time properties 6416639 RFE: provide zfs get -a 6437808 ZFS module version should match on-disk version 6454551 'zfs create -b blocksize filesystem' should fail. 6457478 unrecognized character in error message with 'zpool create -R' command 6457865 missing device name in the error message of 'zpool clear' command 6458571 zfs_ioc_set_prop() doesn't validate input 6458614 zfs ACL #defines should use prefix 6458638 get_configs() accesses bogus memory 6458678 zvol functions should be moved out of zfs_ioctl.h 6458683 zfs_cmd_t could use more cleanup 6458691 common routines to manage zfs_cmd_t nvlists 6460398 zpool import cores on zfs_prop_get 6461029 zpool status -x noexisting-pool has incorrect error message. 6461223 index translations should live with property definitions 6461424 zpool_unmount_datasets() has some busted logic 6461427 zfs_realloc() would be useful 6461757 'zpool status' can report the wrong number of persistent errors 6461784 recursive zfs_snapshot() leaks memory
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
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
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
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
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>
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
    29
#include <sys/fm/fs/zfs.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/txg.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/spa_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/zio_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/zio_compress.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/zio_checksum.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
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
 * I/O priority table
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
uint8_t zio_priority_table[ZIO_PRIORITY_TABLE_SIZE] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
	0,	/* ZIO_PRIORITY_NOW		*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
	0,	/* ZIO_PRIORITY_SYNC_READ	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
	0,	/* ZIO_PRIORITY_SYNC_WRITE	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	6,	/* ZIO_PRIORITY_ASYNC_READ	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	4,	/* ZIO_PRIORITY_ASYNC_WRITE	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	4,	/* ZIO_PRIORITY_FREE		*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	0,	/* ZIO_PRIORITY_CACHE_FILL	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	0,	/* ZIO_PRIORITY_LOG_WRITE	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	10,	/* ZIO_PRIORITY_RESILVER	*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	20,	/* ZIO_PRIORITY_SCRUB		*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
 * I/O type descriptions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
char *zio_type_name[ZIO_TYPES] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
	"null", "read", "write", "free", "claim", "ioctl" };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
/* At or above this size, force gang blocking - for testing */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
uint64_t zio_gang_bang = SPA_MAXBLOCKSIZE + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
typedef struct zio_sync_pass {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
	int	zp_defer_free;		/* defer frees after this pass */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	int	zp_dontcompress;	/* don't compress after this pass */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
	int	zp_rewrite;		/* rewrite new bps after this pass */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
} zio_sync_pass_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
zio_sync_pass_t zio_sync_pass = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	1,	/* zp_defer_free */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	4,	/* zp_dontcompress */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	1,	/* zp_rewrite */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
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
 * I/O kmem caches
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
kmem_cache_t *zio_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
zio_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	size_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
	 * For small buffers, we want a cache for each multiple of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	 * SPA_MINBLOCKSIZE.  For medium-size buffers, we want a cache
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	 * for each quarter-power of 2.  For large buffers, we want
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	 * a cache for each multiple of PAGESIZE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
		size_t size = (c + 1) << SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
		size_t p2 = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
		size_t align = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
		while (p2 & (p2 - 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
			p2 &= p2 - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
		if (size <= 4 * SPA_MINBLOCKSIZE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
			align = SPA_MINBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
		} else if (P2PHASE(size, PAGESIZE) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
			align = PAGESIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
		} else if (P2PHASE(size, p2 >> 2) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
			align = p2 >> 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
		if (align != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			char name[30];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			(void) sprintf(name, "zio_buf_%lu", size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			zio_buf_cache[c] = kmem_cache_create(name, size,
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
   117
			    align, NULL, NULL, NULL, NULL, NULL, KMC_NODEBUG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
			dprintf("creating cache for size %5lx align %5lx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
			    size, align);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	while (--c != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		ASSERT(zio_buf_cache[c] != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
		if (zio_buf_cache[c - 1] == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
			zio_buf_cache[c - 1] = zio_buf_cache[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   128
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   129
	zio_inject_init();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
zio_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	size_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	kmem_cache_t *last_cache = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
		if (zio_buf_cache[c] != last_cache) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
			last_cache = zio_buf_cache[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
			kmem_cache_destroy(zio_buf_cache[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
		zio_buf_cache[c] = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   145
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   146
	zio_inject_fini();
789
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
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
 * Allocate and free I/O buffers
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
void *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
zio_buf_alloc(size_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
	ASSERT(c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
	return (kmem_cache_alloc(zio_buf_cache[c], KM_SLEEP));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
zio_buf_free(void *buf, size_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	ASSERT(c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	kmem_cache_free(zio_buf_cache[c], buf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
 * Push and pop I/O transform buffers
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
zio_push_transform(zio_t *zio, void *data, uint64_t size, uint64_t bufsize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	zio_transform_t *zt = kmem_alloc(sizeof (zio_transform_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	zt->zt_data = data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	zt->zt_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	zt->zt_bufsize = bufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
	zt->zt_next = zio->io_transform_stack;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	zio->io_transform_stack = zt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	zio->io_data = data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
	zio->io_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
zio_pop_transform(zio_t *zio, void **data, uint64_t *size, uint64_t *bufsize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	zio_transform_t *zt = zio->io_transform_stack;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
	*data = zt->zt_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
	*size = zt->zt_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
	*bufsize = zt->zt_bufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
	zio->io_transform_stack = zt->zt_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	kmem_free(zt, sizeof (zio_transform_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	if ((zt = zio->io_transform_stack) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		zio->io_data = zt->zt_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
		zio->io_size = zt->zt_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
zio_clear_transform_stack(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	void *data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	uint64_t size, bufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	ASSERT(zio->io_transform_stack != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	zio_pop_transform(zio, &data, &size, &bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	while (zio->io_transform_stack != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
		zio_buf_free(data, bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
		zio_pop_transform(zio, &data, &size, &bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
 * Create the various types of I/O (read, write, free)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
static zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
zio_create(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
    void *data, uint64_t size, zio_done_func_t *done, void *private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
    zio_type_t type, int priority, int flags, uint8_t stage, uint32_t pipeline)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	zio = kmem_zalloc(sizeof (zio_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	zio->io_parent = pio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	zio->io_spa = spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	zio->io_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	if (bp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
		zio->io_bp = bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
		zio->io_bp_copy = *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
		zio->io_bp_orig = *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	zio->io_done = done;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	zio->io_private = private;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	zio->io_type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	zio->io_priority = priority;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	zio->io_stage = stage;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	zio->io_pipeline = pipeline;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	zio->io_async_stages = ZIO_ASYNC_PIPELINE_STAGES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	zio->io_timestamp = lbolt64;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	zio->io_flags = flags;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	zio_push_transform(zio, data, size, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	if (pio == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		if (!(flags & ZIO_FLAG_CONFIG_HELD))
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   265
			spa_config_enter(zio->io_spa, RW_READER, zio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
		zio->io_root = zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
		zio->io_root = pio->io_root;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   269
		if (!(flags & ZIO_FLAG_NOBOOKMARK))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   270
			zio->io_logical = pio->io_logical;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
		mutex_enter(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		if (stage < ZIO_STAGE_READY)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
			pio->io_children_notready++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		pio->io_children_notdone++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
		zio->io_sibling_next = pio->io_child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
		zio->io_sibling_prev = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		if (pio->io_child != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
			pio->io_child->io_sibling_prev = zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		pio->io_child = zio;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   280
		zio->io_ndvas = pio->io_ndvas;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
zio_null(zio_t *pio, spa_t *spa, zio_done_func_t *done, void *private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
	int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	    ZIO_TYPE_NULL, ZIO_PRIORITY_NOW, flags, ZIO_STAGE_OPEN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
	    ZIO_WAIT_FOR_CHILDREN_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
zio_root(spa_t *spa, zio_done_func_t *done, void *private, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
	return (zio_null(NULL, spa, done, private, flags));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
zio_read(zio_t *pio, spa_t *spa, blkptr_t *bp, void *data,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
    uint64_t size, zio_done_func_t *done, void *private,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   309
    int priority, int flags, zbookmark_t *zb)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	ASSERT3U(size, ==, BP_GET_LSIZE(bp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	zio = zio_create(pio, spa, bp->blk_birth, bp, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	    ZIO_TYPE_READ, priority, flags, ZIO_STAGE_OPEN, ZIO_READ_PIPELINE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   317
	zio->io_bookmark = *zb;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   318
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   319
	zio->io_logical = zio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	 * Work off our copy of the bp so the caller can free it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	zio->io_bp = &zio->io_bp_copy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		uint64_t csize = BP_GET_PSIZE(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		void *cbuf = zio_buf_alloc(csize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
		zio_push_transform(zio, cbuf, csize, csize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
		zio->io_pipeline |= 1U << ZIO_STAGE_READ_DECOMPRESS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   334
	if (BP_IS_GANG(bp)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
		uint64_t gsize = SPA_GANGBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
		void *gbuf = zio_buf_alloc(gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
		zio_push_transform(zio, gbuf, gsize, gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
		zio->io_pipeline |= 1U << ZIO_STAGE_READ_GANG_MEMBERS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
zio_t *
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   346
zio_write(zio_t *pio, spa_t *spa, int checksum, int compress, int ncopies,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
    uint64_t txg, blkptr_t *bp, void *data, uint64_t size,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   348
    zio_done_func_t *done, void *private, int priority, int flags,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   349
    zbookmark_t *zb)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	ASSERT(checksum >= ZIO_CHECKSUM_OFF &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	    checksum < ZIO_CHECKSUM_FUNCTIONS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	ASSERT(compress >= ZIO_COMPRESS_OFF &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	    compress < ZIO_COMPRESS_FUNCTIONS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	zio = zio_create(pio, spa, txg, bp, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	    ZIO_TYPE_WRITE, priority, flags,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
	    ZIO_STAGE_OPEN, ZIO_WRITE_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   363
	zio->io_bookmark = *zb;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   364
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   365
	zio->io_logical = zio;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   366
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	zio->io_checksum = checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
	zio->io_compress = compress;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   369
	zio->io_ndvas = ncopies;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	if (compress != ZIO_COMPRESS_OFF)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
		zio->io_async_stages |= 1U << ZIO_STAGE_WRITE_COMPRESS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	if (bp->blk_birth != txg) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
		/* XXX the bp usually (always?) gets re-zeroed later */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
		BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		BP_SET_LSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
		BP_SET_PSIZE(bp, size);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   379
	} else {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   380
		/* Make sure someone doesn't change their mind on overwrites */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   381
		ASSERT(MIN(zio->io_ndvas + BP_IS_GANG(bp),
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   382
		    spa_max_replication(spa)) == BP_GET_NDVAS(bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
zio_rewrite(zio_t *pio, spa_t *spa, int checksum,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
    uint64_t txg, blkptr_t *bp, void *data, uint64_t size,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   391
    zio_done_func_t *done, void *private, int priority, int flags,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   392
    zbookmark_t *zb)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	zio = zio_create(pio, spa, txg, bp, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	    ZIO_TYPE_WRITE, priority, flags,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	    ZIO_STAGE_OPEN, ZIO_REWRITE_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   400
	zio->io_bookmark = *zb;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	zio->io_checksum = checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
	zio->io_compress = ZIO_COMPRESS_OFF;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   404
	if (pio != NULL)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   405
		ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   406
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
static zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
zio_write_allocate(zio_t *pio, spa_t *spa, int checksum,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
    uint64_t txg, blkptr_t *bp, void *data, uint64_t size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
    zio_done_func_t *done, void *private, int priority, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
	BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
	BP_SET_LSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
	BP_SET_PSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
	BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
	zio = zio_create(pio, spa, txg, bp, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	    ZIO_TYPE_WRITE, priority, flags,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	    ZIO_STAGE_OPEN, ZIO_WRITE_ALLOCATE_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
	zio->io_checksum = checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
	zio->io_compress = ZIO_COMPRESS_OFF;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
zio_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
    zio_done_func_t *done, void *private)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	ASSERT(!BP_IS_HOLE(bp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	if (txg == spa->spa_syncing_txg &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
	    spa->spa_sync_pass > zio_sync_pass.zp_defer_free) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   442
		bplist_enqueue_deferred(&spa->spa_sync_bplist, bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
		return (zio_null(pio, spa, NULL, NULL, 0));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	zio = zio_create(pio, spa, txg, bp, NULL, 0, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
	    ZIO_TYPE_FREE, ZIO_PRIORITY_FREE, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
	    ZIO_STAGE_OPEN, ZIO_FREE_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
	zio->io_bp = &zio->io_bp_copy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
    zio_done_func_t *done, void *private)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	 * A claim is an allocation of a specific block.  Claims are needed
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
	 * to support immediate writes in the intent log.  The issue is that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
	 * immediate writes contain committed data, but in a txg that was
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
	 * *not* committed.  Upon opening the pool after an unclean shutdown,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	 * the intent log claims all blocks that contain immediate write data
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	 * so that the SPA knows they're in use.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	 * All claims *must* be resolved in the first txg -- before the SPA
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	 * starts allocating blocks -- so that nothing is allocated twice.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
	ASSERT3U(spa->spa_uberblock.ub_rootbp.blk_birth, <, spa_first_txg(spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
	ASSERT3U(spa_first_txg(spa), <=, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	zio = zio_create(pio, spa, txg, bp, NULL, 0, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
	    ZIO_TYPE_CLAIM, ZIO_PRIORITY_NOW, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	    ZIO_STAGE_OPEN, ZIO_CLAIM_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
	zio->io_bp = &zio->io_bp_copy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
    zio_done_func_t *done, void *private, int priority, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
		zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
		    ZIO_TYPE_IOCTL, priority, flags,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
		    ZIO_STAGE_OPEN, ZIO_IOCTL_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
		zio->io_vd = vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
		zio->io_cmd = cmd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
		zio = zio_null(pio, spa, NULL, NULL, flags);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
		for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
			zio_nowait(zio_ioctl(zio, spa, vd->vdev_child[c], cmd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
			    done, private, priority, flags));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
zio_phys_bp_init(vdev_t *vd, blkptr_t *bp, uint64_t offset, uint64_t size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
    int checksum)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
	ASSERT(vd->vdev_children == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
	ASSERT(size <= SPA_MAXBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	ASSERT(offset + size <= VDEV_LABEL_START_SIZE ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	    offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
	ASSERT3U(offset + size, <=, vd->vdev_psize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
	BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
	BP_SET_LSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
	BP_SET_PSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
	BP_SET_CHECKSUM(bp, checksum);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
	if (checksum != ZIO_CHECKSUM_OFF)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
		ZIO_SET_CHECKSUM(&bp->blk_cksum, offset, 0, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
    void *data, int checksum, zio_done_func_t *done, void *private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
    int priority, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
	blkptr_t blk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	zio_phys_bp_init(vd, &blk, offset, size, checksum);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	zio = zio_create(pio, vd->vdev_spa, 0, &blk, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	    ZIO_TYPE_READ, priority, flags | ZIO_FLAG_PHYSICAL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	    ZIO_STAGE_OPEN, ZIO_READ_PHYS_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
	zio->io_vd = vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
	zio->io_offset = offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	 * Work off our copy of the bp so the caller can free it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
	zio->io_bp = &zio->io_bp_copy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
    void *data, int checksum, zio_done_func_t *done, void *private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
    int priority, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	zio_block_tail_t *zbt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	void *wbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	blkptr_t blk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
	zio_phys_bp_init(vd, &blk, offset, size, checksum);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	zio = zio_create(pio, vd->vdev_spa, 0, &blk, data, size, done, private,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
	    ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_PHYSICAL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
	    ZIO_STAGE_OPEN, ZIO_WRITE_PHYS_PIPELINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	zio->io_vd = vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	zio->io_offset = offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	zio->io_bp = &zio->io_bp_copy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	zio->io_checksum = checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	if (zio_checksum_table[checksum].ci_zbt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
		 * zbt checksums are necessarily destructive -- they modify
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
		 * one word of the write buffer to hold the verifier/checksum.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
		 * Therefore, we must make a local copy in case the data is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
		 * being written to multiple places.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
		wbuf = zio_buf_alloc(size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
		bcopy(data, wbuf, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
		zio_push_transform(zio, wbuf, size, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
		zbt = (zio_block_tail_t *)((char *)wbuf + size) - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
		zbt->zbt_cksum = blk.blk_cksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
 * Create a child I/O to do some work for us.  It has no associated bp.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd, uint64_t offset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
	void *data, uint64_t size, int type, int priority, int flags,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
	zio_done_func_t *done, void *private)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
	uint32_t pipeline = ZIO_VDEV_CHILD_PIPELINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	zio_t *cio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	if (type == ZIO_TYPE_READ && bp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
		 * If we have the bp, then the child should perform the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
		 * checksum and the parent need not.  This pushes error
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
		 * detection as close to the leaves as possible and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
		 * eliminates redundant checksums in the interior nodes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
		pipeline |= 1U << ZIO_STAGE_CHECKSUM_VERIFY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
		zio->io_pipeline &= ~(1U << ZIO_STAGE_CHECKSUM_VERIFY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
	cio = zio_create(zio, zio->io_spa, zio->io_txg, bp, data, size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	    done, private, type, priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	    (zio->io_flags & ZIO_FLAG_VDEV_INHERIT) | ZIO_FLAG_CANFAIL | flags,
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   626
	    ZIO_STAGE_VDEV_IO_START - 1, pipeline);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
	cio->io_vd = vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	cio->io_offset = offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	return (cio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
 * Initiate I/O, either sync or async
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
zio_wait(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
	ASSERT(zio->io_stage == ZIO_STAGE_OPEN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
	zio->io_waiter = curthread;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
	mutex_enter(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
	while (zio->io_stalled != ZIO_STAGE_DONE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
		cv_wait(&zio->io_cv, &zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
	mutex_exit(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
	error = zio->io_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
	kmem_free(zio, sizeof (zio_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
zio_nowait(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
	zio_next_stage_async(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
 * I/O pipeline interlocks: parent/child dependency scoreboarding
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
zio_wait_for_children(zio_t *zio, uint32_t stage, uint64_t *countp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
	mutex_enter(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
	if (*countp == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
		ASSERT(zio->io_stalled == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
		mutex_exit(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
		zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
		zio->io_stalled = stage;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
		mutex_exit(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
zio_notify_parent(zio_t *zio, uint32_t stage, uint64_t *countp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
	zio_t *pio = zio->io_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
	mutex_enter(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
	if (pio->io_error == 0 && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
		pio->io_error = zio->io_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
	if (--*countp == 0 && pio->io_stalled == stage) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
		pio->io_stalled = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
		zio_next_stage_async(pio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
zio_wait_children_ready(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
	zio_wait_for_children(zio, ZIO_STAGE_WAIT_CHILDREN_READY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
	    &zio->io_children_notready);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
zio_wait_children_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
	zio_wait_for_children(zio, ZIO_STAGE_WAIT_CHILDREN_DONE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
	    &zio->io_children_notdone);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
zio_ready(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
	zio_t *pio = zio->io_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
	if (pio != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
		zio_notify_parent(zio, ZIO_STAGE_WAIT_CHILDREN_READY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
		    &pio->io_children_notready);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
	if (zio->io_bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
		zio->io_bp_copy = *zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
zio_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
	zio_t *pio = zio->io_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
	spa_t *spa = zio->io_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
	vdev_t *vd = zio->io_vd;
896
f5270e6bd04d 6348089 panic in dbuf_remove_ref
maybee
parents: 849
diff changeset
   740
	char blkbuf[BP_SPRINTF_LEN];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
	ASSERT(zio->io_children_notready == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
	ASSERT(zio->io_children_notdone == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
	if (bp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
		ASSERT(bp->blk_pad[0] == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
		ASSERT(bp->blk_pad[1] == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
		ASSERT(bp->blk_pad[2] == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
		ASSERT(bcmp(bp, &zio->io_bp_copy, sizeof (blkptr_t)) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
		if (zio->io_type == ZIO_TYPE_WRITE && !BP_IS_HOLE(bp) &&
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   751
		    !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
			ASSERT(!BP_SHOULD_BYTESWAP(bp));
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   753
			if (zio->io_ndvas != 0)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   754
				ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   755
			ASSERT(BP_COUNT_GANG(bp) == 0 ||
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   756
			    (BP_COUNT_GANG(bp) == BP_GET_NDVAS(bp)));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   757
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
	if (vd != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
		vdev_stat_update(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	if (zio->io_error) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   764
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   765
		 * If this I/O is attached to a particular vdev,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   766
		 * generate an error message describing the I/O failure
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   767
		 * at the block level.  We ignore these errors if the
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   768
		 * device is currently unavailable.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   769
		 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   770
		if (zio->io_error != ECKSUM && vd != NULL && !vdev_is_dead(vd))
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   771
			zfs_ereport_post(FM_EREPORT_ZFS_IO,
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   772
			    zio->io_spa, vd, zio, 0, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   774
		if ((zio->io_error == EIO ||
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   775
		    !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   776
		    zio->io_logical == zio) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   777
			/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   778
			 * For root I/O requests, tell the SPA to log the error
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   779
			 * appropriately.  Also, generate a logical data
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   780
			 * ereport.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   781
			 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   782
			spa_log_error(zio->io_spa, zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   783
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   784
			zfs_ereport_post(FM_EREPORT_ZFS_DATA,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   785
			    zio->io_spa, NULL, zio, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   786
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   788
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   789
		 * For I/O requests that cannot fail, panic appropriately.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   790
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   791
		if (!(zio->io_flags & ZIO_FLAG_CANFAIL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   792
			sprintf_blkptr(blkbuf, BP_SPRINTF_LEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   793
			    bp ? bp : &zio->io_bp_copy);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   794
			panic("ZFS: %s (%s on %s off %llx: zio %p %s): error "
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   795
			    "%d", zio->io_error == ECKSUM ?
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   796
			    "bad checksum" : "I/O failure",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   797
			    zio_type_name[zio->io_type],
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   798
			    vdev_description(vd),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   799
			    (u_longlong_t)zio->io_offset,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   800
			    zio, blkbuf, zio->io_error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   801
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
	zio_clear_transform_stack(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
	if (zio->io_done)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
		zio->io_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
	ASSERT(zio->io_delegate_list == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
	ASSERT(zio->io_delegate_next == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
	if (pio != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
		zio_t *next, *prev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
		mutex_enter(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
		next = zio->io_sibling_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
		prev = zio->io_sibling_prev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
		if (next != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
			next->io_sibling_prev = prev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
		if (prev != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
			prev->io_sibling_next = next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
		if (pio->io_child == zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
			pio->io_child = next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
		zio_notify_parent(zio, ZIO_STAGE_WAIT_CHILDREN_DONE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
		    &pio->io_children_notdone);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
	if (pio == NULL && !(zio->io_flags & ZIO_FLAG_CONFIG_HELD))
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
   831
		spa_config_exit(spa, zio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
	if (zio->io_waiter != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
		mutex_enter(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
		ASSERT(zio->io_stage == ZIO_STAGE_DONE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
		zio->io_stalled = zio->io_stage;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
		cv_broadcast(&zio->io_cv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
		mutex_exit(&zio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
		kmem_free(zio, sizeof (zio_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
 * Compression support
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
zio_write_compress(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
	int compress = zio->io_compress;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
	void *cbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
	uint64_t lsize = zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
	uint64_t csize = lsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
	uint64_t cbufsize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
	int pass;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
	if (bp->blk_birth == zio->io_txg) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
		 * We're rewriting an existing block, which means we're
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
		 * working on behalf of spa_sync().  For spa_sync() to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
		 * converge, it must eventually be the case that we don't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
		 * have to allocate new blocks.  But compression changes
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
		 * the blocksize, which forces a reallocate, and makes
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
		 * convergence take longer.  Therefore, after the first
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		 * few passes, stop compressing to ensure convergence.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
		pass = spa_sync_pass(zio->io_spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
		if (pass > zio_sync_pass.zp_dontcompress)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
			compress = ZIO_COMPRESS_OFF;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
		ASSERT(BP_IS_HOLE(bp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
		pass = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
	if (compress != ZIO_COMPRESS_OFF)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
		if (!zio_compress_data(compress, zio->io_data, zio->io_size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
		    &cbuf, &csize, &cbufsize))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
			compress = ZIO_COMPRESS_OFF;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
	if (compress != ZIO_COMPRESS_OFF && csize != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
		zio_push_transform(zio, cbuf, csize, cbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
	 * The final pass of spa_sync() must be all rewrites, but the first
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
	 * few passes offer a trade-off: allocating blocks defers convergence,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
	 * but newly allocated blocks are sequential, so they can be written
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
	 * to disk faster.  Therefore, we allow the first few passes of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
	 * spa_sync() to reallocate new blocks, but force rewrites after that.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
	 * There should only be a handful of blocks after pass 1 in any case.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
	if (bp->blk_birth == zio->io_txg && BP_GET_PSIZE(bp) == csize &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
	    pass > zio_sync_pass.zp_rewrite) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
		ASSERT(csize != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
		ASSERT3U(BP_GET_COMPRESS(bp), ==, compress);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
		ASSERT3U(BP_GET_LSIZE(bp), ==, lsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
		zio->io_pipeline = ZIO_REWRITE_PIPELINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
		if (bp->blk_birth == zio->io_txg) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
			ASSERT3U(BP_GET_LSIZE(bp), ==, lsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
			bzero(bp, sizeof (blkptr_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
		if (csize == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
			BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
			zio->io_pipeline = ZIO_WAIT_FOR_CHILDREN_PIPELINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
		} else {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   910
			ASSERT3U(BP_GET_NDVAS(bp), ==, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
			BP_SET_LSIZE(bp, lsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
			BP_SET_PSIZE(bp, csize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
			BP_SET_COMPRESS(bp, compress);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
			zio->io_pipeline = ZIO_WRITE_ALLOCATE_PIPELINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   917
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   920
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
zio_read_decompress(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
	void *data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
	uint64_t size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
	uint64_t bufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
	int compress = BP_GET_COMPRESS(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
	ASSERT(compress != ZIO_COMPRESS_OFF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
	zio_pop_transform(zio, &data, &size, &bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
	if (zio_decompress_data(compress, data, size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
	    zio->io_data, zio->io_size))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
		zio->io_error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
	zio_buf_free(data, bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
 * Gang block support
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
zio_gang_pipeline(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   952
	 * By default, the pipeline assumes that we're dealing with a gang
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
	 * block.  If we're not, strip out any gang-specific stages.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
	 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   955
	if (!BP_IS_GANG(zio->io_bp))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
		zio->io_pipeline &= ~ZIO_GANG_STAGES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   957
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   958
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
zio_gang_byteswap(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
	ASSERT(zio->io_size == SPA_GANGBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
	if (BP_SHOULD_BYTESWAP(zio->io_bp))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
		byteswap_uint64_array(zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
zio_get_gang_header(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
	uint64_t gsize = SPA_GANGBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
	void *gbuf = zio_buf_alloc(gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   977
	ASSERT(BP_IS_GANG(bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
	zio_push_transform(zio, gbuf, gsize, gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
	zio_nowait(zio_create(zio, zio->io_spa, bp->blk_birth, bp, gbuf, gsize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
	    NULL, NULL, ZIO_TYPE_READ, zio->io_priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
	    zio->io_flags & ZIO_FLAG_GANG_INHERIT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
	    ZIO_STAGE_OPEN, ZIO_READ_PIPELINE));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
	zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
zio_read_gang_members(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
	zio_gbh_phys_t *gbh;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	uint64_t gsize, gbufsize, loff, lsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   996
	ASSERT(BP_IS_GANG(zio->io_bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	zio_gang_byteswap(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
	zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
	for (loff = 0, i = 0; loff != zio->io_size; loff += lsize, i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
		blkptr_t *gbp = &gbh->zg_blkptr[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
		lsize = BP_GET_PSIZE(gbp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
		ASSERT(BP_GET_COMPRESS(gbp) == ZIO_COMPRESS_OFF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
		ASSERT3U(lsize, ==, BP_GET_LSIZE(gbp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
		ASSERT3U(loff + lsize, <=, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
		ASSERT(i < SPA_GBH_NBLKPTRS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
		ASSERT(!BP_IS_HOLE(gbp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
		zio_nowait(zio_read(zio, zio->io_spa, gbp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
		    (char *)zio->io_data + loff, lsize, NULL, NULL,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1013
		    zio->io_priority, zio->io_flags & ZIO_FLAG_GANG_INHERIT,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1014
		    &zio->io_bookmark));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
	zio_buf_free(gbh, gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
	zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
zio_rewrite_gang_members(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
	zio_gbh_phys_t *gbh;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
	uint64_t gsize, gbufsize, loff, lsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1028
	ASSERT(BP_IS_GANG(zio->io_bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
	ASSERT3U(zio->io_size, ==, SPA_GANGBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1031
	zio_gang_byteswap(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
	zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
	ASSERT(gsize == gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
	for (loff = 0, i = 0; loff != zio->io_size; loff += lsize, i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
		blkptr_t *gbp = &gbh->zg_blkptr[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
		lsize = BP_GET_PSIZE(gbp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
		ASSERT(BP_GET_COMPRESS(gbp) == ZIO_COMPRESS_OFF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
		ASSERT3U(lsize, ==, BP_GET_LSIZE(gbp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
		ASSERT3U(loff + lsize, <=, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
		ASSERT(i < SPA_GBH_NBLKPTRS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
		ASSERT(!BP_IS_HOLE(gbp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1046
		zio_nowait(zio_rewrite(zio, zio->io_spa, zio->io_checksum,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
		    zio->io_txg, gbp, (char *)zio->io_data + loff, lsize,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1048
		    NULL, NULL, zio->io_priority, zio->io_flags,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1049
		    &zio->io_bookmark));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
	zio_push_transform(zio, gbh, gsize, gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
	zio_wait_children_ready(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
zio_free_gang_members(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1059
	zio_gbh_phys_t *gbh;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
	uint64_t gsize, gbufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1063
	ASSERT(BP_IS_GANG(zio->io_bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1064
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
	zio_gang_byteswap(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1066
	zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1068
	for (i = 0; i < SPA_GBH_NBLKPTRS; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
		blkptr_t *gbp = &gbh->zg_blkptr[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
		if (BP_IS_HOLE(gbp))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
		zio_nowait(zio_free(zio, zio->io_spa, zio->io_txg,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1074
		    gbp, NULL, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
	zio_buf_free(gbh, gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1078
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
zio_claim_gang_members(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
	zio_gbh_phys_t *gbh;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
	uint64_t gsize, gbufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1088
	ASSERT(BP_IS_GANG(zio->io_bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
	zio_gang_byteswap(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
	zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
	for (i = 0; i < SPA_GBH_NBLKPTRS; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1094
		blkptr_t *gbp = &gbh->zg_blkptr[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1095
		if (BP_IS_HOLE(gbp))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
		zio_nowait(zio_claim(zio, zio->io_spa, zio->io_txg,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
		    gbp, NULL, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
	zio_buf_free(gbh, gbufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
zio_write_allocate_gang_member_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
	zio_t *pio = zio->io_parent;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1109
	dva_t *cdva = zio->io_bp->blk_dva;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1110
	dva_t *pdva = pio->io_bp->blk_dva;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	uint64_t asize;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1112
	int d;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1114
	ASSERT3U(pio->io_ndvas, ==, zio->io_ndvas);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1115
	ASSERT3U(BP_GET_NDVAS(zio->io_bp), <=, BP_GET_NDVAS(pio->io_bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1116
	ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(zio->io_bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1117
	ASSERT3U(pio->io_ndvas, <=, BP_GET_NDVAS(pio->io_bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1118
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
	mutex_enter(&pio->io_lock);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1120
	for (d = 0; d < BP_GET_NDVAS(pio->io_bp); d++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1121
		ASSERT(DVA_GET_GANG(&pdva[d]));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1122
		asize = DVA_GET_ASIZE(&pdva[d]);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1123
		asize += DVA_GET_ASIZE(&cdva[d]);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1124
		DVA_SET_ASIZE(&pdva[d], asize);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1125
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
	mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
zio_write_allocate_gang_members(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
	blkptr_t *bp = zio->io_bp;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1133
	dva_t *dva = bp->blk_dva;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1134
	spa_t *spa = zio->io_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
	zio_gbh_phys_t *gbh;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1136
	uint64_t txg = zio->io_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
	uint64_t resid = zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
	uint64_t maxalloc = P2ROUNDUP(zio->io_size >> 1, SPA_MINBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
	uint64_t gsize, loff, lsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
	uint32_t gbps_left;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1141
	int ndvas = zio->io_ndvas;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1142
	int gbh_ndvas = MIN(ndvas + 1, spa_max_replication(spa));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
	int error;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1144
	int i, d;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
	gsize = SPA_GANGBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
	gbps_left = SPA_GBH_NBLKPTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1149
	error = metaslab_alloc(spa, gsize, bp, gbh_ndvas, txg, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	if (error == ENOSPC)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
		panic("can't allocate gang block header");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1154
	for (d = 0; d < gbh_ndvas; d++)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1155
		DVA_SET_GANG(&dva[d], 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1157
	bp->blk_birth = txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
	gbh = zio_buf_alloc(gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
	bzero(gbh, gsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1162
	/* We need to test multi-level gang blocks */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1163
	if (maxalloc >= zio_gang_bang && (lbolt & 0x1) == 0)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1164
		maxalloc = MAX(maxalloc >> 2, SPA_MINBLOCKSIZE);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1165
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	for (loff = 0, i = 0; loff != zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
	    loff += lsize, resid -= lsize, gbps_left--, i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
		blkptr_t *gbp = &gbh->zg_blkptr[i];
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1169
		dva = gbp->blk_dva;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
		ASSERT(gbps_left != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
		maxalloc = MIN(maxalloc, resid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1174
		while (resid <= maxalloc * gbps_left) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1175
			error = metaslab_alloc(spa, maxalloc, gbp, ndvas,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1176
			    txg, bp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1177
			if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
			ASSERT3U(error, ==, ENOSPC);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
			if (maxalloc == SPA_MINBLOCKSIZE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
				panic("really out of space");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
			maxalloc = P2ROUNDUP(maxalloc >> 1, SPA_MINBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
		if (resid <= maxalloc * gbps_left) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
			lsize = maxalloc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
			BP_SET_LSIZE(gbp, lsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
			BP_SET_PSIZE(gbp, lsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
			BP_SET_COMPRESS(gbp, ZIO_COMPRESS_OFF);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1190
			gbp->blk_birth = txg;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1191
			zio_nowait(zio_rewrite(zio, spa,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1192
			    zio->io_checksum, txg, gbp,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
			    (char *)zio->io_data + loff, lsize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
			    zio_write_allocate_gang_member_done, NULL,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1195
			    zio->io_priority, zio->io_flags,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1196
			    &zio->io_bookmark));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
			lsize = P2ROUNDUP(resid / gbps_left, SPA_MINBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
			ASSERT(lsize != SPA_MINBLOCKSIZE);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1200
			zio_nowait(zio_write_allocate(zio, spa,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1201
			    zio->io_checksum, txg, gbp,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
			    (char *)zio->io_data + loff, lsize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1203
			    zio_write_allocate_gang_member_done, NULL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
			    zio->io_priority, zio->io_flags));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
	ASSERT(resid == 0 && loff == zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
	zio->io_pipeline |= 1U << ZIO_STAGE_GANG_CHECKSUM_GENERATE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
	zio_push_transform(zio, gbh, gsize, gsize);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1213
	/*
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1214
	 * As much as we'd like this to be zio_wait_children_ready(),
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1215
	 * updating our ASIZE doesn't happen until the io_done callback,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1216
	 * so we have to wait for that to finish in order for our BP
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1217
	 * to be stable.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1218
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1219
	zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1220
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
 * Allocate and free blocks
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
zio_dva_allocate(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1230
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
	ASSERT(BP_IS_HOLE(bp));
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1234
	ASSERT3U(BP_GET_NDVAS(bp), ==, 0);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1235
	ASSERT3U(zio->io_ndvas, >, 0);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1236
	ASSERT3U(zio->io_ndvas, <=, spa_max_replication(zio->io_spa));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1238
	/* For testing, make some blocks above a certain size be gang blocks */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
	if (zio->io_size >= zio_gang_bang && (lbolt & 0x3) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
		zio_write_allocate_gang_members(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1243
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
	ASSERT3U(zio->io_size, ==, BP_GET_PSIZE(bp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1245
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1246
	error = metaslab_alloc(zio->io_spa, zio->io_size, bp, zio->io_ndvas,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1247
	    zio->io_txg, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
	if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
		bp->blk_birth = zio->io_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
	} else if (error == ENOSPC) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
		if (zio->io_size == SPA_MINBLOCKSIZE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
			panic("really, truly out of space");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
		zio_write_allocate_gang_members(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
		zio->io_error = error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
zio_dva_free(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1267
	metaslab_free(zio->io_spa, bp, zio->io_txg, B_FALSE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
	BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1271
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1273
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1274
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1275
zio_dva_claim(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1276
{
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1277
	zio->io_error = metaslab_claim(zio->io_spa, zio->io_bp, zio->io_txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
 * Read and write to physical devices
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
static void
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1289
zio_vdev_io_start(zio_t *zio)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
	vdev_t *vd = zio->io_vd;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1292
	vdev_t *tvd = vd ? vd->vdev_top : NULL;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1293
	blkptr_t *bp = zio->io_bp;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1294
	uint64_t align;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1296
	if (vd == NULL) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1297
		/* The mirror_ops handle multiple DVAs in a single BP */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1298
		vdev_mirror_ops.vdev_op_io_start(zio);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1299
		return;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1300
	}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1301
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1302
	align = 1ULL << tvd->vdev_ashift;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1303
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1304
	if (zio->io_retries == 0 && vd == tvd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1305
		zio->io_flags |= ZIO_FLAG_FAILFAST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1306
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1307
	if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) &&
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1308
	    vd->vdev_children == 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
		zio->io_flags |= ZIO_FLAG_PHYSICAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
		zio->io_offset += VDEV_LABEL_START_SIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1312
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1313
	if (P2PHASE(zio->io_size, align) != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1314
		uint64_t asize = P2ROUNDUP(zio->io_size, align);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1315
		char *abuf = zio_buf_alloc(asize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1316
		ASSERT(vd == tvd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1317
		if (zio->io_type == ZIO_TYPE_WRITE) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1318
			bcopy(zio->io_data, abuf, zio->io_size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1319
			bzero(abuf + zio->io_size, asize - zio->io_size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1320
		}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1321
		zio_push_transform(zio, abuf, asize, asize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1322
		ASSERT(!(zio->io_flags & ZIO_FLAG_SUBBLOCK));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1323
		zio->io_flags |= ZIO_FLAG_SUBBLOCK;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1324
	}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1325
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1326
	ASSERT(P2PHASE(zio->io_offset, align) == 0);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1327
	ASSERT(P2PHASE(zio->io_size, align) == 0);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1328
	ASSERT(bp == NULL ||
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1329
	    P2ROUNDUP(ZIO_GET_IOSIZE(zio), align) == zio->io_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1330
	ASSERT(zio->io_type != ZIO_TYPE_WRITE || (spa_mode & FWRITE));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
	vdev_io_start(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1334
	/* zio_next_stage_async() gets called from io completion interrupt */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1337
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1338
zio_vdev_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1339
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1340
	if (zio->io_vd == NULL)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1341
		/* The mirror_ops handle multiple DVAs in a single BP */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1342
		vdev_mirror_ops.vdev_op_io_done(zio);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1343
	else
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1344
		vdev_io_done(zio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1345
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1347
/* XXPOLICY */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1348
boolean_t
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1349
zio_should_retry(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1350
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1352
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1353
	if (zio->io_error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1354
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1355
	if (zio->io_delegate_list != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1356
		return (B_FALSE);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1357
	if (vd && vd != vd->vdev_top)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1358
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1359
	if (zio->io_flags & ZIO_FLAG_DONT_RETRY)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1360
		return (B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1361
	if (zio->io_retries > 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1363
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1364
	return (B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1365
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1366
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1367
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1368
zio_vdev_io_assess(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1369
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1370
	vdev_t *vd = zio->io_vd;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1371
	vdev_t *tvd = vd ? vd->vdev_top : NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1372
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1373
	ASSERT(zio->io_vsd == NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1375
	if (zio->io_flags & ZIO_FLAG_SUBBLOCK) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1376
		void *abuf;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1377
		uint64_t asize;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1378
		ASSERT(vd == tvd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1379
		zio_pop_transform(zio, &abuf, &asize, &asize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1380
		if (zio->io_type == ZIO_TYPE_READ)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1381
			bcopy(abuf, zio->io_data, zio->io_size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1382
		zio_buf_free(abuf, asize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1383
		zio->io_flags &= ~ZIO_FLAG_SUBBLOCK;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1384
	}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
  1385
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1386
	if (zio_injection_enabled && !zio->io_error)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1387
		zio->io_error = zio_handle_fault_injection(zio, EIO);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1388
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1389
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1390
	 * If the I/O failed, determine whether we should attempt to retry it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1391
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1392
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1393
	if (zio_should_retry(zio)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1394
		ASSERT(tvd == vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1396
		zio->io_retries++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1397
		zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1398
		zio->io_flags &= ZIO_FLAG_VDEV_INHERIT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1399
		/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1400
		zio->io_flags &= ~ZIO_FLAG_FAILFAST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1401
		zio->io_flags |= ZIO_FLAG_DONT_CACHE;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1402
		zio->io_stage = ZIO_STAGE_VDEV_IO_START - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1403
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
		dprintf("retry #%d for %s to %s offset %llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
		    zio->io_retries, zio_type_name[zio->io_type],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
		    vdev_description(vd), zio->io_offset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1408
		zio_next_stage_async(zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1409
		return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1410
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1412
	if (zio->io_error != 0 && zio->io_error != ECKSUM &&
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1413
	    !(zio->io_flags & ZIO_FLAG_SPECULATIVE) && vd) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1415
		 * Poor man's hotplug support.  Even if we're done retrying this
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1416
		 * I/O, try to reopen the vdev to see if it's still attached.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1417
		 * To avoid excessive thrashing, we only try it once a minute.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1418
		 * This also has the effect of detecting when missing devices
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1419
		 * have come back, by polling the device once a minute.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1420
		 *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1421
		 * We need to do this asynchronously because we can't grab
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1422
		 * all the necessary locks way down here.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1423
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1424
		if (gethrtime() - vd->vdev_last_try > 60ULL * NANOSEC) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1425
			vd->vdev_last_try = gethrtime();
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1426
			tvd->vdev_reopen_wanted = 1;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1427
			spa_async_request(vd->vdev_spa, SPA_ASYNC_REOPEN);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1428
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
zio_vdev_io_reissue(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
	ASSERT(zio->io_error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
	zio->io_stage--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1444
zio_vdev_io_redone(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_DONE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1448
	zio->io_stage--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1449
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1451
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
zio_vdev_io_bypass(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
	ASSERT(zio->io_error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1456
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
	zio->io_flags |= ZIO_FLAG_IO_BYPASS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
	zio->io_stage = ZIO_STAGE_VDEV_IO_ASSESS - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1459
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
 * Generate and verify checksums
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
zio_checksum_generate(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
	int checksum = zio->io_checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	blkptr_t *bp = zio->io_bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
	ASSERT3U(zio->io_size, ==, BP_GET_PSIZE(bp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
	BP_SET_CHECKSUM(bp, checksum);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
	BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
	zio_checksum(checksum, &bp->blk_cksum, zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1482
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1483
zio_gang_checksum_generate(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1484
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1485
	zio_cksum_t zc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1486
	zio_gbh_phys_t *gbh = zio->io_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1487
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1488
	ASSERT(BP_IS_GANG(zio->io_bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1489
	ASSERT3U(zio->io_size, ==, SPA_GANGBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1490
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1491
	zio_set_gang_verifier(zio, &gbh->zg_tail.zbt_cksum);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1492
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1493
	zio_checksum(ZIO_CHECKSUM_GANG_HEADER, &zc, zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1494
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1495
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1496
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1497
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1498
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1499
zio_checksum_verify(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1500
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1501
	if (zio->io_bp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1502
		zio->io_error = zio_checksum_error(zio);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1503
		if (zio->io_error && !(zio->io_flags & ZIO_FLAG_SPECULATIVE))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1504
			zfs_ereport_post(FM_EREPORT_ZFS_CHECKSUM,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1505
			    zio->io_spa, zio->io_vd, zio, 0, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1506
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1508
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1509
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1510
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1511
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1512
 * Called by RAID-Z to ensure we don't compute the checksum twice.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1513
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1514
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1515
zio_checksum_verified(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1516
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
	zio->io_pipeline &= ~(1U << ZIO_STAGE_CHECKSUM_VERIFY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1518
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1520
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1521
 * Set the external verifier for a gang block based on stuff in the bp
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1522
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1523
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1524
zio_set_gang_verifier(zio_t *zio, zio_cksum_t *zcp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1525
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1526
	blkptr_t *bp = zio->io_bp;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1527
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1528
	zcp->zc_word[0] = DVA_GET_VDEV(BP_IDENTITY(bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1529
	zcp->zc_word[1] = DVA_GET_OFFSET(BP_IDENTITY(bp));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1530
	zcp->zc_word[2] = bp->blk_birth;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
	zcp->zc_word[3] = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1533
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1536
 * Define the pipeline
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1538
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1539
typedef void zio_pipe_stage_t(zio_t *zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1540
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1541
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
zio_badop(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
	panic("Invalid I/O pipeline stage %u for zio %p", zio->io_stage, zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1545
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1547
zio_pipe_stage_t *zio_pipeline[ZIO_STAGE_DONE + 2] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1548
	zio_badop,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
	zio_wait_children_ready,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
	zio_write_compress,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
	zio_checksum_generate,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
	zio_gang_pipeline,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1553
	zio_get_gang_header,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1554
	zio_rewrite_gang_members,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1555
	zio_free_gang_members,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1556
	zio_claim_gang_members,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
	zio_dva_allocate,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
	zio_dva_free,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
	zio_dva_claim,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
	zio_gang_checksum_generate,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1561
	zio_ready,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
	zio_vdev_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
	zio_vdev_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
	zio_vdev_io_assess,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
	zio_wait_children_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
	zio_checksum_verify,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
	zio_read_gang_members,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
	zio_read_decompress,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1569
	zio_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1570
	zio_badop
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1572
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1574
 * Move an I/O to the next stage of the pipeline and execute that stage.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1575
 * There's no locking on io_stage because there's no legitimate way for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1576
 * multiple threads to be attempting to process the same I/O.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1577
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1578
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1579
zio_next_stage(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1580
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1581
	uint32_t pipeline = zio->io_pipeline;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1582
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1583
	ASSERT(!MUTEX_HELD(&zio->io_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1585
	if (zio->io_error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1586
		dprintf("zio %p vdev %s offset %llx stage %d error %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1587
		    zio, vdev_description(zio->io_vd),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1588
		    zio->io_offset, zio->io_stage, zio->io_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1589
		if (((1U << zio->io_stage) & ZIO_VDEV_IO_PIPELINE) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1590
			pipeline &= ZIO_ERROR_PIPELINE_MASK;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1591
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1592
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1593
	while (((1U << ++zio->io_stage) & pipeline) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1594
		continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1595
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1596
	ASSERT(zio->io_stage <= ZIO_STAGE_DONE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1597
	ASSERT(zio->io_stalled == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1598
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1599
	zio_pipeline[zio->io_stage](zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1600
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1601
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1602
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1603
zio_next_stage_async(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1604
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1605
	taskq_t *tq;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1606
	uint32_t pipeline = zio->io_pipeline;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1607
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1608
	ASSERT(!MUTEX_HELD(&zio->io_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1609
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1610
	if (zio->io_error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1611
		dprintf("zio %p vdev %s offset %llx stage %d error %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1612
		    zio, vdev_description(zio->io_vd),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1613
		    zio->io_offset, zio->io_stage, zio->io_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1614
		if (((1U << zio->io_stage) & ZIO_VDEV_IO_PIPELINE) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1615
			pipeline &= ZIO_ERROR_PIPELINE_MASK;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1616
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1617
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1618
	while (((1U << ++zio->io_stage) & pipeline) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1619
		continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1620
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1621
	ASSERT(zio->io_stage <= ZIO_STAGE_DONE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1622
	ASSERT(zio->io_stalled == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1623
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1624
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1625
	 * For performance, we'll probably want two sets of task queues:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1626
	 * per-CPU issue taskqs and per-CPU completion taskqs.  The per-CPU
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1627
	 * part is for read performance: since we have to make a pass over
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1628
	 * the data to checksum it anyway, we want to do this on the same CPU
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1629
	 * that issued the read, because (assuming CPU scheduling affinity)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1630
	 * that thread is probably still there.  Getting this optimization
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1631
	 * right avoids performance-hostile cache-to-cache transfers.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1632
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1633
	 * Note that having two sets of task queues is also necessary for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1634
	 * correctness: if all of the issue threads get bogged down waiting
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1635
	 * for dependent reads (e.g. metaslab freelist) to complete, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1636
	 * there won't be any threads available to service I/O completion
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1637
	 * interrupts.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1638
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1639
	if ((1U << zio->io_stage) & zio->io_async_stages) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1640
		if (zio->io_stage < ZIO_STAGE_VDEV_IO_DONE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1641
			tq = zio->io_spa->spa_zio_issue_taskq[zio->io_type];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1642
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1643
			tq = zio->io_spa->spa_zio_intr_taskq[zio->io_type];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1644
		(void) taskq_dispatch(tq,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1645
		    (task_func_t *)zio_pipeline[zio->io_stage], zio, TQ_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
		zio_pipeline[zio->io_stage](zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1651
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
 * Try to allocate an intent log block.  Return 0 on success, errno on failure.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1653
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1654
int
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1655
zio_alloc_blk(spa_t *spa, uint64_t size, blkptr_t *bp, uint64_t txg)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1656
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1657
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1658
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1659
	spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1660
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1661
	BP_ZERO(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1662
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1663
	error = metaslab_alloc(spa, size, bp, 1, txg, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1664
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
	if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
		BP_SET_LSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1667
		BP_SET_PSIZE(bp, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1668
		BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF);
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1669
		BP_SET_CHECKSUM(bp, ZIO_CHECKSUM_ZILOG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1670
		BP_SET_TYPE(bp, DMU_OT_INTENT_LOG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1671
		BP_SET_LEVEL(bp, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1672
		BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1673
		bp->blk_birth = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1674
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1675
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1676
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1677
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1678
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1680
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1681
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1682
 * Free an intent log block.  We know it can't be a gang block, so there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1683
 * nothing to do except metaslab_free() it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1684
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1686
zio_free_blk(spa_t *spa, blkptr_t *bp, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1688
	ASSERT(!BP_IS_GANG(bp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1690
	spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1691
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1692
	metaslab_free(spa, bp, txg, B_FALSE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1693
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 896
diff changeset
  1694
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1695
}