usr/src/uts/common/fs/zfs/zvol.c
author amw
Thu, 25 Oct 2007 16:34:29 -0700
changeset 5331 3047ad28a67b
parent 4935 c80bf0e6f4aa
child 5688 c0b02c8fd2c0
permissions -rw-r--r--
PSARC/2007/218 caller_context_t in all VOPs PSARC/2007/227 VFS Feature Registration and ACL on Create PSARC/2007/244 ZFS Case-insensitive support PSARC/2007/315 Extensible Attribute Interfaces PSARC/2007/394 ls(1) new command line options '-/' and '-%': CIFS system attributes support PSARC/2007/403 Modified Access Checks for CIFS PSARC/2007/410 Add system attribute support to chmod(1) PSARC/2007/432 CIFS system attributes support for cp(1), pack(1), unpack(1), compress(1) and uncompress(1) PSARC/2007/444 Rescind SETTABLE Attribute PSARC/2007/459 CIFS system attributes support for cpio(1), pax(1), tar(1) PSARC/2007/546 Update utilities to match CIFS system attributes changes. PSARC/2007/560 ZFS sharesmb property 4890717 want append-only files 6417428 Case-insensitive file system name lookup to support CIFS 6417435 DOS attributes and additional timestamps to support for CIFS 6417442 File system quarantined and modified attributes to support an integrated Anti-Virus service 6417453 FS boolean property for rejecting/allowing invalid UTF-8 sequences in file names 6473733 RFE: Need support for open-deny modes 6473755 RFE: Need ability to reconcile oplock and delegation conflicts 6494624 sharemgr needs to support CIFS shares better 6546705 All vnode operations need to pass caller_context_t 6546706 Need VOP_SETATTR/VOP_GETATTR to support new, optional attributes 6546893 Solaris system attribute support 6550962 ZFS ACL inheritance needs to be enhanced to support Automatic Inheritance 6553589 RFE: VFS Feature Registration facility 6553770 RFE: ZFS support for ACL-on-CREATE (PSARC 2007/227) 6565581 ls(1) should support file system attributes proposed in PSARC/2007/315 6566784 NTFS streams are not copied along with the files. 6576205 cp(1), pack(1) and compress(1) should support file system attributes proposed in PSARC/2007/315 6578875 RFE: kernel interfaces for nbmand need improvement 6578883 RFE: VOP_SHRLOCK needs additional access types 6578885 chmod(1) should support file system attributes proposed in PSARC/2007/315 6578886 RFE: disallow nbmand state to change on remount 6583349 ACL parser needs to support audit/alarm ACE types 6590347 tar(1) should support filesystem attributes proposed in PSARC/2007/315 6597357 *tar* xv@ doesn't show the hidden directory even though it is restored 6597360 *tar* should re-init xattr info if openat() fails during extraction of and extended attribute 6597368 *tar* cannot restore hard linked extended attributes 6597374 *tar* doesn't display "x " when hard linked attributes are restored 6597375 *tar* extended attribute header off by one 6614861 *cpio* incorrectly archives extended system attributes with -@ 6614896 *pax* incorrectly archives extended system attributes with -@ 6615225 *tar* incorrectly archives extended system attributes with -@ 6617183 CIFS Service - PSARC 2006/715
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
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   117
zvol_size_changed(zvol_state_t *zv, major_t maj)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
{
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   119
	dev_t dev = makedevice(maj, zv->zv_minor);
789
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
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   222
/* ARGSUSED */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
void
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   224
zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4935
diff changeset
   226
	zfs_creat_t *zct = arg;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4935
diff changeset
   227
	nvlist_t *nvprops = zct->zct_props;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	int error;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   229
	uint64_t volblocksize, volsize;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   231
	VERIFY(nvlist_lookup_uint64(nvprops,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   232
	    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) == 0);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   233
	if (nvlist_lookup_uint64(nvprops,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   234
	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &volblocksize) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   235
		volblocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   236
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   237
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   238
	 * These properites must be removed from the list so the generic
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   239
	 * property setting step won't apply to them.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   240
	 */
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   241
	VERIFY(nvlist_remove_all(nvprops,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   242
	    zfs_prop_to_name(ZFS_PROP_VOLSIZE)) == 0);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4391
diff changeset
   243
	(void) nvlist_remove_all(nvprops,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   244
	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   245
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   246
	error = dmu_object_claim(os, ZVOL_OBJ, DMU_OT_ZVOL, volblocksize,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	    DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	error = zap_create_claim(os, ZVOL_ZAP_OBJ, DMU_OT_ZVOL_PROP,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	    DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   254
	error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
/*
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   259
 * Replay a TX_WRITE ZIL transaction that didn't get committed
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   260
 * after a system failure
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   261
 */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   262
static int
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   263
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
   264
{
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   265
	objset_t *os = zv->zv_objset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   266
	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   267
	uint64_t off = lr->lr_offset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   268
	uint64_t len = lr->lr_length;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   269
	dmu_tx_t *tx;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   270
	int error;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   271
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   272
	if (byteswap)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   273
		byteswap_uint64_array(lr, sizeof (*lr));
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   274
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   275
	tx = dmu_tx_create(os);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   276
	dmu_tx_hold_write(tx, ZVOL_OBJ, off, len);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   277
	error = dmu_tx_assign(tx, zv->zv_txg_assign);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   278
	if (error) {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   279
		dmu_tx_abort(tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   280
	} else {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   281
		dmu_write(os, ZVOL_OBJ, off, len, data, tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   282
		dmu_tx_commit(tx);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   283
	}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   284
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   285
	return (error);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   286
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   287
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   288
/* ARGSUSED */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   289
static int
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   290
zvol_replay_err(zvol_state_t *zv, lr_t *lr, boolean_t byteswap)
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   291
{
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   292
	return (ENOTSUP);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   293
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   294
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   295
/*
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   296
 * Callback vectors for replaying records.
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   297
 * Only TX_WRITE is needed for zvol.
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   298
 */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   299
zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = {
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   300
	zvol_replay_err,	/* 0 no such transaction type */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   301
	zvol_replay_err,	/* TX_CREATE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   302
	zvol_replay_err,	/* TX_MKDIR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   303
	zvol_replay_err,	/* TX_MKXATTR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   304
	zvol_replay_err,	/* TX_SYMLINK */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   305
	zvol_replay_err,	/* TX_REMOVE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   306
	zvol_replay_err,	/* TX_RMDIR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   307
	zvol_replay_err,	/* TX_LINK */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   308
	zvol_replay_err,	/* TX_RENAME */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   309
	zvol_replay_write,	/* TX_WRITE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   310
	zvol_replay_err,	/* TX_TRUNCATE */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   311
	zvol_replay_err,	/* TX_SETATTR */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   312
	zvol_replay_err,	/* TX_ACL */
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   313
};
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   314
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   315
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
 * Create a minor node for the specified volume.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
int
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   319
zvol_create_minor(const char *name, major_t maj)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	objset_t *os;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   323
	dmu_object_info_t doi;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	uint64_t volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	minor_t minor = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	struct pathname linkpath;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	int ds_mode = DS_MODE_PRIMARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	vnode_t *vp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	char *devpath;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + 1 + strlen(name) + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	char chrbuf[30], blkbuf[30];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	if ((zv = zvol_minor_lookup(name)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
		return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	if (strchr(name, '@') != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		ds_mode |= DS_MODE_READONLY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	error = dmu_objset_open(name, DMU_OST_ZVOL, ds_mode, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	 * If there's an existing /dev/zvol symlink, try to use the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
	 * same minor number we used last time.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
	devpath = kmem_alloc(devpathlen, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
	(void) sprintf(devpath, "%s/%s", ZVOL_FULL_DEV_DIR, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	error = lookupname(devpath, UIO_SYSSPACE, NO_FOLLOW, NULL, &vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
	kmem_free(devpath, devpathlen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	if (error == 0 && vp->v_type != VLNK)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
		error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
		pn_alloc(&linkpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
		error = pn_getsymlink(vp, &linkpath, kcred);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
			char *ms = strstr(linkpath.pn_path, ZVOL_PSEUDO_DEV);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
			if (ms != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
				ms += strlen(ZVOL_PSEUDO_DEV);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
				minor = stoi(&ms);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
		pn_free(&linkpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
	if (vp != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
		VN_RELE(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	 * 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
   392
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	if (minor != 0 && ddi_get_soft_state(zvol_state, minor) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		minor = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	if (minor == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
		minor = zvol_minor_alloc();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
	if (minor == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
	if (ddi_soft_state_zalloc(zvol_state, minor) != DDI_SUCCESS) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
		return (EAGAIN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   411
	(void) ddi_prop_update_string(minor, zfs_dip, ZVOL_PROP_NAME,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   412
	    (char *)name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
	(void) sprintf(chrbuf, "%uc,raw", minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
	if (ddi_create_minor_node(zfs_dip, chrbuf, S_IFCHR,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
		ddi_soft_state_free(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
		return (EAGAIN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	(void) sprintf(blkbuf, "%uc", minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
	if (ddi_create_minor_node(zfs_dip, blkbuf, S_IFBLK,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
		ddi_remove_minor_node(zfs_dip, chrbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
		ddi_soft_state_free(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
		return (EAGAIN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
	(void) strcpy(zv->zv_name, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	zv->zv_min_bs = DEV_BSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	zv->zv_minor = minor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	zv->zv_volsize = volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
	zv->zv_objset = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   442
	zv->zv_mode = ds_mode;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   443
	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
   444
	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
   445
	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
   446
	    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
   447
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   448
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   449
	/* get and cache the blocksize */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   450
	error = dmu_object_info(os, ZVOL_OBJ, &doi);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   451
	ASSERT(error == 0);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   452
	zv->zv_volblocksize = doi.doi_data_block_size;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   453
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3245
diff changeset
   454
	zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   456
	zvol_size_changed(zv, maj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   458
	/* XXX this should handle the possible i/o error */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	VERIFY(dsl_prop_register(dmu_objset_ds(zv->zv_objset),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
	    "readonly", zvol_readonly_changed_cb, zv) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	zvol_minors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
 * Remove minor node for the specified volume.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   473
zvol_remove_minor(const char *name)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
	char namebuf[30];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   480
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	if (zv->zv_total_opens != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
		return (EBUSY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
	(void) sprintf(namebuf, "%uc,raw", zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	ddi_remove_minor_node(zfs_dip, namebuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
	(void) sprintf(namebuf, "%uc", zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
	ddi_remove_minor_node(zfs_dip, namebuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
	VERIFY(dsl_prop_unregister(dmu_objset_ds(zv->zv_objset),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
	    "readonly", zvol_readonly_changed_cb, zv) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   499
	zil_close(zv->zv_zilog);
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   500
	zv->zv_zilog = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
	dmu_objset_close(zv->zv_objset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
	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
   503
	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
   504
	mutex_destroy(&zv->zv_znode.z_range_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
	ddi_soft_state_free(zvol_state, zv->zv_minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
	zvol_minors--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
int
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   516
zvol_set_volsize(const char *name, major_t maj, uint64_t volsize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	int error;
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   521
	dmu_object_info_t doi;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   525
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   530
	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
   531
	    (error = zvol_check_volsize(volsize,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   532
	    doi.doi_data_block_size)) != 0) {
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   533
		mutex_exit(&zvol_state_lock);
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   534
		return (error);
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   535
	}
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 849
diff changeset
   536
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	if (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
	tx = dmu_tx_create(zv->zv_objset);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   543
	dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   544
	dmu_tx_hold_free(tx, ZVOL_OBJ, volsize, DMU_OBJECT_END);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
		dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
	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
   553
	    &volsize, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   554
	if (error == 0) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   555
		error = dmu_free_range(zv->zv_objset, ZVOL_OBJ, volsize,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
		    DMU_OBJECT_END, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1357
diff changeset
   557
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	if (error == 0) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   562
		zv->zv_volsize = volsize;
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4543
diff changeset
   563
		zvol_size_changed(zv, maj);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   572
zvol_set_volblocksize(const char *name, uint64_t volblocksize)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   580
	if ((zv = zvol_minor_lookup(name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
	if (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
	tx = dmu_tx_create(zv->zv_objset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	dmu_tx_hold_bonus(tx, ZVOL_OBJ);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
		dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
		error = dmu_object_set_blocksize(zv->zv_objset, ZVOL_OBJ,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
   597
		    volblocksize, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
		if (error == ENOTSUP)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
			error = EBUSY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
		dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	minor_t minor = getminor(*devp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
	if (minor == 0)			/* This is the control device */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
	ASSERT(zv->zv_objset != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
	if ((flag & FWRITE) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	    (zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	if (zv->zv_open_count[otyp] == 0 || otyp == OTYP_LYR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
		zv->zv_open_count[otyp]++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
		zv->zv_total_opens++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
zvol_close(dev_t dev, int flag, int otyp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	minor_t minor = getminor(dev);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	zvol_state_t *zv;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
	if (minor == 0)		/* This is the control device */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	zv = ddi_get_soft_state(zvol_state, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
	 * The next statement is a workaround for the following DDI bug:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
	 * 6343604 specfs race: multiple "last-close" of the same device
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	if (zv->zv_total_opens == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
	 * If the open count is zero, this is a spurious close.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
	 * That indicates a bug in the kernel / DDI framework.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
	ASSERT(zv->zv_open_count[otyp] != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
	ASSERT(zv->zv_total_opens != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
	 * You may get multiple opens, but only one close.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
	zv->zv_open_count[otyp]--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
	zv->zv_total_opens--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   689
static void
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   690
zvol_get_done(dmu_buf_t *db, void *vzgd)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   691
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   692
	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
   693
	rl_t *rl = zgd->zgd_rl;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   694
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   695
	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
   696
	zfs_range_unlock(rl);
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   697
	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
   698
	kmem_free(zgd, sizeof (zgd_t));
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
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   701
/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   702
 * Get data to generate a TX_WRITE intent log record.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   703
 */
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   704
static int
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   705
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
   706
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   707
	zvol_state_t *zv = arg;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   708
	objset_t *os = zv->zv_objset;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   709
	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
   710
	rl_t *rl;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   711
	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
   712
	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
   713
	int dlen = lr->lr_length;	/* length of user data */
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   714
	int error;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   715
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   716
	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
   717
	ASSERT(dlen != 0);
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   718
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
   719
	/*
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
	 * 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
   721
	 * 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
   722
	 * 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
   723
	 * 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
   724
	 * 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
   725
	 */
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
   726
	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
   727
		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
   728
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   729
	zgd = (zgd_t *)kmem_alloc(sizeof (zgd_t), KM_SLEEP);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   730
	zgd->zgd_zilog = zv->zv_zilog;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   731
	zgd->zgd_bp = &lr->lr_blkptr;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   732
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
   733
	/*
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
	 * 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
   735
	 * 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
   736
	 * 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
   737
	 */
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
	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
   739
	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
   740
	    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
   741
	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
   742
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   743
	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
   744
	error = dmu_sync(zio, db, &lr->lr_blkptr,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   745
	    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
   746
	if (error == 0)
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   747
		zil_add_vdev(zv->zv_zilog,
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   748
		    DVA_GET_VDEV(BP_IDENTITY(&lr->lr_blkptr)));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   749
	/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   750
	 * If we get EINPROGRESS, then we need to wait for a
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   751
	 * write IO initiated by dmu_sync() to complete before
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   752
	 * we can release this dbuf.  We will finish everything
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   753
	 * up in the zvol_get_done() callback.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   754
	 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   755
	if (error == EINPROGRESS)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   756
		return (0);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   757
	dmu_buf_rele(db, zgd);
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
   758
	zfs_range_unlock(rl);
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   759
	kmem_free(zgd, sizeof (zgd_t));
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   760
	return (error);
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   761
}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   762
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   763
/*
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   764
 * zvol_log_write() handles synchronous writes using TX_WRITE ZIL transactions.
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   765
 *
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   766
 * 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
   767
 * Otherwise we will later flush the data out via dmu_sync().
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   768
 */
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   769
ssize_t zvol_immediate_write_sz = 32768;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   770
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   771
static void
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   772
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
   773
{
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   774
	uint32_t blocksize = zv->zv_volblocksize;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   775
	lr_write_t *lr;
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   776
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   777
	while (len) {
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   778
		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
   779
		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
   780
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   781
		itx->itx_wr_state =
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   782
		    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
   783
		itx->itx_private = zv;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   784
		lr = (lr_write_t *)&itx->itx_lr;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   785
		lr->lr_foid = ZVOL_OBJ;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   786
		lr->lr_offset = off;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   787
		lr->lr_length = nbytes;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   788
		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
   789
		BP_ZERO(&lr->lr_blkptr);
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   790
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   791
		(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
   792
		len -= nbytes;
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   793
		off += nbytes;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   794
	}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   795
}
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   796
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
zvol_strategy(buf_t *bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
	zvol_state_t *zv = ddi_get_soft_state(zvol_state, getminor(bp->b_edev));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
	uint64_t off, volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
	size_t size, resid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
	char *addr;
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   804
	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
   805
	rl_t *rl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
	int error = 0;
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
   807
	boolean_t reading;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
		bioerror(bp, ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	if (getminor(bp->b_edev) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
		bioerror(bp, EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   821
	if ((zv->zv_readonly || (zv->zv_mode & DS_MODE_READONLY)) &&
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   822
	    !(bp->b_flags & B_READ)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
		bioerror(bp, EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
		biodone(bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
	off = ldbtob(bp->b_blkno);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
	volsize = zv->zv_volsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   831
	os = zv->zv_objset;
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   832
	ASSERT(os != NULL);
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
	 */
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   842
	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
   843
	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
   844
	    reading ? RL_READER : RL_WRITER);
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   845
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
	while (resid != 0 && off < volsize) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   848
		size = MIN(resid, zvol_maxphys); /* zvol_maxphys per tx */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
		if (size > volsize - off)	/* don't write past the end */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
			size = volsize - off;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
1861
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   853
		if (reading) {
7929434f26fb 6413125 zvol_strategy() race can lead to on-disk corruption.
perrin
parents: 1669
diff changeset
   854
			error = dmu_read(os, ZVOL_OBJ, off, size, addr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
		} else {
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   856
			dmu_tx_t *tx = dmu_tx_create(os);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
			dmu_tx_hold_write(tx, ZVOL_OBJ, off, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
			error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
			if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
				dmu_tx_abort(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
			} else {
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   862
				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
   863
				zvol_log_write(zv, tx, off, size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
				dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
		if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
		off += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
		addr += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
		resid -= size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
	}
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
   873
	zfs_range_unlock(rl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
	if ((bp->b_resid = resid) == bp->b_bcount)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
		bioerror(bp, off > volsize ? EINVAL : error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
4391
ddb512bd7379 6565574 zvol read perf problem
perrin
parents: 4107
diff changeset
   878
	if (!(bp->b_flags & B_ASYNC) && !reading && !zil_disable)
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   879
		zil_commit(zv->zv_zilog, UINT64_MAX, ZVOL_OBJ);
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   880
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   881
	biodone(bp);
1141
ca4bb9237a10 6354547 sticky log buf size
perrin
parents: 1133
diff changeset
   882
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   886
/*
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   887
 * Set the buffer count to the zvol maximum transfer.
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   888
 * Using our own routine instead of the default minphys()
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   889
 * 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
   890
 * (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
   891
 * (every zvol_maxphys - currently 1MB) instead of minphys (currently
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   892
 * 56K on X86 and 128K on sparc).
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   893
 */
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   894
void
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   895
zvol_minphys(struct buf *bp)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   896
{
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   897
	if (bp->b_bcount > zvol_maxphys)
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   898
		bp->b_bcount = zvol_maxphys;
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   899
}
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 3016
diff changeset
   900
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
int
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   903
zvol_read(dev_t dev, uio_t *uio, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
{
4107
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   905
	minor_t minor = getminor(dev);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   906
	zvol_state_t *zv;
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
4107
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   910
	if (minor == 0)			/* This is the control device */
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   911
		return (ENXIO);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   912
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   913
	zv = ddi_get_soft_state(zvol_state, minor);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   914
	if (zv == NULL)
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   915
		return (ENXIO);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   916
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
   917
	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
   918
	    RL_READER);
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   919
	while (uio->uio_resid > 0) {
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   920
		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
   921
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   922
		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
   923
		if (error)
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   924
			break;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   925
	}
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
   926
	zfs_range_unlock(rl);
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   927
	return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
int
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   932
zvol_write(dev_t dev, uio_t *uio, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
{
4107
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   934
	minor_t minor = getminor(dev);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   935
	zvol_state_t *zv;
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
   936
	rl_t *rl;
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   937
	int error = 0;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   938
4107
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   939
	if (minor == 0)			/* This is the control device */
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   940
		return (ENXIO);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   941
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   942
	zv = ddi_get_soft_state(zvol_state, minor);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   943
	if (zv == NULL)
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   944
		return (ENXIO);
5b13dedb1ea7 6549112 writes to /dev/zfs panic system
gw25295
parents: 3897
diff changeset
   945
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
   946
	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
   947
	    RL_WRITER);
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   948
	while (uio->uio_resid > 0) {
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   949
		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
   950
		uint64_t off = uio->uio_loffset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   952
		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
   953
		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
   954
		error = dmu_tx_assign(tx, TXG_WAIT);
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   955
		if (error) {
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   956
			dmu_tx_abort(tx);
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   957
			break;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   958
		}
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   959
		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
   960
		if (error == 0)
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   961
			zvol_log_write(zv, tx, off, bytes);
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   962
		dmu_tx_commit(tx);
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   963
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   964
		if (error)
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   965
			break;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   966
	}
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
   967
	zfs_range_unlock(rl);
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
   968
	return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
 * Dirtbag ioctls to support mkfs(1M) for UFS filesystems.  See dkio(7I).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
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
   977
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
	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
   979
	struct dk_cinfo dki;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
	struct dk_minfo dkm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
	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
   982
	struct dk_callback *dkc;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
	struct uuid uuid = EFI_RESERVED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
	uint32_t crc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
	mutex_enter(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
	zv = ddi_get_soft_state(zvol_state, getminor(dev));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
	if (zv == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	switch (cmd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	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
   999
		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
  1000
		(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
  1001
		(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
  1002
		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
  1003
		dki.dki_maxtransfer = 1 << (SPA_MAXBLOCKSHIFT - zv->zv_min_bs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
		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
  1005
		if (ddi_copyout(&dki, (void *)arg, sizeof (dki), flag))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
			error = EFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
	case DKIOCGMEDIAINFO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
		bzero(&dkm, sizeof (dkm));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
		dkm.dki_lbsize = 1U << zv->zv_min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
		dkm.dki_capacity = zv->zv_volsize >> zv->zv_min_bs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
		dkm.dki_media_type = DK_UNKNOWN;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
		mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
		if (ddi_copyout(&dkm, (void *)arg, sizeof (dkm), flag))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
			error = EFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
	case DKIOCGETEFI:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
		if (ddi_copyin((void *)arg, &efi, sizeof (dk_efi_t), flag)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
			mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
			return (EFAULT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
		efi.dki_data = (void *)(uintptr_t)efi.dki_data_64;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1026
		/*
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1027
		 * 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
  1028
		 * zvol.  Currently this interface will return ENOTTY to
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1029
		 * such requests.  These requests could be supported by
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1030
		 * 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
  1031
		 * RMBR.
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1032
		 */
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1033
		if (efi.dki_lba == 1) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1034
			efi_gpt_t gpt;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1035
			efi_gpe_t gpe;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1036
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1037
			bzero(&gpt, sizeof (gpt));
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1038
			bzero(&gpe, 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
			if (efi.dki_length < sizeof (gpt)) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1041
				mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1042
				return (EINVAL);
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
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1045
			gpt.efi_gpt_Signature = LE_64(EFI_SIGNATURE);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1046
			gpt.efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1047
			gpt.efi_gpt_HeaderSize = LE_32(sizeof (gpt));
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1048
			gpt.efi_gpt_FirstUsableLBA = LE_64(34ULL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1049
			gpt.efi_gpt_LastUsableLBA =
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1050
			    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
  1051
			gpt.efi_gpt_NumberOfPartitionEntries = LE_32(1);
3080
deef42200cee 6490291 Unable to newfs zvols, returns exit code of 32.
maybee
parents: 3063
diff changeset
  1052
			gpt.efi_gpt_PartitionEntryLBA = LE_64(2ULL);
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1053
			gpt.efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (gpe));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1055
			UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1056
			gpe.efi_gpe_StartingLBA = gpt.efi_gpt_FirstUsableLBA;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1057
			gpe.efi_gpe_EndingLBA = gpt.efi_gpt_LastUsableLBA;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1058
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1059
			CRC32(crc, &gpe, sizeof (gpe), -1U, crc32_table);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1060
			gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1061
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1062
			CRC32(crc, &gpt, sizeof (gpt), -1U, crc32_table);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1063
			gpt.efi_gpt_HeaderCRC32 = LE_32(~crc);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1064
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1065
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1066
			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
  1067
				error = EFAULT;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1068
		} else if (efi.dki_lba == 2) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1069
			efi_gpe_t gpe;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1070
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1071
			bzero(&gpe, sizeof (gpe));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1073
			if (efi.dki_length < sizeof (gpe)) {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1074
				mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1075
				return (EINVAL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1076
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1078
			UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1079
			gpe.efi_gpe_StartingLBA = LE_64(34ULL);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1080
			gpe.efi_gpe_EndingLBA =
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1081
			    LE_64((zv->zv_volsize >> zv->zv_min_bs) - 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1083
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1084
			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
  1085
				error = EFAULT;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1086
		} else {
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1087
			mutex_exit(&zvol_state_lock);
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1088
			error = EINVAL;
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1089
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
  1092
	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
  1093
		dkc = (struct dk_callback *)arg;
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
  1094
		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
  1095
		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
  1096
			(*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
  1097
			error = 0;
278bade789ba 6437750 panic: db->db_buf==0||arc_referenced(db->db_buf), file: dbuf.c,line:1539
maybee
parents: 3755
diff changeset
  1098
		}
3638
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
  1099
		break;
6b28ebc717aa 6496357 spec_fsync() is useless on devices that do write caching
billm
parents: 3461
diff changeset
  1100
3245
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1101
	case DKIOCGGEOM:
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1102
	case DKIOCGVTOC:
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1103
		/* commands using these (like prtvtoc) expect ENOTSUP */
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1104
		error = ENOTSUP;
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1105
		break;
0c86ad4b2673 6493634 zvol should return ENOTSUP on DKIOCGVTOC ioctl
maybee
parents: 3080
diff changeset
  1106
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	default:
3016
e46176752558 6480048 newfs failed to create new ufs in zvol.
maybee
parents: 2885
diff changeset
  1108
		error = ENOTTY;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
	mutex_exit(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
zvol_busy(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
	return (zvol_minors != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
zvol_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
	VERIFY(ddi_soft_state_init(&zvol_state, sizeof (zvol_state_t), 1) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
	mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
zvol_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
	mutex_destroy(&zvol_state_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
	ddi_soft_state_fini(&zvol_state);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
}