usr/src/uts/common/fs/zfs/zfs_ctldir.c
author George Wilson <George.Wilson@Sun.COM>
Tue, 29 Sep 2009 07:29:35 -0700
changeset 10685 931790026ac6
parent 10373 bcf97ee54990
child 11935 538c866aaac6
permissions -rw-r--r--
6846163 ZFS continues to use faulted logzilla, bringing system to a crawl 6872547 ztest LUN expansion test fails 6873635 zdb should be able to open a pool with a failed slog 6873654 system panics when a slog device is offlined 6875236 zdb should be able to dump the spa history
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1512
dad2d74ca2cb 6391609 zfs_fid() missing ZFS_EXIT()
ek110237
parents: 1298
diff changeset
     5
 * Common Development and Distribution License (the "License").
dad2d74ca2cb 6391609 zfs_fid() missing ZFS_EXIT()
ek110237
parents: 1298
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
8547
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
    22
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
 * ZFS control directory (a.k.a. ".zfs")
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
 * This directory provides a common location for all ZFS meta-objects.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 * Currently, this is only the 'snapshot' directory, but this may expand in the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * future.  The elements are built using the GFS primitives, as the hierarchy
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 * does not actually exist on disk.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 * For 'snapshot', we don't want to have all snapshots always mounted, because
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * this would take up a huge amount of space in /etc/mnttab.  We have three
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 * types of objects:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
 * 	ctldir ------> snapshotdir -------> snapshot
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
 *                                             |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
 *                                             |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
 *                                             V
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
 *                                         mounted fs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
 * The 'snapshot' node contains just enough information to lookup '..' and act
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
 * as a mountpoint for the snapshot.  Whenever we lookup a specific snapshot, we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
 * perform an automount of the underlying filesystem and return the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
 * corresponding vnode.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
 * All mounts are handled automatically by the kernel, but unmounts are
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
 * (currently) handled from user land.  The main reason is that there is no
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
 * reliable way to auto-unmount the filesystem when it's "no longer in use".
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
 * When the user unmounts a filesystem, we call zfsctl_unmount(), which
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
 * unmounts any snapshots within the snapshot directory.
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    54
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    55
 * The '.zfs', '.zfs/snapshot', and all directories created under
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    56
 * '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') are all GFS nodes and
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    57
 * share the same vfs_t as the head filesystem (what '.zfs' lives under).
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    58
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    59
 * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>'
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    60
 * (ie: snapshots) are ZFS nodes and have their own unique vfs_t.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    61
 * However, vnodes within these mounted on file systems have their v_vfsp
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
    62
 * fields set to the head filesystem to make NFS happy (see
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    63
 * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    64
 * so that it cannot be freed until all snapshots have been unmounted.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
#include <fs/fs_subr.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
#include <sys/zfs_ctldir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
#include <sys/zfs_ioctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
#include <sys/zfs_vfsops.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
    71
#include <sys/vfs_opreg.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
#include <sys/gfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
#include <sys/dmu.h>
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
    75
#include <sys/dsl_deleg.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
#include <sys/mount.h>
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
    77
#include <sys/sunddi.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
6658
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
    79
#include "zfs_namecheck.h"
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
    80
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    81
typedef struct zfsctl_node {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    82
	gfs_dir_t	zc_gfs_private;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    83
	uint64_t	zc_id;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    84
	timestruc_t	zc_cmtime;	/* ctime and mtime, always the same */
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    85
} zfsctl_node_t;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    86
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    87
typedef struct zfsctl_snapdir {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    88
	zfsctl_node_t	sd_node;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    89
	kmutex_t	sd_lock;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    90
	avl_tree_t	sd_snaps;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    91
} zfsctl_snapdir_t;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
    92
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
typedef struct {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	char		*se_name;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	vnode_t		*se_root;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	avl_node_t	se_node;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
} zfs_snapentry_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
snapentry_compare(const void *a, const void *b)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	const zfs_snapentry_t *sa = a;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	const zfs_snapentry_t *sb = b;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	int ret = strcmp(sa->se_name, sb->se_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	if (ret < 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	else if (ret > 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
vnodeops_t *zfsctl_ops_root;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
vnodeops_t *zfsctl_ops_snapdir;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
vnodeops_t *zfsctl_ops_snapshot;
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   117
vnodeops_t *zfsctl_ops_shares;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   118
vnodeops_t *zfsctl_ops_shares_dir;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
static const fs_operation_def_t zfsctl_tops_root[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
static const fs_operation_def_t zfsctl_tops_snapdir[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
static const fs_operation_def_t zfsctl_tops_snapshot[];
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   123
static const fs_operation_def_t zfsctl_tops_shares[];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
static vnode_t *zfsctl_mknode_snapdir(vnode_t *);
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   126
static vnode_t *zfsctl_mknode_shares(vnode_t *);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset);
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   128
static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
static gfs_opsvec_t zfsctl_opsvec[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
	{ ".zfs", zfsctl_tops_root, &zfsctl_ops_root },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	{ ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	{ ".zfs/snapshot/vnode", zfsctl_tops_snapshot, &zfsctl_ops_snapshot },
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   134
	{ ".zfs/shares", zfsctl_tops_shares, &zfsctl_ops_shares_dir },
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   135
	{ ".zfs/shares/vnode", zfsctl_tops_shares, &zfsctl_ops_shares },
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	{ NULL }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
/*
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   140
 * Root directory elements.  We only have two entries
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   141
 * snapshot and shares.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
static gfs_dirent_t zfsctl_root_entries[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	{ "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE },
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   145
	{ "shares", zfsctl_mknode_shares, GFS_CACHE_VNODE },
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
	{ NULL }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
/* include . and .. in the calculation */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
#define	NROOT_ENTRIES	((sizeof (zfsctl_root_entries) / \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
    sizeof (gfs_dirent_t)) + 1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
 * Initialize the various GFS pieces we'll need to create and manipulate .zfs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
 * directories.  This is called from the ZFS init routine, and initializes the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
 * vnode ops vectors that we'll be using.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
zfsctl_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
zfsctl_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	 * Remove vfsctl vnode ops
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	if (zfsctl_ops_root)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
		vn_freevnodeops(zfsctl_ops_root);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	if (zfsctl_ops_snapdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
		vn_freevnodeops(zfsctl_ops_snapdir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	if (zfsctl_ops_snapshot)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
		vn_freevnodeops(zfsctl_ops_snapshot);
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   177
	if (zfsctl_ops_shares)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   178
		vn_freevnodeops(zfsctl_ops_shares);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   179
	if (zfsctl_ops_shares_dir)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   180
		vn_freevnodeops(zfsctl_ops_shares_dir);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	zfsctl_ops_root = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	zfsctl_ops_snapdir = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	zfsctl_ops_snapshot = NULL;
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   185
	zfsctl_ops_shares = NULL;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   186
	zfsctl_ops_shares_dir = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
/*
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   190
 * Return the inode number associated with the 'snapshot' or
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   191
 * 'shares' directory.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
static ino64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
zfsctl_root_inode_cb(vnode_t *vp, int index)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
{
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   197
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   198
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   199
	ASSERT(index <= 2);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   200
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   201
	if (index == 0)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   202
		return (ZFSCTL_INO_SNAPDIR);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   203
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   204
	return (zfsvfs->z_shares_dir);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
 * Create the '.zfs' directory.  This directory is cached as part of the VFS
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
 * structure.  This results in a hold on the vfs_t.  The code in zfs_umount()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
 * therefore checks against a vfs_count of 2 instead of 1.  This reference
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
 * is removed when the ctldir is destroyed in the unmount.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
zfsctl_create(zfsvfs_t *zfsvfs)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
{
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   216
	vnode_t *vp, *rvp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	zfsctl_node_t *zcp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	ASSERT(zfsvfs->z_ctldir == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	vp = gfs_root_create(sizeof (zfsctl_node_t), zfsvfs->z_vfs,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	    zfsctl_ops_root, ZFSCTL_INO_ROOT, zfsctl_root_entries,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	    zfsctl_root_inode_cb, MAXNAMELEN, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	zcp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	zcp->zc_id = ZFSCTL_INO_ROOT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   227
	VERIFY(VFS_ROOT(zfsvfs->z_vfs, &rvp) == 0);
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   228
	ZFS_TIME_DECODE(&zcp->zc_cmtime, VTOZ(rvp)->z_phys->zp_crtime);
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   229
	VN_RELE(rvp);
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   230
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
	 * We're only faking the fact that we have a root of a filesystem for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
	 * the sake of the GFS interfaces.  Undo the flag manipulation it did
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
	 * for us.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
	vp->v_flag &= ~(VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	zfsvfs->z_ctldir = vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
/*
1298
1a70f57b62f0 6368181 some memleaks found related to zfs mount
perrin
parents: 1154
diff changeset
   242
 * Destroy the '.zfs' directory.  Only called when the filesystem is unmounted.
1a70f57b62f0 6368181 some memleaks found related to zfs mount
perrin
parents: 1154
diff changeset
   243
 * There might still be more references if we were force unmounted, but only
1a70f57b62f0 6368181 some memleaks found related to zfs mount
perrin
parents: 1154
diff changeset
   244
 * new zfs_inactive() calls can occur and they don't reference .zfs
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
zfsctl_destroy(zfsvfs_t *zfsvfs)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	VN_RELE(zfsvfs->z_ctldir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	zfsvfs->z_ctldir = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
 * Given a root znode, retrieve the associated .zfs directory.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
 * Add a hold to the vnode and return it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
vnode_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
zfsctl_root(znode_t *zp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	ASSERT(zfs_has_ctldir(zp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	VN_HOLD(zp->z_zfsvfs->z_ctldir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	return (zp->z_zfsvfs->z_ctldir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
 * Common open routine.  Disallow any write access.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   270
zfsctl_common_open(vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
	if (flags & FWRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		return (EACCES);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
 * Common close routine.  Nothing to do here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
zfsctl_common_close(vnode_t *vpp, int flags, int count, offset_t off,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   284
    cred_t *cr, caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
 * Common access routine.  Disallow writes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   294
zfsctl_common_access(vnode_t *vp, int mode, int flags, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   295
    caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
{
8547
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   297
	if (flags & V_ACE_MASK) {
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   298
		if (mode & ACE_ALL_WRITE_PERMS)
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   299
			return (EACCES);
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   300
	} else {
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   301
		if (mode & VWRITE)
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   302
			return (EACCES);
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   303
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
 * Common getattr function.  Fill in basic information.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
{
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   314
	timestruc_t	now;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	vap->va_uid = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	vap->va_gid = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	vap->va_rdev = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	/*
10373
bcf97ee54990 6395956 snapshot dir needs real c/mtime
Chris Kirby <chris.kirby@sun.com>
parents: 10298
diff changeset
   320
	 * We are a purely virtual object, so we have no
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	 * blocksize or allocated blocks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	vap->va_blksize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	vap->va_nblocks = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	vap->va_seq = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	vap->va_fsid = vp->v_vfsp->vfs_dev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	    S_IROTH | S_IXOTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	vap->va_type = VDIR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	/*
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   331
	 * We live in the now (for atime).
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	gethrestime(&now);
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
   334
	vap->va_atime = now;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   337
/*ARGSUSED*/
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   339
zfsctl_common_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	zfsvfs_t	*zfsvfs = vp->v_vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	zfsctl_node_t	*zcp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	uint64_t	object = zcp->zc_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	zfid_short_t	*zfid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	int		i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	if (fidp->fid_len < SHORT_FID_LEN) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
		fidp->fid_len = SHORT_FID_LEN;
1512
dad2d74ca2cb 6391609 zfs_fid() missing ZFS_EXIT()
ek110237
parents: 1298
diff changeset
   351
		ZFS_EXIT(zfsvfs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
		return (ENOSPC);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	zfid = (zfid_short_t *)fidp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	zfid->zf_len = SHORT_FID_LEN;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	for (i = 0; i < sizeof (zfid->zf_object); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	/* .zfs znodes always have a generation number of 0 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
	for (i = 0; i < sizeof (zfid->zf_gen); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
		zfid->zf_gen[i] = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   370
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   371
/*ARGSUSED*/
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   372
static int
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   373
zfsctl_shares_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   374
{
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   375
	zfsvfs_t	*zfsvfs = vp->v_vfsp->vfs_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   376
	znode_t		*dzp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   377
	int		error;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   378
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   379
	ZFS_ENTER(zfsvfs);
9030
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   380
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   381
	if (zfsvfs->z_shares_dir == 0) {
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   382
		ZFS_EXIT(zfsvfs);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   383
		return (ENOTSUP);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   384
	}
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   385
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   386
	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   387
		error = VOP_FID(ZTOV(dzp), fidp, ct);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   388
		VN_RELE(ZTOV(dzp));
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   389
	}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   390
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   391
	ZFS_EXIT(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   392
	return (error);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   393
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
 * .zfs inode namespace
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
 * We need to generate unique inode numbers for all files and directories
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
 * within the .zfs pseudo-filesystem.  We use the following scheme:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
 * 	ENTRY			ZFSCTL_INODE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
 * 	.zfs			1
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
 * 	.zfs/snapshot		2
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
 * 	.zfs/snapshot/<snap>	objectid(snap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
#define	ZFSCTL_INO_SNAP(id)	(id)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
 * Get root directory attributes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   413
zfsctl_root_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   414
    caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
10373
bcf97ee54990 6395956 snapshot dir needs real c/mtime
Chris Kirby <chris.kirby@sun.com>
parents: 10298
diff changeset
   417
	zfsctl_node_t *zcp = vp->v_data;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
	vap->va_nodeid = ZFSCTL_INO_ROOT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
	vap->va_nlink = vap->va_size = NROOT_ENTRIES;
10373
bcf97ee54990 6395956 snapshot dir needs real c/mtime
Chris Kirby <chris.kirby@sun.com>
parents: 10298
diff changeset
   422
	vap->va_mtime = vap->va_ctime = zcp->zc_cmtime;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	zfsctl_common_getattr(vp, vap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
 * Special case the handling of "..".
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   436
    int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   437
    int *direntflags, pathname_t *realpnp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   442
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   443
	 * No extended attributes allowed under .zfs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   444
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   445
	if (flags & LOOKUP_XATTR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   446
		return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   447
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
	if (strcmp(nm, "..") == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
		err = VFS_ROOT(dvp->v_vfsp, vpp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	} else {
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   453
		err = gfs_vop_lookup(dvp, nm, vpp, pnp, flags, rdir,
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   454
		    cr, ct, direntflags, realpnp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
8547
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   462
static int
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   463
zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   464
    caller_context_t *ct)
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   465
{
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   466
	/*
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   467
	 * We only care about ACL_ENABLED so that libsec can
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   468
	 * display ACL correctly and not default to POSIX draft.
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   469
	 */
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   470
	if (cmd == _PC_ACL_ENABLED) {
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   471
		*valp = _ACL_ACE_ENABLED;
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   472
		return (0);
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   473
	}
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   474
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   475
	return (fs_pathconf(vp, cmd, valp, cr, ct));
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   476
}
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   477
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
static const fs_operation_def_t zfsctl_tops_root[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   479
	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   480
	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   481
	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   482
	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_root_getattr }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   483
	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   484
	{ VOPNAME_READDIR,	{ .vop_readdir = gfs_vop_readdir } 	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   485
	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_root_lookup }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   486
	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   487
	{ VOPNAME_INACTIVE,	{ .vop_inactive = gfs_vop_inactive }	},
8547
bcc7b46e5ff7 6792884 Vista clients cannot access .zfs
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 7229
diff changeset
   488
	{ VOPNAME_PATHCONF,	{ .vop_pathconf = zfsctl_pathconf }	},
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
   489
	{ VOPNAME_FID,		{ .vop_fid = zfsctl_common_fid	}	},
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
	{ NULL }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
	objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
6658
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
   498
	if (snapshot_namecheck(name, NULL, NULL) != 0)
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
   499
		return (EILSEQ);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
	dmu_objset_name(os, zname);
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   501
	if (strlen(zname) + 1 + strlen(name) >= len)
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   502
		return (ENAMETOOLONG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
	(void) strcat(zname, "@");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	(void) strcat(zname, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   508
static int
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   509
zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
{
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   511
	vnode_t *svp = sep->se_root;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   512
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   514
	ASSERT(vn_ismntpt(svp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	/* this will be dropped by dounmount() */
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   517
	if ((error = vn_vfswlock(svp)) != 0)
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   518
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   520
	VN_HOLD(svp);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   521
	error = dounmount(vn_mountedvfs(svp), fflags, cr);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   522
	if (error) {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   523
		VN_RELE(svp);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   524
		return (error);
1589
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   525
	}
9214
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   526
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   527
	/*
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   528
	 * We can't use VN_RELE(), as that will try to invoke
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   529
	 * zfsctl_snapdir_inactive(), which would cause us to destroy
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   530
	 * the sd_lock mutex held by our caller.
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   531
	 */
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   532
	ASSERT(svp->v_count == 1);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   533
	gfs_vop_inactive(svp, cr, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	kmem_free(sep->se_name, strlen(sep->se_name) + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	kmem_free(sep, sizeof (zfs_snapentry_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   541
static void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	avl_index_t where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	vfs_t *vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	refstr_t *pathref;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	char newpath[MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	char *tail;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
	ASSERT(MUTEX_HELD(&sdp->sd_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
	ASSERT(sep != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
	vfsp = vn_mountedvfs(sep->se_root);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	ASSERT(vfsp != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   556
	vfs_lock_wait(vfsp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
	 * Change the name in the AVL tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	avl_remove(&sdp->sd_snaps, sep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
	kmem_free(sep->se_name, strlen(sep->se_name) + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
	sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	(void) strcpy(sep->se_name, nm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
	VERIFY(avl_find(&sdp->sd_snaps, sep, &where) == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	avl_insert(&sdp->sd_snaps, sep, where);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	 * Change the current mountpoint info:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	 * 	- update the tail of the mntpoint path
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
	 *	- update the tail of the resource path
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	pathref = vfs_getmntpoint(vfsp);
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   574
	(void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   575
	VERIFY((tail = strrchr(newpath, '/')) != NULL);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   576
	*(tail+1) = '\0';
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   577
	ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	(void) strcat(newpath, nm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	refstr_rele(pathref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	vfs_setmntpoint(vfsp, newpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
	pathref = vfs_getresource(vfsp);
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   583
	(void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   584
	VERIFY((tail = strrchr(newpath, '@')) != NULL);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   585
	*(tail+1) = '\0';
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 1589
diff changeset
   586
	ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
	(void) strcat(newpath, nm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	refstr_rele(pathref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
	vfs_setresource(vfsp, newpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	vfs_unlock(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   594
/*ARGSUSED*/
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   597
    cred_t *cr, caller_context_t *ct, int flags)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	zfsctl_snapdir_t *sdp = sdvp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	zfs_snapentry_t search, *sep;
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   601
	zfsvfs_t *zfsvfs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	avl_index_t where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	char from[MAXNAMELEN], to[MAXNAMELEN];
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   604
	char real[MAXNAMELEN];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   607
	zfsvfs = sdvp->v_vfsp->vfs_data;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   608
	ZFS_ENTER(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   609
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   610
	if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   611
		err = dmu_snapshot_realname(zfsvfs->z_os, snm, real,
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   612
		    MAXNAMELEN, NULL);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   613
		if (err == 0) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   614
			snm = real;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   615
		} else if (err != ENOTSUP) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   616
			ZFS_EXIT(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   617
			return (err);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   618
		}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   619
	}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   620
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   621
	ZFS_EXIT(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   622
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   623
	err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from);
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   624
	if (!err)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   625
		err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   626
	if (!err)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   627
		err = zfs_secpolicy_rename_perms(from, to, cr);
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   628
	if (err)
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   629
		return (err);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   630
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	 * Cannot move snapshots out of the snapdir.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	if (sdvp != tdvp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
	if (strcmp(snm, tnm) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
	search.se_name = (char *)snm;
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   643
	if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) {
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   644
		mutex_exit(&sdp->sd_lock);
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   645
		return (ENOENT);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
4007
c6f5c6753018 PSARC 2007/142 zfs rename -r
mmusante
parents: 3898
diff changeset
   648
	err = dmu_objset_rename(from, to, B_FALSE);
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   649
	if (err == 0)
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   650
		zfsctl_rename_snap(sdp, sep, tnm);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
	mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   659
zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   660
    caller_context_t *ct, int flags)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	zfsctl_snapdir_t *sdp = dvp->v_data;
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   663
	zfs_snapentry_t *sep;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   664
	zfs_snapentry_t search;
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   665
	zfsvfs_t *zfsvfs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	char snapname[MAXNAMELEN];
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   667
	char real[MAXNAMELEN];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   670
	zfsvfs = dvp->v_vfsp->vfs_data;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   671
	ZFS_ENTER(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   672
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   673
	if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   674
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   675
		err = dmu_snapshot_realname(zfsvfs->z_os, name, real,
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   676
		    MAXNAMELEN, NULL);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   677
		if (err == 0) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   678
			name = real;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   679
		} else if (err != ENOTSUP) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   680
			ZFS_EXIT(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   681
			return (err);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   682
		}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   683
	}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   684
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   685
	ZFS_EXIT(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   686
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   687
	err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname);
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   688
	if (!err)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   689
		err = zfs_secpolicy_destroy_perms(snapname, cr);
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   690
	if (err)
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   691
		return (err);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   692
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   695
	search.se_name = name;
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   696
	sep = avl_find(&sdp->sd_snaps, &search, NULL);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   697
	if (sep) {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   698
		avl_remove(&sdp->sd_snaps, sep);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   699
		err = zfsctl_unmount_snap(sep, MS_FORCE, cr);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   700
		if (err)
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   701
			avl_add(&sdp->sd_snaps, sep);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   702
		else
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 9355
diff changeset
   703
			err = dmu_objset_destroy(snapname, B_FALSE);
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   704
	} else {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   705
		err = ENOENT;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
	mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   713
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   714
 * This creates a snapshot under '.zfs/snapshot'.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   715
 */
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   716
/* ARGSUSED */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   717
static int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   718
zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t  **vpp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   719
    cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   720
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   721
	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   722
	char name[MAXNAMELEN];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   723
	int err;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   724
	static enum symfollow follow = NO_FOLLOW;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   725
	static enum uio_seg seg = UIO_SYSSPACE;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   726
6658
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
   727
	if (snapshot_namecheck(dirname, NULL, NULL) != 0)
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
   728
		return (EILSEQ);
468e12a53baf 6700649 zfs_ctldir snapshot creation issues with CIFS clients
marks
parents: 6492
diff changeset
   729
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   730
	dmu_objset_name(zfsvfs->z_os, name);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   731
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   732
	*vpp = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   733
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   734
	err = zfs_secpolicy_snapshot_perms(name, cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   735
	if (err)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   736
		return (err);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   737
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   738
	if (err == 0) {
9355
09928982c591 6818183 zfs snapshot -r is slow due to set_snap_props() doing txg_wait_synced() for each new snapshot
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 9214
diff changeset
   739
		err = dmu_objset_snapshot(name, dirname, NULL, B_FALSE);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   740
		if (err)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   741
			return (err);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   742
		err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   743
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   744
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   745
	return (err);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   746
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
   747
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
 * Lookup entry point for the 'snapshot' directory.  Try to open the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
 * snapshot if it exist, creating the pseudo filesystem vnode as necessary.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
 * Perform a mount of the associated dataset on top of the vnode.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   756
    int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   757
    int *direntflags, pathname_t *realpnp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
	zfsctl_snapdir_t *sdp = dvp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
	objset_t *snap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
	char snapname[MAXNAMELEN];
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   762
	char real[MAXNAMELEN];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	char *mountpoint;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
	zfs_snapentry_t *sep, search;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	struct mounta margs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	vfs_t *vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	size_t mountpoint_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	avl_index_t where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   772
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   773
	 * No extended attributes allowed under .zfs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   774
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   775
	if (flags & LOOKUP_XATTR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   776
		return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
   777
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	ASSERT(dvp->v_type == VDIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
	 * If we get a recursive call, that means we got called
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
	 * from the domount() code while it was trying to look up the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
	 * spec (which looks like a local path for zfs).  We need to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
	 * add some flag to domount() to tell it not to do this lookup.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
	if (MUTEX_HELD(&sdp->sd_lock))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
9214
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   791
	if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   792
		ZFS_EXIT(zfsvfs);
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   793
		return (0);
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   794
	}
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   795
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   796
	if (flags & FIGNORECASE) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   797
		boolean_t conflict = B_FALSE;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   798
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   799
		err = dmu_snapshot_realname(zfsvfs->z_os, nm, real,
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   800
		    MAXNAMELEN, &conflict);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   801
		if (err == 0) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   802
			nm = real;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   803
		} else if (err != ENOTSUP) {
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   804
			ZFS_EXIT(zfsvfs);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   805
			return (err);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   806
		}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   807
		if (realpnp)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   808
			(void) strlcpy(realpnp->pn_buf, nm,
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   809
			    realpnp->pn_bufsize);
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   810
		if (conflict && direntflags)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   811
			*direntflags = ED_CASE_CONFLICT;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   812
	}
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
   813
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	search.se_name = (char *)nm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
	if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
		*vpp = sep->se_root;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
		VN_HOLD(*vpp);
1589
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   819
		err = traverse(vpp);
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   820
		if (err) {
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   821
			VN_RELE(*vpp);
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   822
			*vpp = NULL;
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   823
		} else if (*vpp == sep->se_root) {
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   824
			/*
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   825
			 * The snapshot was unmounted behind our backs,
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   826
			 * try to remount it.
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   827
			 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
			goto domount;
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   829
		} else {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   830
			/*
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   831
			 * VROOT was set during the traverse call.  We need
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   832
			 * to clear it since we're pretending to be part
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   833
			 * of our parent's vfs.
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   834
			 */
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
   835
			(*vpp)->v_flag &= ~VROOT;
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   836
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
		mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
		ZFS_EXIT(zfsvfs);
1589
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
   839
		return (err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
	 * The requested snapshot is not currently mounted, look it up.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
	 */
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   845
	err = zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname);
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   846
	if (err) {
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   847
		mutex_exit(&sdp->sd_lock);
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   848
		ZFS_EXIT(zfsvfs);
7229
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   849
		/*
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   850
		 * handle "ls *" or "?" in a graceful manner,
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   851
		 * forcing EILSEQ to ENOENT.
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   852
		 * Since shell ultimately passes "*" or "?" as name to lookup
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   853
		 */
7836e02dc984 6731778 'ls *' in empty zfs snapshot directory returns EILSEQ vs. ENOENT we get in other empty directories
marks
parents: 6689
diff changeset
   854
		return (err == EILSEQ ? ENOENT : err);
1154
08f3f98286fe 6359739 panic in zfsctl_snapshot_zname()
maybee
parents: 816
diff changeset
   855
	}
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 10242
diff changeset
   856
	if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
		mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
	sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
	sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
	(void) strcpy(sep->se_name, nm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
	*vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
	avl_insert(&sdp->sd_snaps, sep, where);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
10298
a0d52501437c 6860996 %temporary clones are not automatically destroyed on error
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 10242
diff changeset
   868
	dmu_objset_rele(snap, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
domount:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
	mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
	    strlen("/.zfs/snapshot/") + strlen(nm) + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
	mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
	(void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
	    refstr_value(dvp->v_vfsp->vfs_mntpt), nm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
	margs.spec = snapname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
	margs.dir = mountpoint;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
	margs.flags = MS_SYSSPACE | MS_NOMNTTAB;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
	margs.fstype = "zfs";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
	margs.dataptr = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
	margs.datalen = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
	margs.optptr = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
	margs.optlen = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
	err = domount("zfs", &margs, *vpp, kcred, &vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
	kmem_free(mountpoint, mountpoint_len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   888
	if (err == 0) {
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   889
		/*
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   890
		 * Return the mounted root rather than the covered mount point.
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   891
		 * Takes the GFS vnode at .zfs/snapshot/<snapname> and returns
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   892
		 * the ZFS vnode mounted on top of the GFS node.  This ZFS
9214
8d350e5d04aa 6604992 forced unmount + being in .zfs/snapshot/<snap1> = not happy
Chris Kirby <chris.kirby@sun.com>
parents: 9030
diff changeset
   893
		 * vnode is the root of the newly created vfsp.
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   894
		 */
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   895
		VFS_RELE(vfsp);
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   896
		err = traverse(vpp);
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   897
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   899
	if (err == 0) {
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   900
		/*
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   901
		 * Fix up the root vnode mounted on .zfs/snapshot/<snapname>.
4736
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4543
diff changeset
   902
		 *
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4543
diff changeset
   903
		 * This is where we lie about our v_vfsp in order to
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   904
		 * make .zfs/snapshot/<snapname> accessible over NFS
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
   905
		 * without requiring manual mounts of <snapname>.
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   906
		 */
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   907
		ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs);
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   908
		VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs;
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   909
		(*vpp)->v_vfsp = zfsvfs->z_vfs;
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   910
		(*vpp)->v_flag &= ~VROOT;
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   911
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
	mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   915
	/*
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   916
	 * If we had an error, drop our hold on the vnode and
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   917
	 * zfsctl_snapshot_inactive() will clean up.
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   918
	 */
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   919
	if (err) {
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   920
		VN_RELE(*vpp);
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   921
		*vpp = NULL;
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
   922
	}
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 789
diff changeset
   923
	return (err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
static int
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   928
zfsctl_shares_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   929
    int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   930
    int *direntflags, pathname_t *realpnp)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   931
{
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   932
	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   933
	znode_t *dzp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   934
	int error;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   935
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   936
	ZFS_ENTER(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   937
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   938
	if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   939
		ZFS_EXIT(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   940
		return (0);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   941
	}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   942
9030
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   943
	if (zfsvfs->z_shares_dir == 0) {
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   944
		ZFS_EXIT(zfsvfs);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   945
		return (ENOTSUP);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
   946
	}
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   947
	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   948
		error = VOP_LOOKUP(ZTOV(dzp), nm, vpp, pnp,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   949
		    flags, rdir, cr, ct, direntflags, realpnp);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   950
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   951
	VN_RELE(ZTOV(dzp));
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   952
	ZFS_EXIT(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   953
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   954
	return (error);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   955
}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   956
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   957
/* ARGSUSED */
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
   958
static int
5663
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   959
zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp,
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   960
    offset_t *offp, offset_t *nextp, void *data, int flags)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
	char snapname[MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
	uint64_t id, cookie;
5663
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   965
	boolean_t case_conflict;
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   966
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
	cookie = *offp;
5663
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   971
	error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id,
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   972
	    &cookie, &case_conflict);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   973
	if (error) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
		ZFS_EXIT(zfsvfs);
5663
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   975
		if (error == ENOENT) {
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   976
			*eofp = 1;
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   977
			return (0);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   978
		}
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   979
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
5663
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   982
	if (flags & V_RDDIR_ENTFLAGS) {
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   983
		edirent_t *eodp = dp;
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   984
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   985
		(void) strcpy(eodp->ed_name, snapname);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   986
		eodp->ed_ino = ZFSCTL_INO_SNAP(id);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   987
		eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0;
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   988
	} else {
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   989
		struct dirent64 *odp = dp;
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   990
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   991
		(void) strcpy(odp->d_name, snapname);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   992
		odp->d_ino = ZFSCTL_INO_SNAP(id);
029cc4273b57 6627223 gfs needs to support extended dirent flags
ck153898
parents: 5331
diff changeset
   993
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
	*nextp = cookie;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1001
/* ARGSUSED */
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1002
static int
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1003
zfsctl_shares_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1004
    caller_context_t *ct, int flags)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1005
{
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1006
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1007
	znode_t *dzp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1008
	int error;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1009
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1010
	ZFS_ENTER(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1011
9030
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1012
	if (zfsvfs->z_shares_dir == 0) {
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1013
		ZFS_EXIT(zfsvfs);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1014
		return (ENOTSUP);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1015
	}
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1016
	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1017
		error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp, ct, flags);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1018
		VN_RELE(ZTOV(dzp));
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1019
	} else {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1020
		*eofp = 1;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1021
		error = ENOENT;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1022
	}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1023
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1024
	ZFS_EXIT(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1025
	return (error);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1026
}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1027
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1028
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1029
 * pvp is the '.zfs' directory (zfsctl_node_t).
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1030
 * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t).
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1031
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1032
 * This function is the callback to create a GFS vnode for '.zfs/snapshot'
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1033
 * when a lookup is performed on .zfs for "snapshot".
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1034
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
vnode_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
zfsctl_mknode_snapdir(vnode_t *pvp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
	vnode_t *vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
	zfsctl_snapdir_t *sdp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
	vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
	    zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
	    zfsctl_snapdir_readdir_cb, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
	sdp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
	sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR;
1571
5aae3c7637de 6349516 surprise: .zfs & .zfs/snapshot keep changing
ek110237
parents: 1566
diff changeset
  1046
	sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
	mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
	avl_create(&sdp->sd_snaps, snapentry_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1049
	    sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
	return (vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1053
vnode_t *
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1054
zfsctl_mknode_shares(vnode_t *pvp)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1055
{
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1056
	vnode_t *vp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1057
	zfsctl_node_t *sdp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1058
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1059
	vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1060
	    zfsctl_ops_shares, NULL, NULL, MAXNAMELEN,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1061
	    NULL, NULL);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1062
	sdp = vp->v_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1063
	sdp->zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1064
	return (vp);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1065
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1066
}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1067
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1068
/* ARGSUSED */
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1069
static int
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1070
zfsctl_shares_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1071
    caller_context_t *ct)
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1072
{
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1073
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1074
	znode_t *dzp;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1075
	int error;
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1076
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1077
	ZFS_ENTER(zfsvfs);
9030
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1078
	if (zfsvfs->z_shares_dir == 0) {
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1079
		ZFS_EXIT(zfsvfs);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1080
		return (ENOTSUP);
243fd360d81f 6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents: 8845
diff changeset
  1081
	}
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1082
	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1083
		error = VOP_GETATTR(ZTOV(dzp), vap, flags, cr, ct);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1084
		VN_RELE(ZTOV(dzp));
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1085
	}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1086
	ZFS_EXIT(zfsvfs);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1087
	return (error);
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1088
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1089
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1090
}
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1091
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1094
zfsctl_snapdir_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1095
    caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
	zfsctl_snapdir_t *sdp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
	zfsctl_common_getattr(vp, vap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	vap->va_nodeid = gfs_file_inode(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2;
10373
bcf97ee54990 6395956 snapshot dir needs real c/mtime
Chris Kirby <chris.kirby@sun.com>
parents: 10298
diff changeset
  1104
	vap->va_ctime = vap->va_mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1110
/* ARGSUSED */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1112
zfsctl_snapdir_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
	zfsctl_snapdir_t *sdp = vp->v_data;
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1115
	void *private;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1117
	private = gfs_dir_inactive(vp);
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1118
	if (private != NULL) {
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1119
		ASSERT(avl_numnodes(&sdp->sd_snaps) == 0);
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1120
		mutex_destroy(&sdp->sd_lock);
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1121
		avl_destroy(&sdp->sd_snaps);
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1122
		kmem_free(private, sizeof (zfsctl_snapdir_t));
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1123
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
static const fs_operation_def_t zfsctl_tops_snapdir[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1127
	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1128
	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1129
	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1130
	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_snapdir_getattr } },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1131
	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1132
	{ VOPNAME_RENAME,	{ .vop_rename = zfsctl_snapdir_rename }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1133
	{ VOPNAME_RMDIR,	{ .vop_rmdir = zfsctl_snapdir_remove }	},
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4007
diff changeset
  1134
	{ VOPNAME_MKDIR,	{ .vop_mkdir = zfsctl_snapdir_mkdir }	},
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1135
	{ VOPNAME_READDIR,	{ .vop_readdir = gfs_vop_readdir }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1136
	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_snapdir_lookup }	},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1137
	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1138
	{ VOPNAME_INACTIVE,	{ .vop_inactive = zfsctl_snapdir_inactive } },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1139
	{ VOPNAME_FID,		{ .vop_fid = zfsctl_common_fid }	},
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
	{ NULL }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
8845
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1143
static const fs_operation_def_t zfsctl_tops_shares[] = {
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1144
	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1145
	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1146
	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1147
	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_shares_getattr } },
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1148
	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1149
	{ VOPNAME_READDIR,	{ .vop_readdir = zfsctl_shares_readdir } },
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1150
	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_shares_lookup }	},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1151
	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1152
	{ VOPNAME_INACTIVE,	{ .vop_inactive = gfs_vop_inactive } },
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1153
	{ VOPNAME_FID,		{ .vop_fid = zfsctl_shares_fid } },
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1154
	{ NULL }
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1155
};
91af0d9c0790 6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents: 8547
diff changeset
  1156
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1157
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1158
 * pvp is the GFS vnode '.zfs/snapshot'.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1159
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1160
 * This creates a GFS node under '.zfs/snapshot' representing each
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1161
 * snapshot.  This newly created GFS node is what we mount snapshot
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1162
 * vfs_t's ontop of.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1163
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
static vnode_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
	vnode_t *vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	zfsctl_node_t *zcp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
	vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
	    zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
	zcp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
	zcp->zc_id = objset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1174
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1175
	return (vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1176
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1179
zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
	zfsctl_snapdir_t *sdp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
	zfs_snapentry_t *sep, *next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
	vnode_t *dvp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6068
diff changeset
  1185
	VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
	sdp = dvp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
	if (vp->v_count > 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
		mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
	ASSERT(!vn_ismntpt(vp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
	sep = avl_first(&sdp->sd_snaps);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
	while (sep != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
		next = AVL_NEXT(&sdp->sd_snaps, sep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
		if (sep->se_root == vp) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
			avl_remove(&sdp->sd_snaps, sep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
			kmem_free(sep->se_name, strlen(sep->se_name) + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1203
			kmem_free(sep, sizeof (zfs_snapentry_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
		sep = next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
	ASSERT(sep != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
	mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
	VN_RELE(dvp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
1566
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1213
	/*
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1214
	 * Dispose of the vnode for the snapshot mount point.
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1215
	 * This is safe to do because once this entry has been removed
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1216
	 * from the AVL tree, it can't be found again, so cannot become
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1217
	 * "active".  If we lookup the same name again we will end up
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1218
	 * creating a new vnode.
93e41df9efa5 6355162 'zfs restore -d' should not succeed upon a volume
maybee
parents: 1512
diff changeset
  1219
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1220
	gfs_vop_inactive(vp, cr, ct);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
 * These VP's should never see the light of day.  They should always
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
 * be covered.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
static const fs_operation_def_t zfsctl_tops_snapshot[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2676
diff changeset
  1229
	VOPNAME_INACTIVE, { .vop_inactive =  zfsctl_snapshot_inactive },
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1230
	NULL, NULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1234
zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1235
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1236
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
	vnode_t *dvp, *vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1238
	zfsctl_snapdir_t *sdp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
	zfsctl_node_t *zcp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
	zfs_snapentry_t *sep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1243
	ASSERT(zfsvfs->z_ctldir != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
	error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1245
	    NULL, 0, NULL, kcred, NULL, NULL, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1246
	if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1247
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
	sdp = dvp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
	sep = avl_first(&sdp->sd_snaps);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
	while (sep != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
		vp = sep->se_root;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
		zcp = vp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
		if (zcp->zc_id == objsetid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
		sep = AVL_NEXT(&sdp->sd_snaps, sep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
	if (sep != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
		VN_HOLD(vp);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1263
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1264
		 * Return the mounted root rather than the covered mount point.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1265
		 * Takes the GFS vnode at .zfs/snapshot/<snapshot objsetid>
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1266
		 * and returns the ZFS vnode mounted on top of the GFS node.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1267
		 * This ZFS vnode is the root of the vfs for objset 'objsetid'.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4736
diff changeset
  1268
		 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
		error = traverse(&vp);
1589
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1270
		if (error == 0) {
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1271
			if (vp == sep->se_root)
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1272
				error = EINVAL;
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1273
			else
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1274
				*zfsvfsp = VTOZ(vp)->z_zfsvfs;
64c230a17c47 6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
maybee
parents: 1572
diff changeset
  1275
		}
1572
0469a7fd3981 6390579 panic: recursive mutex_enter, at zfs:zfsctl_snapshot_inactive
nd150628
parents: 1571
diff changeset
  1276
		mutex_exit(&sdp->sd_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1277
		VN_RELE(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1278
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
		error = EINVAL;
1572
0469a7fd3981 6390579 panic: recursive mutex_enter, at zfs:zfsctl_snapshot_inactive
nd150628
parents: 1571
diff changeset
  1280
		mutex_exit(&sdp->sd_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
	VN_RELE(dvp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
 * Unmount any snapshots for the given filesystem.  This is called from
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
 * zfs_umount() - if we have a ctldir, then go through and unmount all the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
 * snapshots.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1293
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1294
zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1296
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1297
	vnode_t *dvp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	zfsctl_snapdir_t *sdp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
	zfs_snapentry_t *sep, *next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
	ASSERT(zfsvfs->z_ctldir != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
	error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5326
diff changeset
  1304
	    NULL, 0, NULL, cr, NULL, NULL, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1305
	if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1306
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1307
	sdp = dvp->v_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1308
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
	mutex_enter(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
	sep = avl_first(&sdp->sd_snaps);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1312
	while (sep != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
		next = AVL_NEXT(&sdp->sd_snaps, sep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
		 * If this snapshot is not mounted, then it must
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
		 * have just been unmounted by somebody else, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
		 * will be cleaned up by zfsctl_snapdir_inactive().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1319
		 */
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1320
		if (vn_ismntpt(sep->se_root)) {
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1321
			avl_remove(&sdp->sd_snaps, sep);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1322
			error = zfsctl_unmount_snap(sep, fflags, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1323
			if (error) {
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1324
				avl_add(&sdp->sd_snaps, sep);
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1325
				break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1326
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1328
		sep = next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1329
	}
6068
44728d72cfec 6564619 panic after a filesystem with snapshots that have files open was destroyed or umounted
ck153898
parents: 5663
diff changeset
  1330
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
	mutex_exit(&sdp->sd_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
	VN_RELE(dvp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1334
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
}