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