usr/src/uts/common/fs/zfs/zvol.c
author maybee
Thu, 14 Dec 2006 11:54:54 -0800
changeset 3245 0c86ad4b2673
parent 3080 deef42200cee
child 3461 c19b22f347d6
permissions -rw-r--r--
6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl 6496365 assertion failed: refcount_count(&tx->tx_space_written) + delta <= tx->tx_space_towrite
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: 1357
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
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
/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1175
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
 * ZFS volume emulation driver.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * Makes a DMU object look like a volume of arbitrary size, up to 2^64 bytes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 * Volumes are accessed through the symbolic links named:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 * /dev/zvol/dsk/<pool_name>/<dataset_name>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * /dev/zvol/rdsk/<pool_name>/<dataset_name>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
 * These links are created by the ZFS-specific devfsadm link generator.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
 * Volumes are persistent through reboot.  No user command needs to be
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
 * run before opening and using a device.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#include <sys/param.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/aio_req.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <sys/uio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <sys/buf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
#include <sys/modctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include <sys/open.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/kmem.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include <sys/conf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <sys/cmn_err.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
#include <sys/zio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
#include <sys/dsl_prop.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
#include <sys/dkio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
#include <sys/efi_partition.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
#include <sys/byteorder.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
#include <sys/pathname.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
#include <sys/ddi.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
#include <sys/sunddi.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
#include <sys/crc32.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
#include <sys/dirent.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
#include <sys/policy.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
#include <sys/zfs_ioctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
#include <sys/mkdev.h>
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
    70
#include <sys/zil.h>
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
    71
#include <sys/refcount.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
#include "zfs_namecheck.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
#define	ZVOL_OBJ		1ULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
#define	ZVOL_ZAP_OBJ		2ULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
static void *zvol_state;
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
 * This lock protects the zvol_state structure from being modified
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
 * while it's being used, e.g. an open that comes in before a create
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
 * finishes.  It also protects temporary opens of the dataset so that,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
 * e.g., an open doesn't get a spurious EBUSY.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
static kmutex_t zvol_state_lock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
static uint32_t zvol_minors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
 * The in-core state of each volume.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
typedef struct zvol_state {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	char		zv_name[MAXPATHLEN]; /* pool/dd name */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	uint64_t	zv_volsize;	/* amount of space we advertise */
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
    95
	uint64_t	zv_volblocksize; /* volume block size */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	minor_t		zv_minor;	/* minor number */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	uint8_t		zv_min_bs;	/* minimum addressable block shift */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
	uint8_t		zv_readonly;	/* hard readonly; like write-protect */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	objset_t	*zv_objset;	/* objset handle */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	uint32_t	zv_mode;	/* DS_MODE_* flags at open time */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	uint32_t	zv_open_count[OTYPCNT];	/* open counts */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	uint32_t	zv_total_opens;	/* total open count */
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   103
	zilog_t		*zv_zilog;	/* ZIL handle */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   104
	uint64_t	zv_txg_assign;	/* txg to assign during ZIL replay */
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   105
	krwlock_t	zv_dslock;	/* dmu_sync() rwlock */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
} zvol_state_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   108
/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   109
 * zvol maximum transfer in one DMU tx.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   110
 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   111
int zvol_maxphys = DMU_MAX_ACCESS/2;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   112
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   113
int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   114
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
zvol_size_changed(zvol_state_t *zv, dev_t dev)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
	dev = makedevice(getmajor(dev), zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
	VERIFY(ddi_prop_update_int64(dev, zfs_dip,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	    "Size", zv->zv_volsize) == DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
	VERIFY(ddi_prop_update_int64(dev, zfs_dip,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	    "Nblocks", lbtodb(zv->zv_volsize)) == DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   127
zvol_check_volsize(uint64_t volsize, uint64_t blocksize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
{
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   129
	if (volsize == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   132
	if (volsize % blocksize != 0)
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   133
		return (EINVAL);
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   134
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
#ifdef _ILP32
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   136
	if (volsize - 1 > SPEC_MAXOFFSET_T)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
		return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   143
zvol_check_volblocksize(uint64_t volblocksize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
{
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   145
	if (volblocksize < SPA_MINBLOCKSIZE ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   146
	    volblocksize > SPA_MAXBLOCKSIZE ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   147
	    !ISP2(volblocksize))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
		return (EDOM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
zvol_readonly_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	zvol_state_t *zv = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
	zv->zv_readonly = (uint8_t)newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
int
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   162
zvol_get_stats(objset_t *os, nvlist_t *nv)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
	dmu_object_info_t doi;
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   166
	uint64_t val;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   169
	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &val);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   173
	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLSIZE, val);
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   174
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	error = dmu_object_info(os, ZVOL_OBJ, &doi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   177
	if (error == 0) {
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   178
		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLBLOCKSIZE,
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   179
		    doi.doi_data_block_size);
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   180
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
 * Find a free minor number.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
static minor_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
zvol_minor_alloc(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	minor_t minor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	ASSERT(MUTEX_HELD(&zvol_state_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	for (minor = 1; minor <= ZVOL_MAX_MINOR; minor++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
		if (ddi_get_soft_state(zvol_state, minor) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
			return (minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
static zvol_state_t *
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   203
zvol_minor_lookup(const char *name)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	minor_t minor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
	ASSERT(MUTEX_HELD(&zvol_state_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	for (minor = 1; minor <= ZVOL_MAX_MINOR; minor++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
		zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
		if (zv == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
		if (strcmp(zv->zv_name, name) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
	return (zv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
zvol_create_cb(objset_t *os, void *arg, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
{
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   224
	zfs_create_data_t *zc = arg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	int error;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   226
	uint64_t volblocksize, volsize;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   228
	VERIFY(nvlist_lookup_uint64(zc->zc_props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   229
	    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   230
	if (nvlist_lookup_uint64(zc->zc_props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   231
	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &volblocksize) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   232
		volblocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   233
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   234
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   235
	 * These properites must be removed from the list so the generic
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   236
	 * property setting step won't apply to them.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   237
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   238
	VERIFY(nvlist_remove_all(zc->zc_props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   239
	    zfs_prop_to_name(ZFS_PROP_VOLSIZE)) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   240
	(void) nvlist_remove_all(zc->zc_props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   241
	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   242
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   243
	error = dmu_object_claim(os, ZVOL_OBJ, DMU_OT_ZVOL, volblocksize,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	    DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	error = zap_create_claim(os, ZVOL_ZAP_OBJ, DMU_OT_ZVOL_PROP,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	    DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   251
	error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
/*
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   256
 * Replay a TX_WRITE ZIL transaction that didn't get committed
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   257
 * after a system failure
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   258
 */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   259
static int
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   260
zvol_replay_write(zvol_state_t *zv, lr_write_t *lr, boolean_t byteswap)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   261
{
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   262
	objset_t *os = zv->zv_objset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   263
	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   264
	uint64_t off = lr->lr_offset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   265
	uint64_t len = lr->lr_length;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   266
	dmu_tx_t *tx;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   267
	int error;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   268
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   269
	if (byteswap)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   270
		byteswap_uint64_array(lr, sizeof (*lr));
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   271
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   272
	tx = dmu_tx_create(os);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   273
	dmu_tx_hold_write(tx, ZVOL_OBJ, off, len);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   274
	error = dmu_tx_assign(tx, zv->zv_txg_assign);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   275
	if (error) {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   276
		dmu_tx_abort(tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   277
	} else {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   278
		dmu_write(os, ZVOL_OBJ, off, len, data, tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   279
		dmu_tx_commit(tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   280
	}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   281
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   282
	return (error);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   283
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   284
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   285
/* ARGSUSED */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   286
static int
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   287
zvol_replay_err(zvol_state_t *zv, lr_t *lr, boolean_t byteswap)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   288
{
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   289
	return (ENOTSUP);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   290
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   291
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   292
/*
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   293
 * Callback vectors for replaying records.
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   294
 * Only TX_WRITE is needed for zvol.
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   295
 */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   296
zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   297
	zvol_replay_err,	/* 0 no such transaction type */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   298
	zvol_replay_err,	/* TX_CREATE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   299
	zvol_replay_err,	/* TX_MKDIR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   300
	zvol_replay_err,	/* TX_MKXATTR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   301
	zvol_replay_err,	/* TX_SYMLINK */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   302
	zvol_replay_err,	/* TX_REMOVE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   303
	zvol_replay_err,	/* TX_RMDIR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   304
	zvol_replay_err,	/* TX_LINK */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   305
	zvol_replay_err,	/* TX_RENAME */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   306
	zvol_replay_write,	/* TX_WRITE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   307
	zvol_replay_err,	/* TX_TRUNCATE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   308
	zvol_replay_err,	/* TX_SETATTR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   309
	zvol_replay_err,	/* TX_ACL */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   310
};
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   311
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   312
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
 * Create a minor node for the specified volume.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   316
zvol_create_minor(const char *name, dev_t dev)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	objset_t *os;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   320
	dmu_object_info_t doi;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	uint64_t volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	minor_t minor = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	struct pathname linkpath;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	int ds_mode = DS_MODE_PRIMARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	vnode_t *vp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	char *devpath;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + 1 + strlen(name) + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	char chrbuf[30], blkbuf[30];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	if ((zv = zvol_minor_lookup(name)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
		return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	if (strchr(name, '@') != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
		ds_mode |= DS_MODE_READONLY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	error = dmu_objset_open(name, DMU_OST_ZVOL, ds_mode, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	 * If there's an existing /dev/zvol symlink, try to use the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	 * same minor number we used last time.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	devpath = kmem_alloc(devpathlen, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	(void) sprintf(devpath, "%s/%s", ZVOL_FULL_DEV_DIR, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
	error = lookupname(devpath, UIO_SYSSPACE, NO_FOLLOW, NULL, &vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
	kmem_free(devpath, devpathlen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
	if (error == 0 && vp->v_type != VLNK)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
		error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
		pn_alloc(&linkpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
		error = pn_getsymlink(vp, &linkpath, kcred);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
		if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
			char *ms = strstr(linkpath.pn_path, ZVOL_PSEUDO_DEV);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
			if (ms != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
				ms += strlen(ZVOL_PSEUDO_DEV);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
				minor = stoi(&ms);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
		pn_free(&linkpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	if (vp != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
		VN_RELE(vp);
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
	 * If we found a minor but it's already in use, we must pick a new one.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
	if (minor != 0 && ddi_get_soft_state(zvol_state, minor) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
		minor = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	if (minor == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		minor = zvol_minor_alloc();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	if (minor == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
	if (ddi_soft_state_zalloc(zvol_state, minor) != DDI_SUCCESS) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
		return (EAGAIN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   408
	(void) ddi_prop_update_string(minor, zfs_dip, ZVOL_PROP_NAME,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   409
	    (char *)name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
	(void) sprintf(chrbuf, "%uc,raw", minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
	if (ddi_create_minor_node(zfs_dip, chrbuf, S_IFCHR,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
		ddi_soft_state_free(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
		return (EAGAIN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
	(void) sprintf(blkbuf, "%uc", minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	if (ddi_create_minor_node(zfs_dip, blkbuf, S_IFBLK,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
		ddi_remove_minor_node(zfs_dip, chrbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
		ddi_soft_state_free(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
		return (EAGAIN);
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
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
	(void) strcpy(zv->zv_name, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
	zv->zv_min_bs = DEV_BSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
	zv->zv_minor = minor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
	zv->zv_volsize = volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	zv->zv_objset = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	zv->zv_mode = ds_mode;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   440
	zv->zv_zilog = zil_open(os, zvol_get_data);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   441
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   442
	/* get and cache the blocksize */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   443
	error = dmu_object_info(os, ZVOL_OBJ, &doi);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   444
	ASSERT(error == 0);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   445
	zv->zv_volblocksize = doi.doi_data_block_size;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   446
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   447
	rw_init(&zv->zv_dslock, NULL, RW_DEFAULT, NULL);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   448
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   449
	zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
	zvol_size_changed(zv, dev);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   453
	/* XXX this should handle the possible i/o error */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
	VERIFY(dsl_prop_register(dmu_objset_ds(zv->zv_objset),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	    "readonly", zvol_readonly_changed_cb, zv) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	zvol_minors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
 * Remove minor node for the specified volume.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   468
zvol_remove_minor(const char *name)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	char namebuf[30];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   475
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
	if (zv->zv_total_opens != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
		return (EBUSY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	(void) sprintf(namebuf, "%uc,raw", zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
	ddi_remove_minor_node(zfs_dip, namebuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	(void) sprintf(namebuf, "%uc", zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	ddi_remove_minor_node(zfs_dip, namebuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	VERIFY(dsl_prop_unregister(dmu_objset_ds(zv->zv_objset),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
	    "readonly", zvol_readonly_changed_cb, zv) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   494
	zil_close(zv->zv_zilog);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   495
	zv->zv_zilog = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
	dmu_objset_close(zv->zv_objset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
	zv->zv_objset = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
	ddi_soft_state_free(zvol_state, zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
	zvol_minors--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   509
zvol_set_volsize(const char *name, dev_t dev, uint64_t volsize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
	int error;
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   514
	dmu_object_info_t doi;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   518
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   523
	if ((error = dmu_object_info(zv->zv_objset, ZVOL_OBJ, &doi)) != 0 ||
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   524
	    (error = zvol_check_volsize(volsize,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   525
	    doi.doi_data_block_size)) != 0) {
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   526
		mutex_exit(&zvol_state_lock);
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   527
		return (error);
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   528
	}
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   529
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	if (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	tx = dmu_tx_create(zv->zv_objset);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   536
	dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   537
	dmu_tx_hold_free(tx, ZVOL_OBJ, volsize, DMU_OBJECT_END);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
	error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
		dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	error = zap_update(zv->zv_objset, ZVOL_ZAP_OBJ, "size", 8, 1,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   546
	    &volsize, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   547
	if (error == 0) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   548
		error = dmu_free_range(zv->zv_objset, ZVOL_OBJ, volsize,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
		    DMU_OBJECT_END, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   550
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	if (error == 0) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   555
		zv->zv_volsize = volsize;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
		zvol_size_changed(zv, dev);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   565
zvol_set_volblocksize(const char *name, uint64_t volblocksize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   573
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	if (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	tx = dmu_tx_create(zv->zv_objset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
	dmu_tx_hold_bonus(tx, ZVOL_OBJ);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
	error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
		dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
		error = dmu_object_set_blocksize(zv->zv_objset, ZVOL_OBJ,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   590
		    volblocksize, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
		if (error == ENOTSUP)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
			error = EBUSY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
		dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	return (error);
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
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	minor_t minor = getminor(*devp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	if (minor == 0)			/* This is the control device */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	ASSERT(zv->zv_objset != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	if ((flag & FWRITE) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	    (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
	if (zv->zv_open_count[otyp] == 0 || otyp == OTYP_LYR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
		zv->zv_open_count[otyp]++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
		zv->zv_total_opens++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
zvol_close(dev_t dev, int flag, int otyp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
	minor_t minor = getminor(dev);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
	if (minor == 0)		/* This is the control device */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	 * The next statement is a workaround for the following DDI bug:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
	 * 6343604 specfs race: multiple "last-close" of the same device
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
	if (zv->zv_total_opens == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
	 * If the open count is zero, this is a spurious close.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	 * That indicates a bug in the kernel / DDI framework.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
	ASSERT(zv->zv_open_count[otyp] != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
	ASSERT(zv->zv_total_opens != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
	 * You may get multiple opens, but only one close.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
	zv->zv_open_count[otyp]--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
	zv->zv_total_opens--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   682
/*
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   683
 * Create and return an immediate write ZIL transaction.
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   684
 */
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   685
itx_t *
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   686
zvol_immediate_itx(offset_t off, ssize_t len, char *addr)
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   687
{
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   688
	itx_t *itx;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   689
	lr_write_t *lr;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   690
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   691
	itx = zil_itx_create(TX_WRITE, sizeof (*lr) + len);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   692
	lr = (lr_write_t *)&itx->itx_lr;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   693
	lr->lr_foid = ZVOL_OBJ;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   694
	lr->lr_offset = off;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   695
	lr->lr_length = len;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   696
	lr->lr_blkoff = 0;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   697
	BP_ZERO(&lr->lr_blkptr);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   698
	bcopy(addr, (char *)itx + offsetof(itx_t, itx_lr) +
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   699
	    sizeof (*lr), len);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   700
	itx->itx_wr_state = WR_COPIED;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   701
	return (itx);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   702
}
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   703
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   704
void
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   705
zvol_get_done(dmu_buf_t *db, void *vzgd)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   706
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   707
	zgd_t *zgd = (zgd_t *)vzgd;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   708
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   709
	dmu_buf_rele(db, vzgd);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   710
	zil_add_vdev(zgd->zgd_zilog, DVA_GET_VDEV(BP_IDENTITY(zgd->zgd_bp)));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   711
	kmem_free(zgd, sizeof (zgd_t));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   712
}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   713
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   714
/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   715
 * Get data to generate a TX_WRITE intent log record.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   716
 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   717
int
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   718
zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   719
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   720
	zvol_state_t *zv = arg;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   721
	objset_t *os = zv->zv_objset;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   722
	dmu_buf_t *db;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   723
	zgd_t *zgd;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   724
	int dlen = lr->lr_length;  		/* length of user data */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   725
	int error;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   726
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   727
	ASSERT(zio);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   728
	ASSERT(dlen != 0);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   729
	ASSERT(buf == NULL);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   730
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   731
	zgd = (zgd_t *)kmem_alloc(sizeof (zgd_t), KM_SLEEP);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   732
	zgd->zgd_zilog = zv->zv_zilog;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   733
	zgd->zgd_bp = &lr->lr_blkptr;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   734
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   735
	VERIFY(0 == dmu_buf_hold(os, ZVOL_OBJ, lr->lr_offset, zgd, &db));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   736
	/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   737
	 * Have to lock to ensure when when the data is
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   738
	 * written out and it's checksum is being calculated
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   739
	 * that no one can change the data.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   740
	 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   741
	rw_enter(&zv->zv_dslock, RW_READER);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   742
	error = dmu_sync(zio, db, &lr->lr_blkptr,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   743
	    lr->lr_common.lrc_txg, zvol_get_done, zgd);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   744
	rw_exit(&zv->zv_dslock);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   745
	if (error == 0) {
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   746
		zil_add_vdev(zv->zv_zilog,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   747
		    DVA_GET_VDEV(BP_IDENTITY(&lr->lr_blkptr)));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   748
	}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   749
	/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   750
	 * If we get EINPROGRESS, then we need to wait for a
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   751
	 * write IO initiated by dmu_sync() to complete before
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   752
	 * we can release this dbuf.  We will finish everything
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   753
	 * up in the zvol_get_done() callback.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   754
	 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   755
	if (error == EINPROGRESS)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   756
		return (0);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   757
	dmu_buf_rele(db, zgd);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   758
	kmem_free(zgd, sizeof (zgd_t));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   759
	return (error);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   760
}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   761
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   762
/*
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   763
 * zvol_log_write() handles synchronous writes using TX_WRITE ZIL transactions.
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   764
 *
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   765
 * We store data in the log buffers if it's small enough.
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   766
 * Otherwise we will later flush the data out via dmu_sync().
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   767
 */
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   768
ssize_t zvol_immediate_write_sz = 32768;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   769
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   770
void
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   771
zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t len,
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   772
    char *addr)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   773
{
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   774
	ssize_t nbytes;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   775
	itx_t *itx;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   776
	lr_write_t *lr;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   777
	zilog_t *zilog = zv->zv_zilog;
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
   778
	uint64_t boff;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   779
	uint32_t blocksize;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   780
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   781
	/* handle common case */
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   782
	if (len <= zvol_immediate_write_sz) {
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   783
		itx = zvol_immediate_itx(off, len, addr);
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   784
		(void) zil_itx_assign(zilog, itx, tx);
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   785
	}
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   786
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   787
	blocksize = zv->zv_volblocksize;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   788
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   789
	while (len) {
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   790
		nbytes = MIN(len, blocksize - P2PHASE(off, blocksize));
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   791
		if (nbytes <= zvol_immediate_write_sz) {
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   792
			itx = zvol_immediate_itx(off, nbytes, addr);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   793
		} else {
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   794
			boff = P2ALIGN_TYPED(off, blocksize, uint64_t);
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   795
			itx = zil_itx_create(TX_WRITE, sizeof (*lr));
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   796
			itx->itx_wr_state = WR_INDIRECT;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   797
			itx->itx_private = zv;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   798
			lr = (lr_write_t *)&itx->itx_lr;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   799
			lr->lr_foid = ZVOL_OBJ;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   800
			lr->lr_offset = off;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   801
			lr->lr_length = nbytes;
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
   802
			lr->lr_blkoff = off - boff;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   803
			BP_ZERO(&lr->lr_blkptr);
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   804
		}
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   805
		(void) zil_itx_assign(zilog, itx, tx);
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   806
		len -= nbytes;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   807
		off += nbytes;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   808
	}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   809
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   810
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
zvol_strategy(buf_t *bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
	zvol_state_t *zv = ddi_get_soft_state(zvol_state, getminor(bp->b_edev));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	uint64_t off, volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
	size_t size, resid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
	char *addr;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   818
	objset_t *os;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
	int error = 0;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   820
	int sync;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   821
	int reading;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
		bioerror(bp, ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
	if (getminor(bp->b_edev) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
		bioerror(bp, EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   835
	if ((zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) &&
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   836
	    !(bp->b_flags & B_READ)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
		bioerror(bp, EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	off = ldbtob(bp->b_blkno);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
	volsize = zv->zv_volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   845
	os = zv->zv_objset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   846
	ASSERT(os != NULL);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   847
	sync = !(bp->b_flags & B_ASYNC) && !(zil_disable);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
	bp_mapin(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
	addr = bp->b_un.b_addr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
	resid = bp->b_bcount;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   853
	/*
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   854
	 * There must be no buffer changes when doing a dmu_sync() because
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   855
	 * we can't change the data whilst calculating the checksum.
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   856
	 * A better approach than a per zvol rwlock would be to lock ranges.
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   857
	 */
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   858
	reading = bp->b_flags & B_READ;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   859
	if (reading || resid <= zvol_immediate_write_sz)
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   860
		rw_enter(&zv->zv_dslock, RW_READER);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   861
	else
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   862
		rw_enter(&zv->zv_dslock, RW_WRITER);
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   863
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
	while (resid != 0 && off < volsize) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   866
		size = MIN(resid, zvol_maxphys); /* zvol_maxphys per tx */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		if (size > volsize - off)	/* don't write past the end */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
			size = volsize - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   871
		if (reading) {
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   872
			error = dmu_read(os, ZVOL_OBJ, off, size, addr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
		} else {
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   874
			dmu_tx_t *tx = dmu_tx_create(os);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
			dmu_tx_hold_write(tx, ZVOL_OBJ, off, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
			error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
			if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
				dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
			} else {
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   880
				dmu_write(os, ZVOL_OBJ, off, size, addr, tx);
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   881
				/* add a log write transaction */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   882
				if (sync)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   883
					zvol_log_write(zv, tx, off, size, addr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
				dmu_tx_commit(tx);
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
		if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
		off += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
		addr += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
		resid -= size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
	}
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   893
	rw_exit(&zv->zv_dslock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
	if ((bp->b_resid = resid) == bp->b_bcount)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
		bioerror(bp, off > volsize ? EINVAL : error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
	biodone(bp);
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   899
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   900
	if (sync)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   901
		zil_commit(zv->zv_zilog, UINT64_MAX, 0);
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   902
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   906
/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   907
 * Set the buffer count to the zvol maximum transfer.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   908
 * Using our own routine instead of the default minphys()
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   909
 * means that for larger writes we write bigger buffers on X86
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   910
 * (128K instead of 56K) and flush the disk write cache less often
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   911
 * (every zvol_maxphys - currently 1MB) instead of minphys (currently
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   912
 * 56K on X86 and 128K on sparc).
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   913
 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   914
void
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   915
zvol_minphys(struct buf *bp)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   916
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   917
	if (bp->b_bcount > zvol_maxphys)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   918
		bp->b_bcount = zvol_maxphys;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   919
}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   920
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
zvol_read(dev_t dev, uio_t *uiop, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
{
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   925
	return (physio(zvol_strategy, NULL, dev, B_READ, zvol_minphys, uiop));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
zvol_write(dev_t dev, uio_t *uiop, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
{
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   932
	return (physio(zvol_strategy, NULL, dev, B_WRITE, zvol_minphys, uiop));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
zvol_aread(dev_t dev, struct aio_req *aio, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
{
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   939
	return (aphysio(zvol_strategy, anocancel, dev, B_READ, zvol_minphys,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   940
	    aio));
789
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
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
zvol_awrite(dev_t dev, struct aio_req *aio, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
{
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   947
	return (aphysio(zvol_strategy, anocancel, dev, B_WRITE, zvol_minphys,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   948
	    aio));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
}
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
 * Dirtbag ioctls to support mkfs(1M) for UFS filesystems.  See dkio(7I).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   955
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   957
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   958
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
	struct dk_cinfo dkc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
	struct dk_minfo dkm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
	dk_efi_t efi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
	struct uuid uuid = EFI_RESERVED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
	uint32_t crc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
	zv = ddi_get_soft_state(zvol_state, getminor(dev));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
	switch (cmd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
	case DKIOCINFO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
		bzero(&dkc, sizeof (dkc));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
		(void) strcpy(dkc.dki_cname, "zvol");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
		(void) strcpy(dkc.dki_dname, "zvol");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
		dkc.dki_ctype = DKC_UNKNOWN;
1357
46e683ebd8ea 6367517 32-bit kernel VA exhaustion with logging ufs atop zvol
bonwick
parents: 1356
diff changeset
   982
		dkc.dki_maxtransfer = 1 << (SPA_MAXBLOCKSHIFT - zv->zv_min_bs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
		if (ddi_copyout(&dkc, (void *)arg, sizeof (dkc), flag))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
			error = EFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
	case DKIOCGMEDIAINFO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
		bzero(&dkm, sizeof (dkm));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
		dkm.dki_lbsize = 1U << zv->zv_min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
		dkm.dki_capacity = zv->zv_volsize >> zv->zv_min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
		dkm.dki_media_type = DK_UNKNOWN;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
		if (ddi_copyout(&dkm, (void *)arg, sizeof (dkm), flag))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
			error = EFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	case DKIOCGETEFI:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
		if (ddi_copyin((void *)arg, &efi, sizeof (dk_efi_t), flag)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
			mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
			return (EFAULT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
		efi.dki_data = (void *)(uintptr_t)efi.dki_data_64;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1005
		/*
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1006
		 * Some clients may attempt to request a PMBR for the
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1007
		 * zvol.  Currently this interface will return ENOTTY to
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1008
		 * such requests.  These requests could be supported by
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1009
		 * adding a check for lba == 0 and consing up an appropriate
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1010
		 * RMBR.
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1011
		 */
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1012
		if (efi.dki_lba == 1) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1013
			efi_gpt_t gpt;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1014
			efi_gpe_t gpe;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1015
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1016
			bzero(&gpt, sizeof (gpt));
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1017
			bzero(&gpe, sizeof (gpe));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1019
			if (efi.dki_length < sizeof (gpt)) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1020
				mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1021
				return (EINVAL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1022
			}
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1023
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1024
			gpt.efi_gpt_Signature = LE_64(EFI_SIGNATURE);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1025
			gpt.efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1026
			gpt.efi_gpt_HeaderSize = LE_32(sizeof (gpt));
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1027
			gpt.efi_gpt_FirstUsableLBA = LE_64(34ULL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1028
			gpt.efi_gpt_LastUsableLBA =
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1029
			    LE_64((zv->zv_volsize >> zv->zv_min_bs) - 1);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1030
			gpt.efi_gpt_NumberOfPartitionEntries = LE_32(1);
3080
deef42200cee 6490291 Unable to newfs zvols, returns exit code of 32.
maybee
parents: 3063
diff changeset
  1031
			gpt.efi_gpt_PartitionEntryLBA = LE_64(2ULL);
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1032
			gpt.efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (gpe));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1034
			UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1035
			gpe.efi_gpe_StartingLBA = gpt.efi_gpt_FirstUsableLBA;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1036
			gpe.efi_gpe_EndingLBA = gpt.efi_gpt_LastUsableLBA;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1037
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1038
			CRC32(crc, &gpe, sizeof (gpe), -1U, crc32_table);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1039
			gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1040
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1041
			CRC32(crc, &gpt, sizeof (gpt), -1U, crc32_table);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1042
			gpt.efi_gpt_HeaderCRC32 = LE_32(~crc);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1043
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1044
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1045
			if (ddi_copyout(&gpt, efi.dki_data, sizeof (gpt), flag))
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1046
				error = EFAULT;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1047
		} else if (efi.dki_lba == 2) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1048
			efi_gpe_t gpe;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1049
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1050
			bzero(&gpe, sizeof (gpe));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1052
			if (efi.dki_length < sizeof (gpe)) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1053
				mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1054
				return (EINVAL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1055
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1057
			UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1058
			gpe.efi_gpe_StartingLBA = LE_64(34ULL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1059
			gpe.efi_gpe_EndingLBA =
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1060
			    LE_64((zv->zv_volsize >> zv->zv_min_bs) - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1062
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1063
			if (ddi_copyout(&gpe, efi.dki_data, sizeof (gpe), flag))
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1064
				error = EFAULT;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1065
		} else {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1066
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1067
			error = EINVAL;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1068
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1071
	case DKIOCGGEOM:
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1072
	case DKIOCGVTOC:
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1073
		/* commands using these (like prtvtoc) expect ENOTSUP */
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1074
		error = ENOTSUP;
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1075
		break;
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1076
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
	default:
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1078
		error = ENOTTY;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
zvol_busy(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1088
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
	return (zvol_minors != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
zvol_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1094
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1095
	VERIFY(ddi_soft_state_init(&zvol_state, sizeof (zvol_state_t), 1) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
	mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
zvol_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	mutex_destroy(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	ddi_soft_state_fini(&zvol_state);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
}