usr/src/uts/common/fs/dev/sdev_zvolops.c
author Jerry Jelinek <jerry.jelinek@joyent.com>
Mon, 11 Jun 2012 18:23:37 +0000
changeset 14222 c3f8a4690b1f
parent 10763 f1a11aaa04fc
child 14223 1652c59077c6
permissions -rw-r--r--
3977 zones can commit suicide by zvol Reviewed by: Gordon Ross <[email protected]> Reviewed by: Richard Lowe <[email protected]> Approved by: Garrett D'Amore <[email protected]>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     1
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     2
 * CDDL HEADER START
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     3
 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     7
 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    11
 * and limitations under the License.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    12
 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    18
 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    19
 * CDDL HEADER END
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    20
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    21
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    22
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    23
 * Use is subject to license terms.
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    24
 * Copyright 2013 Joyent, Inc.  All rights reserved.
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    25
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    26
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    27
/* vnode ops for the /dev/zvol directory */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    28
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    29
#include <sys/types.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    30
#include <sys/param.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    31
#include <sys/sysmacros.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    32
#include <sys/ddi.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    33
#include <sys/sunndi.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    34
#include <sys/sunldi.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    35
#include <fs/fs_subr.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    36
#include <sys/fs/dv_node.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    37
#include <sys/fs/sdev_impl.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    38
#include <sys/zfs_ioctl.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    39
#include <sys/policy.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    40
#include <sys/stat.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    41
#include <sys/vfs_opreg.h>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    42
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    43
struct vnodeops	*devzvol_vnodeops;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    44
static uint64_t devzvol_gen = 0;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    45
static uint64_t devzvol_zclist;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    46
static size_t devzvol_zclist_size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    47
static ldi_ident_t devzvol_li;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    48
static ldi_handle_t devzvol_lh;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    49
static kmutex_t devzvol_mtx;
10763
f1a11aaa04fc 6890204 X4240 Server SunVTS regression panic[cpu3]: BAD TRAP: type=d (#gp General protection)
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10588
diff changeset
    50
static boolean_t devzvol_isopen;
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    51
static major_t devzvol_major;
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    52
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    53
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    54
 * we need to use ddi_mod* since fs/dev gets loaded early on in
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    55
 * startup(), and linking fs/dev to fs/zfs would drag in a lot of
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    56
 * other stuff (like drv/random) before the rest of the system is
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    57
 * ready to go
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    58
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    59
ddi_modhandle_t zfs_mod;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    60
int (*szcm)(char *);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    61
int (*szn2m)(char *, minor_t *);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    62
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    63
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    64
sdev_zvol_create_minor(char *dsname)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    65
{
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    66
	if (szcm == NULL)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    67
		return (-1);
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    68
	return ((*szcm)(dsname));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    69
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    70
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    71
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    72
sdev_zvol_name2minor(char *dsname, minor_t *minor)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    73
{
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    74
	if (szn2m == NULL)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    75
		return (-1);
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    76
	return ((*szn2m)(dsname, minor));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    77
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    78
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    79
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    80
devzvol_open_zfs()
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    81
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    82
	int rc;
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
    83
	dev_t dv;
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    84
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    85
	devzvol_li = ldi_ident_from_anon();
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    86
	if (ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    87
	    &devzvol_lh, devzvol_li))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    88
		return (-1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    89
	if (zfs_mod == NULL && ((zfs_mod = ddi_modopen("fs/zfs",
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    90
	    KRTLD_MODE_FIRST, &rc)) == NULL)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    91
		return (rc);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    92
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    93
	ASSERT(szcm == NULL && szn2m == NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    94
	if ((szcm = (int (*)(char *))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    95
	    ddi_modsym(zfs_mod, "zvol_create_minor", &rc)) == NULL) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    96
		cmn_err(CE_WARN, "couldn't resolve zvol_create_minor");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    97
		return (rc);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    98
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
    99
	if ((szn2m = (int(*)(char *, minor_t *))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   100
	    ddi_modsym(zfs_mod, "zvol_name2minor", &rc)) == NULL) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   101
		cmn_err(CE_WARN, "couldn't resolve zvol_name2minor");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   102
		return (rc);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   103
	}
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   104
	if (ldi_get_dev(devzvol_lh, &dv))
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   105
		return (-1);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   106
	devzvol_major = getmajor(dv);
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   107
	return (0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   108
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   109
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   110
void
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   111
devzvol_close_zfs()
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   112
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   113
	szcm = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   114
	szn2m = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   115
	(void) ldi_close(devzvol_lh, FREAD|FWRITE, kcred);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   116
	ldi_ident_release(devzvol_li);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   117
	if (zfs_mod != NULL) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   118
		(void) ddi_modclose(zfs_mod);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   119
		zfs_mod = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   120
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   121
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   122
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   123
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   124
devzvol_handle_ioctl(int cmd, zfs_cmd_t *zc, size_t *alloc_size)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   125
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   126
	uint64_t cookie;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   127
	int size = 8000;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   128
	int unused;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   129
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   130
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   131
	if (cmd != ZFS_IOC_POOL_CONFIGS)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   132
		mutex_enter(&devzvol_mtx);
10763
f1a11aaa04fc 6890204 X4240 Server SunVTS regression panic[cpu3]: BAD TRAP: type=d (#gp General protection)
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10588
diff changeset
   133
	if (!devzvol_isopen) {
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   134
		if ((rc = devzvol_open_zfs()) == 0) {
10763
f1a11aaa04fc 6890204 X4240 Server SunVTS regression panic[cpu3]: BAD TRAP: type=d (#gp General protection)
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10588
diff changeset
   135
			devzvol_isopen = B_TRUE;
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   136
		} else {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   137
			if (cmd != ZFS_IOC_POOL_CONFIGS)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   138
				mutex_exit(&devzvol_mtx);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   139
			return (ENXIO);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   140
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   141
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   142
	cookie = zc->zc_cookie;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   143
again:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   144
	zc->zc_nvlist_dst = (uint64_t)(intptr_t)kmem_alloc(size,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   145
	    KM_SLEEP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   146
	zc->zc_nvlist_dst_size = size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   147
	rc = ldi_ioctl(devzvol_lh, cmd, (intptr_t)zc, FKIOCTL, kcred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   148
	    &unused);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   149
	if (rc == ENOMEM) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   150
		int newsize;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   151
		newsize = zc->zc_nvlist_dst_size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   152
		ASSERT(newsize > size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   153
		kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   154
		size = newsize;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   155
		zc->zc_cookie = cookie;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   156
		goto again;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   157
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   158
	if (alloc_size == NULL)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   159
		kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   160
	else
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   161
		*alloc_size = size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   162
	if (cmd != ZFS_IOC_POOL_CONFIGS)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   163
		mutex_exit(&devzvol_mtx);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   164
	return (rc);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   165
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   166
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   167
/* figures out if the objset exists and returns its type */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   168
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   169
devzvol_objset_check(char *dsname, dmu_objset_type_t *type)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   170
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   171
	boolean_t	ispool;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   172
	zfs_cmd_t	*zc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   173
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   174
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   175
	zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   176
	(void) strlcpy(zc->zc_name, dsname, MAXPATHLEN);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   177
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   178
	ispool = (strchr(dsname, '/') == NULL) ? B_TRUE : B_FALSE;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   179
	if (!ispool && sdev_zvol_name2minor(dsname, NULL) == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   180
		sdcmn_err13(("found cached minor node"));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   181
		if (type)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   182
			*type = DMU_OST_ZVOL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   183
		kmem_free(zc, sizeof (zfs_cmd_t));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   184
		return (0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   185
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   186
	rc = devzvol_handle_ioctl(ispool ? ZFS_IOC_POOL_STATS :
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   187
	    ZFS_IOC_OBJSET_STATS, zc, NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   188
	if (type && rc == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   189
		*type = (ispool) ? DMU_OST_ZFS :
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   190
		    zc->zc_objset_stats.dds_type;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   191
	kmem_free(zc, sizeof (zfs_cmd_t));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   192
	return (rc);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   193
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   194
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   195
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   196
 * returns what the zfs dataset name should be, given the /dev/zvol
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   197
 * path and an optional name; otherwise NULL
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   198
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   199
char *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   200
devzvol_make_dsname(const char *path, const char *name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   201
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   202
	char *dsname;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   203
	const char *ptr;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   204
	int dslen;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   205
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   206
	if (strcmp(path, ZVOL_DIR) == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   207
		return (NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   208
	if (name && (strcmp(name, ".") == 0 || strcmp(name, "..") == 0))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   209
		return (NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   210
	ptr = path + strlen(ZVOL_DIR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   211
	if (strncmp(ptr, "/dsk", 4) == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   212
		ptr += strlen("/dsk");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   213
	else if (strncmp(ptr, "/rdsk", 5) == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   214
		ptr += strlen("/rdsk");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   215
	else
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   216
		return (NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   217
	if (*ptr == '/')
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   218
		ptr++;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   219
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   220
	dslen = strlen(ptr);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   221
	if (dslen)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   222
		dslen++;			/* plus null */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   223
	if (name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   224
		dslen += strlen(name) + 1;	/* plus slash */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   225
	dsname = kmem_zalloc(dslen, KM_SLEEP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   226
	if (*ptr) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   227
		(void) strlcpy(dsname, ptr, dslen);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   228
		if (name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   229
			(void) strlcat(dsname, "/", dslen);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   230
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   231
	if (name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   232
		(void) strlcat(dsname, name, dslen);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   233
	return (dsname);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   234
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   235
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   236
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   237
 * check if the zvol's sdev_node is still valid, which means make
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   238
 * sure the zvol is still valid.  zvol minors aren't proactively
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   239
 * destroyed when the zvol is destroyed, so we use a validator to clean
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   240
 * these up (in other words, when such nodes are encountered during
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   241
 * subsequent lookup() and readdir() operations) so that only valid
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   242
 * nodes are returned.  The ordering between devname_lookup_func and
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   243
 * devzvol_validate is a little inefficient in the case of invalid
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   244
 * or stale nodes because devname_lookup_func calls
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   245
 * devzvol_create_{dir, link}, then the validator says it's invalid,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   246
 * and then the node gets cleaned up.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   247
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   248
int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   249
devzvol_validate(struct sdev_node *dv)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   250
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   251
	dmu_objset_type_t do_type;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   252
	char *dsname;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   253
	char *nm = dv->sdev_name;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   254
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   255
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   256
	sdcmn_err13(("validating ('%s' '%s')", dv->sdev_path, nm));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   257
	/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   258
	 * validate only READY nodes; if someone is sitting on the
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   259
	 * directory of a dataset that just got destroyed we could
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   260
	 * get a zombie node which we just skip.
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   261
	 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   262
	if (dv->sdev_state != SDEV_READY) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   263
		sdcmn_err13(("skipping '%s'", nm));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   264
		return (SDEV_VTOR_SKIP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   265
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   266
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   267
	if ((strcmp(dv->sdev_path, ZVOL_DIR "/dsk") == 0) ||
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   268
	    (strcmp(dv->sdev_path, ZVOL_DIR "/rdsk") == 0))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   269
		return (SDEV_VTOR_VALID);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   270
	dsname = devzvol_make_dsname(dv->sdev_path, NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   271
	if (dsname == NULL)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   272
		return (SDEV_VTOR_INVALID);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   273
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   274
	rc = devzvol_objset_check(dsname, &do_type);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   275
	sdcmn_err13(("  '%s' rc %d", dsname, rc));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   276
	if (rc != 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   277
		kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   278
		return (SDEV_VTOR_INVALID);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   279
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   280
	sdcmn_err13(("  v_type %d do_type %d",
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   281
	    SDEVTOV(dv)->v_type, do_type));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   282
	if ((SDEVTOV(dv)->v_type == VLNK && do_type != DMU_OST_ZVOL) ||
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   283
	    ((SDEVTOV(dv)->v_type == VBLK || SDEVTOV(dv)->v_type == VCHR) &&
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   284
	    do_type != DMU_OST_ZVOL) ||
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   285
	    (SDEVTOV(dv)->v_type == VDIR && do_type == DMU_OST_ZVOL)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   286
		kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   287
		return (SDEV_VTOR_STALE);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   288
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   289
	if (SDEVTOV(dv)->v_type == VLNK) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   290
		char *ptr, *link;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   291
		long val = 0;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   292
		minor_t lminor, ominor;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   293
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   294
		rc = sdev_getlink(SDEVTOV(dv), &link);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   295
		ASSERT(rc == 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   296
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   297
		ptr = strrchr(link, ':') + 1;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   298
		rc = ddi_strtol(ptr, NULL, 10, &val);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   299
		kmem_free(link, strlen(link) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   300
		ASSERT(rc == 0 && val != 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   301
		lminor = (minor_t)val;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   302
		if (sdev_zvol_name2minor(dsname, &ominor) < 0 ||
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   303
		    ominor != lminor) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   304
			kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   305
			return (SDEV_VTOR_STALE);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   306
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   307
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   308
	kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   309
	return (SDEV_VTOR_VALID);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   310
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   311
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   312
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   313
 * creates directories as needed in response to a readdir
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   314
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   315
void
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   316
devzvol_create_pool_dirs(struct vnode *dvp)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   317
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   318
	zfs_cmd_t	*zc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   319
	nvlist_t *nv = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   320
	nvpair_t *elem = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   321
	size_t size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   322
	int pools = 0;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   323
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   324
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   325
	sdcmn_err13(("devzvol_create_pool_dirs"));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   326
	zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   327
	mutex_enter(&devzvol_mtx);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   328
	zc->zc_cookie = devzvol_gen;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   329
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   330
	rc = devzvol_handle_ioctl(ZFS_IOC_POOL_CONFIGS, zc, &size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   331
	switch (rc) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   332
		case 0:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   333
			/* new generation */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   334
			ASSERT(devzvol_gen != zc->zc_cookie);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   335
			devzvol_gen = zc->zc_cookie;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   336
			if (devzvol_zclist)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   337
				kmem_free((void *)(uintptr_t)devzvol_zclist,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   338
				    devzvol_zclist_size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   339
			devzvol_zclist = zc->zc_nvlist_dst;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   340
			devzvol_zclist_size = size;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   341
			break;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   342
		case EEXIST:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   343
			/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   344
			 * no change in the configuration; still need
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   345
			 * to do lookups in case we did a lookup in
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   346
			 * zvol/rdsk but not zvol/dsk (or vice versa)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   347
			 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   348
			kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   349
			    size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   350
			break;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   351
		default:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   352
			kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   353
			    size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   354
			goto out;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   355
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   356
	rc = nvlist_unpack((char *)(uintptr_t)devzvol_zclist,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   357
	    devzvol_zclist_size, &nv, 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   358
	if (rc) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   359
		ASSERT(rc == 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   360
		kmem_free((void *)(uintptr_t)devzvol_zclist,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   361
		    devzvol_zclist_size);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   362
		devzvol_gen = 0;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   363
		devzvol_zclist = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   364
		devzvol_zclist_size = 0;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   365
		goto out;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   366
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   367
	mutex_exit(&devzvol_mtx);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   368
	while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   369
		struct vnode *vp;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   370
		ASSERT(dvp->v_count > 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   371
		rc = VOP_LOOKUP(dvp, nvpair_name(elem), &vp, NULL, 0,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   372
		    NULL, kcred, NULL, 0, NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   373
		/* should either work, or not be visible from a zone */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   374
		ASSERT(rc == 0 || rc == ENOENT);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   375
		if (rc == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   376
			VN_RELE(vp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   377
		pools++;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   378
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   379
	nvlist_free(nv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   380
	mutex_enter(&devzvol_mtx);
10763
f1a11aaa04fc 6890204 X4240 Server SunVTS regression panic[cpu3]: BAD TRAP: type=d (#gp General protection)
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10588
diff changeset
   381
	if (devzvol_isopen && pools == 0) {
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   382
		/* clean up so zfs can be unloaded */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   383
		devzvol_close_zfs();
10763
f1a11aaa04fc 6890204 X4240 Server SunVTS regression panic[cpu3]: BAD TRAP: type=d (#gp General protection)
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10588
diff changeset
   384
		devzvol_isopen = B_FALSE;
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   385
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   386
out:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   387
	mutex_exit(&devzvol_mtx);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   388
	kmem_free(zc, sizeof (zfs_cmd_t));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   389
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   390
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   391
/*ARGSUSED3*/
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   392
static int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   393
devzvol_create_dir(struct sdev_node *ddv, char *nm, void **arg,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   394
    cred_t *cred, void *whatever, char *whichever)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   395
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   396
	timestruc_t now;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   397
	struct vattr *vap = (struct vattr *)arg;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   398
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   399
	sdcmn_err13(("create_dir (%s) (%s) '%s'", ddv->sdev_name,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   400
	    ddv->sdev_path, nm));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   401
	ASSERT(strncmp(ddv->sdev_path, ZVOL_DIR,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   402
	    strlen(ZVOL_DIR)) == 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   403
	*vap = *sdev_getdefault_attr(VDIR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   404
	gethrestime(&now);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   405
	vap->va_atime = now;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   406
	vap->va_mtime = now;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   407
	vap->va_ctime = now;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   408
	return (0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   409
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   410
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   411
/*ARGSUSED3*/
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   412
static int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   413
devzvol_create_link(struct sdev_node *ddv, char *nm,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   414
    void **arg, cred_t *cred, void *whatever, char *whichever)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   415
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   416
	minor_t minor;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   417
	char *pathname = (char *)*arg;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   418
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   419
	char *dsname;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   420
	char *x;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   421
	char str[MAXNAMELEN];
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   422
	sdcmn_err13(("create_link (%s) (%s) '%s'", ddv->sdev_name,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   423
	    ddv->sdev_path, nm));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   424
	dsname = devzvol_make_dsname(ddv->sdev_path, nm);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   425
	rc = sdev_zvol_create_minor(dsname);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   426
	if ((rc != 0 && rc != EEXIST && rc != EBUSY) ||
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   427
	    sdev_zvol_name2minor(dsname, &minor)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   428
		sdcmn_err13(("devzvol_create_link %d", rc));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   429
		kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   430
		return (-1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   431
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   432
	kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   433
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   434
	/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   435
	 * This is a valid zvol; create a symlink that points to the
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   436
	 * minor which was created under /devices/pseudo/zfs@0
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   437
	 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   438
	*pathname = '\0';
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   439
	for (x = ddv->sdev_path; x = strchr(x, '/'); x++)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   440
		(void) strcat(pathname, "../");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   441
	(void) snprintf(str, sizeof (str), ZVOL_PSEUDO_DEV "%u", minor);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   442
	(void) strncat(pathname, str, MAXPATHLEN);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   443
	if (strncmp(ddv->sdev_path, ZVOL_FULL_RDEV_DIR,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   444
	    strlen(ZVOL_FULL_RDEV_DIR)) == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   445
		(void) strcat(pathname, ",raw");
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   446
	return (0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   447
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   448
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   449
/* Clean zvol sdev_nodes that are no longer valid.  */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   450
static void
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   451
devzvol_prunedir(struct sdev_node *ddv)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   452
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   453
	struct sdev_node *dv;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   454
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   455
	ASSERT(RW_READ_HELD(&ddv->sdev_contents));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   456
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   457
	sdcmn_err13(("prunedir '%s'", ddv->sdev_name));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   458
	ASSERT(strncmp(ddv->sdev_path, ZVOL_DIR, strlen(ZVOL_DIR)) == 0);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   459
	if (rw_tryupgrade(&ddv->sdev_contents) == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   460
		rw_exit(&ddv->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   461
		rw_enter(&ddv->sdev_contents, RW_WRITER);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   462
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   463
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   464
	dv = SDEV_FIRST_ENTRY(ddv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   465
	while (dv) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   466
		sdcmn_err13(("sdev_name '%s'", dv->sdev_name));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   467
		/* skip stale nodes */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   468
		if (dv->sdev_flags & SDEV_STALE) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   469
			sdcmn_err13(("  stale"));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   470
			dv = SDEV_NEXT_ENTRY(ddv, dv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   471
			continue;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   472
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   473
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   474
		switch (devzvol_validate(dv)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   475
		case SDEV_VTOR_VALID:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   476
		case SDEV_VTOR_SKIP:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   477
			dv = SDEV_NEXT_ENTRY(ddv, dv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   478
			continue;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   479
		case SDEV_VTOR_INVALID:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   480
			sdcmn_err7(("prunedir: destroy invalid "
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   481
			    "node: %s\n", dv->sdev_name));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   482
			break;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   483
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   484
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   485
		if ((SDEVTOV(dv)->v_type == VDIR) &&
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   486
		    (sdev_cleandir(dv, NULL, 0) != 0)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   487
			dv = SDEV_NEXT_ENTRY(ddv, dv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   488
			continue;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   489
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   490
		SDEV_HOLD(dv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   491
		/* remove the cache node */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   492
		if (sdev_cache_update(ddv, &dv, dv->sdev_name,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   493
		    SDEV_CACHE_DELETE) == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   494
			dv = SDEV_FIRST_ENTRY(ddv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   495
		else
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   496
			dv = SDEV_NEXT_ENTRY(ddv, dv);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   497
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   498
	rw_downgrade(&ddv->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   499
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   500
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   501
/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   502
 * This function is used to create a dir or dev inside a zone's /dev when the
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   503
 * zone has a zvol that is dynamically created within the zone (i.e. inside
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   504
 * of a delegated dataset.  Since there is no /devices tree within a zone,
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   505
 * we create the chr/blk devices directly inside the zone's /dev instead of
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   506
 * making symlinks.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   507
 */
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   508
static int
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   509
devzvol_mk_ngz_node(struct sdev_node *parent, char *nm)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   510
{
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   511
	struct vattr vattr;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   512
	timestruc_t now;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   513
	enum vtype expected_type = VDIR;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   514
	dmu_objset_type_t do_type;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   515
	struct sdev_node *dv = NULL;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   516
	int res;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   517
	char *dsname;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   518
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   519
	bzero(&vattr, sizeof (vattr));
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   520
	gethrestime(&now);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   521
	vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   522
	vattr.va_uid = SDEV_UID_DEFAULT;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   523
	vattr.va_gid = SDEV_GID_DEFAULT;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   524
	vattr.va_type = VNON;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   525
	vattr.va_atime = now;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   526
	vattr.va_mtime = now;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   527
	vattr.va_ctime = now;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   528
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   529
	if ((dsname = devzvol_make_dsname(parent->sdev_path, nm)) == NULL)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   530
		return (ENOENT);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   531
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   532
	if (devzvol_objset_check(dsname, &do_type) != 0) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   533
		kmem_free(dsname, strlen(dsname) + 1);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   534
		return (ENOENT);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   535
	}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   536
	if (do_type == DMU_OST_ZVOL)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   537
		expected_type = VBLK;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   538
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   539
	if (expected_type == VDIR) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   540
		vattr.va_type = VDIR;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   541
		vattr.va_mode = SDEV_DIRMODE_DEFAULT;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   542
	} else {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   543
		minor_t minor;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   544
		dev_t devnum;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   545
		int rc;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   546
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   547
		rc = sdev_zvol_create_minor(dsname);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   548
		if ((rc != 0 && rc != EEXIST && rc != EBUSY) ||
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   549
		    sdev_zvol_name2minor(dsname, &minor)) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   550
			kmem_free(dsname, strlen(dsname) + 1);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   551
			return (ENOENT);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   552
		}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   553
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   554
		devnum = makedevice(devzvol_major, minor);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   555
		vattr.va_rdev = devnum;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   556
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   557
		if (strstr(parent->sdev_path, "/rdsk/") != NULL)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   558
			vattr.va_type = VCHR;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   559
		else
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   560
			vattr.va_type = VBLK;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   561
		vattr.va_mode = SDEV_DEVMODE_DEFAULT;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   562
	}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   563
	kmem_free(dsname, strlen(dsname) + 1);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   564
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   565
	rw_enter(&parent->sdev_contents, RW_WRITER);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   566
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   567
	res = sdev_mknode(parent, nm, &dv, &vattr,
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   568
	    NULL, NULL, kcred, SDEV_READY);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   569
	rw_exit(&parent->sdev_contents);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   570
	if (res != 0)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   571
		return (ENOENT);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   572
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   573
	SDEV_RELE(dv);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   574
	return (0);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   575
}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   576
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   577
/*ARGSUSED*/
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   578
static int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   579
devzvol_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   580
    struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   581
    caller_context_t *ct, int *direntflags, pathname_t *realpnp)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   582
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   583
	enum vtype expected_type = VDIR;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   584
	struct sdev_node *parent = VTOSDEV(dvp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   585
	char *dsname;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   586
	dmu_objset_type_t do_type;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   587
	int error;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   589
	sdcmn_err13(("devzvol_lookup '%s' '%s'", parent->sdev_path, nm));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   590
	*vpp = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   591
	/* execute access is required to search the directory */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   592
	if ((error = VOP_ACCESS(dvp, VEXEC, 0, cred, ct)) != 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   593
		return (error);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   594
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   595
	rw_enter(&parent->sdev_contents, RW_READER);
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   596
	if (SDEV_IS_GLOBAL(parent)) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   597
		/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   598
		 * During iter_datasets, don't create GZ dev when running in
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   599
		 * NGZ.  We can't return ENOENT here since that could
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   600
		 * incorrectly trigger the creation of the dev from the
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   601
		 * recursive call through prof_filldir during iter_datasets.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   602
		 */
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   603
		if (getzoneid() != GLOBAL_ZONEID) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   604
			rw_exit(&parent->sdev_contents);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   605
			return (EPERM);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   606
		}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   607
	} else {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   608
		int res;
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   609
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   610
		rw_exit(&parent->sdev_contents);
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   611
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   612
		/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   613
		 * If we're in the global zone and reach down into a non-global
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   614
		 * zone's /dev/zvol then this action could trigger the creation
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   615
		 * of all of the zvol devices for every zone into the non-global
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   616
		 * zone's /dev tree. This could be a big security hole. To
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   617
		 * prevent this, disallow the global zone from looking inside
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   618
		 * a non-global zones /dev/zvol. This behavior is similar to
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   619
		 * delegated datasets, which cannot be used by the global zone.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   620
		 */
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   621
		if (getzoneid() == GLOBAL_ZONEID)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   622
			return (EPERM);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   623
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   624
		res = prof_lookup(dvp, nm, vpp, cred);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   625
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   626
		/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   627
		 * We won't find a zvol that was dynamically created inside
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   628
		 * a NGZ, within a delegated dataset, in the zone's dev profile
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   629
		 * but prof_lookup will also find it via sdev_cache_lookup.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   630
		 */
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   631
		if (res == ENOENT) {
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   632
			/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   633
			 * We have to create the sdev node for the dymamically
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   634
			 * created zvol.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   635
			 */
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   636
			if (devzvol_mk_ngz_node(parent, nm) != 0)
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   637
				return (ENOENT);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   638
			res = prof_lookup(dvp, nm, vpp, cred);
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   639
		}
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   640
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   641
		return (res);
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   642
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   643
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   644
	dsname = devzvol_make_dsname(parent->sdev_path, nm);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   645
	rw_exit(&parent->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   646
	sdcmn_err13(("rvp dsname %s", dsname ? dsname : "(null)"));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   647
	if (dsname) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   648
		error = devzvol_objset_check(dsname, &do_type);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   649
		if (error != 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   650
			error = ENOENT;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   651
			goto out;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   652
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   653
		if (do_type == DMU_OST_ZVOL)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   654
			expected_type = VLNK;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   655
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   656
	/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   657
	 * the callbacks expect:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   658
	 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   659
	 * parent->sdev_path		   nm
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   660
	 * /dev/zvol			   {r}dsk
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   661
	 * /dev/zvol/{r}dsk		   <pool name>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   662
	 * /dev/zvol/{r}dsk/<dataset name> <last ds component>
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   663
	 *
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   664
	 * sdev_name is always last path component of sdev_path
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   665
	 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   666
	if (expected_type == VDIR) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   667
		error = devname_lookup_func(parent, nm, vpp, cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   668
		    devzvol_create_dir, SDEV_VATTR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   669
	} else {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   670
		error = devname_lookup_func(parent, nm, vpp, cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   671
		    devzvol_create_link, SDEV_VLINK);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   672
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   673
	sdcmn_err13(("devzvol_lookup %d %d", expected_type, error));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   674
	ASSERT(error || ((*vpp)->v_type == expected_type));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   675
out:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   676
	if (dsname)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   677
		kmem_free(dsname, strlen(dsname) + 1);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   678
	sdcmn_err13(("devzvol_lookup %d", error));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   679
	return (error);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   680
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   681
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   682
/*
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   683
 * We allow create to find existing nodes
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   684
 *	- if the node doesn't exist - EROFS
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   685
 *	- creating an existing dir read-only succeeds, otherwise EISDIR
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   686
 *	- exclusive creates fail - EEXIST
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   687
 */
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   688
/*ARGSUSED2*/
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   689
static int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   690
devzvol_create(struct vnode *dvp, char *nm, struct vattr *vap, vcexcl_t excl,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   691
    int mode, struct vnode **vpp, struct cred *cred, int flag,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   692
    caller_context_t *ct, vsecattr_t *vsecp)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   693
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   694
	int error;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   695
	struct vnode *vp;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   696
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   697
	*vpp = NULL;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   698
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   699
	error = devzvol_lookup(dvp, nm, &vp, NULL, 0, NULL, cred, ct, NULL,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   700
	    NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   701
	if (error == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   702
		if (excl == EXCL)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   703
			error = EEXIST;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   704
		else if (vp->v_type == VDIR && (mode & VWRITE))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   705
			error = EISDIR;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   706
		else
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   707
			error = VOP_ACCESS(vp, mode, 0, cred, ct);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   708
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   709
		if (error) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   710
			VN_RELE(vp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   711
		} else
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   712
			*vpp = vp;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   713
	} else if (error == ENOENT) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   714
		error = EROFS;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   715
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   716
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   717
	return (error);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   718
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   719
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   720
void sdev_iter_snapshots(struct vnode *dvp, char *name);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   721
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   722
void
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   723
sdev_iter_datasets(struct vnode *dvp, int arg, char *name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   724
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   725
	zfs_cmd_t	*zc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   726
	int rc;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   727
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   728
	sdcmn_err13(("iter name is '%s' (arg %x)", name, arg));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   729
	zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   730
	(void) strcpy(zc->zc_name, name);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   731
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   732
	while ((rc = devzvol_handle_ioctl(arg, zc, B_FALSE)) == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   733
		struct vnode *vpp;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   734
		char *ptr;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   735
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   736
		sdcmn_err13(("  name %s", zc->zc_name));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   737
		if (strchr(zc->zc_name, '$') || strchr(zc->zc_name, '%'))
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   738
			goto skip;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   739
		ptr = strrchr(zc->zc_name, '/') + 1;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   740
		rc = devzvol_lookup(dvp, ptr, &vpp, NULL, 0, NULL,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   741
		    kcred, NULL, NULL, NULL);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   742
		if (rc == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   743
			VN_RELE(vpp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   744
		} else if (rc == ENOENT) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   745
			goto skip;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   746
		} else {
14222
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   747
			/*
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   748
			 * EBUSY == problem with zvols's dmu holds?
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   749
			 * EPERM when in a NGZ and traversing up and out.
c3f8a4690b1f 3977 zones can commit suicide by zvol
Jerry Jelinek <jerry.jelinek@joyent.com>
parents: 10763
diff changeset
   750
			 */
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   751
			goto skip;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   752
		}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   753
		if (arg == ZFS_IOC_DATASET_LIST_NEXT &&
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   754
		    zc->zc_objset_stats.dds_type != DMU_OST_ZFS)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   755
			sdev_iter_snapshots(dvp, zc->zc_name);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   756
skip:
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   757
		(void) strcpy(zc->zc_name, name);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   758
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   759
	kmem_free(zc, sizeof (zfs_cmd_t));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   760
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   761
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   762
void
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   763
sdev_iter_snapshots(struct vnode *dvp, char *name)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   764
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   765
	sdev_iter_datasets(dvp, ZFS_IOC_SNAPSHOT_LIST_NEXT, name);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   766
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   767
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   768
/*ARGSUSED4*/
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   769
static int
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   770
devzvol_readdir(struct vnode *dvp, struct uio *uiop, struct cred *cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   771
    int *eofp, caller_context_t *ct_unused, int flags_unused)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   772
{
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   773
	struct sdev_node *sdvp = VTOSDEV(dvp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   774
	char *ptr;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   775
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   776
	sdcmn_err13(("zv readdir of '%s' %s'", sdvp->sdev_path,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   777
	    sdvp->sdev_name));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   778
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   779
	if (strcmp(sdvp->sdev_path, ZVOL_DIR) == 0) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   780
		struct vnode *vp;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   781
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   782
		rw_exit(&sdvp->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   783
		(void) devname_lookup_func(sdvp, "dsk", &vp, cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   784
		    devzvol_create_dir, SDEV_VATTR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   785
		VN_RELE(vp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   786
		(void) devname_lookup_func(sdvp, "rdsk", &vp, cred,
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   787
		    devzvol_create_dir, SDEV_VATTR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   788
		VN_RELE(vp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   789
		rw_enter(&sdvp->sdev_contents, RW_READER);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   790
		return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   791
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   792
	if (uiop->uio_offset == 0)
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   793
		devzvol_prunedir(sdvp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   794
	ptr = sdvp->sdev_path + strlen(ZVOL_DIR);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   795
	if ((strcmp(ptr, "/dsk") == 0) || (strcmp(ptr, "/rdsk") == 0)) {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   796
		rw_exit(&sdvp->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   797
		devzvol_create_pool_dirs(dvp);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   798
		rw_enter(&sdvp->sdev_contents, RW_READER);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   799
		return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   800
	}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   801
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   802
	ptr = strchr(ptr + 1, '/') + 1;
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   803
	rw_exit(&sdvp->sdev_contents);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   804
	sdev_iter_datasets(dvp, ZFS_IOC_DATASET_LIST_NEXT, ptr);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   805
	rw_enter(&sdvp->sdev_contents, RW_READER);
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   806
	return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   807
}
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   808
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   809
const fs_operation_def_t devzvol_vnodeops_tbl[] = {
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   810
	VOPNAME_READDIR,	{ .vop_readdir = devzvol_readdir },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   811
	VOPNAME_LOOKUP,		{ .vop_lookup = devzvol_lookup },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   812
	VOPNAME_CREATE,		{ .vop_create = devzvol_create },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   813
	VOPNAME_RENAME,		{ .error = fs_nosys },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   814
	VOPNAME_MKDIR,		{ .error = fs_nosys },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   815
	VOPNAME_RMDIR,		{ .error = fs_nosys },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   816
	VOPNAME_REMOVE,		{ .error = fs_nosys },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   817
	VOPNAME_SYMLINK,	{ .error = fs_nosys },
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   818
	NULL,			NULL
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
diff changeset
   819
};