usr/src/uts/common/fs/zfs/zfs_znode.c
author ek110237
Wed, 24 Oct 2007 16:54:46 -0700
changeset 5326 6752aa2bd5bc
parent 4831 41ec732c6d9f
child 5331 3047ad28a67b
permissions -rw-r--r--
6425096 want online 'zfs recv' (read only and read/write) 6597182 .zfs/snapshot code could use a little more comments
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
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
/*
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    22
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
4144
068f395736ad 6465105 ZFS does not update timestamps upon the creat() of an existing file
peteh
parents: 4105
diff changeset
    26
/* Portions Copyright 2007 Jeremy Teo */
068f395736ad 6465105 ZFS does not update timestamps upon the creat() of an existing file
peteh
parents: 4105
diff changeset
    27
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    30
#ifdef _KERNEL
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/param.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/time.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/systm.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/sysmacros.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/resource.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/mntent.h>
1816
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
    38
#include <sys/mkdev.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3897
diff changeset
    40
#include <sys/vfs_opreg.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/vnode.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <sys/file.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#include <sys/kmem.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <sys/mode.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <sys/atomic.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
#include <vm/pvn.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include "fs/fs_subr.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/zfs_dir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include <sys/zfs_acl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <sys/zfs_ioctl.h>
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
    53
#include <sys/zfs_rlock.h>
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    54
#include <sys/fs/zfs.h>
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    55
#endif /* _KERNEL */
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    56
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    57
#include <sys/dmu.h>
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    58
#include <sys/refcount.h>
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    59
#include <sys/stat.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
#include <sys/zap.h>
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    61
#include <sys/zfs_znode.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    63
/*
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    64
 * Functions needed for userland (ie: libzpool) are not put under
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    65
 * #ifdef_KERNEL; the rest of the functions have dependencies
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    66
 * (such as VFS logic) that will not compile easily in userland.
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    67
 */
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
    68
#ifdef _KERNEL
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
struct kmem_cache *znode_cache = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
znode_pageout_func(dmu_buf_t *dbuf, void *user_ptr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	znode_t *zp = user_ptr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	vnode_t *vp = ZTOV(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    78
	mutex_enter(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
	if (vp->v_count == 0) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    80
		mutex_exit(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
		vn_invalid(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
		zfs_znode_free(zp);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    83
	} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    84
		/* signal force unmount that this znode can be freed */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    85
		zp->z_dbuf = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
    86
		mutex_exit(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
zfs_znode_cache_constructor(void *buf, void *cdrarg, int kmflags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	znode_t *zp = buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	zp->z_vnode = vn_alloc(KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	zp->z_vnode->v_data = (caddr_t)zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
	mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	rw_init(&zp->z_map_lock, NULL, RW_DEFAULT, NULL);
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   100
	rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL);
3897
278bade789ba 6437750 panic: db->db_buf==0||arc_referenced(db->db_buf), file: dbuf.c,line:1539
maybee
parents: 3461
diff changeset
   101
	rw_init(&zp->z_name_lock, NULL, RW_DEFAULT, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL);
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   103
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   104
	mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL);
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   105
	avl_create(&zp->z_range_avl, zfs_range_compare,
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   106
	    sizeof (rl_t), offsetof(rl_t, r_node));
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   107
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	zp->z_dbuf_held = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	zp->z_dirlocks = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
zfs_znode_cache_destructor(void *buf, void *cdarg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
	znode_t *zp = buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	ASSERT(zp->z_dirlocks == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
	mutex_destroy(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	rw_destroy(&zp->z_map_lock);
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   122
	rw_destroy(&zp->z_parent_lock);
3897
278bade789ba 6437750 panic: db->db_buf==0||arc_referenced(db->db_buf), file: dbuf.c,line:1539
maybee
parents: 3461
diff changeset
   123
	rw_destroy(&zp->z_name_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	mutex_destroy(&zp->z_acl_lock);
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   125
	avl_destroy(&zp->z_range_avl);
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   126
	mutex_destroy(&zp->z_range_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	ASSERT(zp->z_dbuf_held == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	ASSERT(ZTOV(zp)->v_count == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	vn_free(ZTOV(zp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
zfs_znode_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	 * Initialize zcache
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	ASSERT(znode_cache == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	znode_cache = kmem_cache_create("zfs_znode_cache",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	    sizeof (znode_t), 0, zfs_znode_cache_constructor,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	    zfs_znode_cache_destructor, NULL, NULL, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
zfs_znode_fini(void)
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
	 * Cleanup vfs & vnode ops
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	zfs_remove_op_tables();
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
	 * Cleanup zcache
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	if (znode_cache)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
		kmem_cache_destroy(znode_cache);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
	znode_cache = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
struct vnodeops *zfs_dvnodeops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
struct vnodeops *zfs_fvnodeops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
struct vnodeops *zfs_symvnodeops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
struct vnodeops *zfs_xdvnodeops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
struct vnodeops *zfs_evnodeops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
zfs_remove_op_tables()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	 * Remove vfs ops
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	ASSERT(zfsfstype);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	(void) vfs_freevfsops_by_type(zfsfstype);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	zfsfstype = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	 * Remove vnode ops
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
	if (zfs_dvnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
		vn_freevnodeops(zfs_dvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	if (zfs_fvnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
		vn_freevnodeops(zfs_fvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	if (zfs_symvnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
		vn_freevnodeops(zfs_symvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	if (zfs_xdvnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
		vn_freevnodeops(zfs_xdvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
	if (zfs_evnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
		vn_freevnodeops(zfs_evnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	zfs_dvnodeops = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
	zfs_fvnodeops = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	zfs_symvnodeops = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
	zfs_xdvnodeops = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	zfs_evnodeops = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
extern const fs_operation_def_t zfs_dvnodeops_template[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
extern const fs_operation_def_t zfs_fvnodeops_template[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
extern const fs_operation_def_t zfs_xdvnodeops_template[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
extern const fs_operation_def_t zfs_symvnodeops_template[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
extern const fs_operation_def_t zfs_evnodeops_template[];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
zfs_create_op_tables()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	 * zfs_dvnodeops can be set if mod_remove() calls mod_installfs()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	 * due to a failure to remove the the 2nd modlinkage (zfs_modldrv).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	 * In this case we just return as the ops vectors are already set up.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
	if (zfs_dvnodeops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
	    &zfs_dvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	    &zfs_fvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	    &zfs_symvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
	error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
	    &zfs_xdvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
	error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	    &zfs_evnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
 * zfs_init_fs - Initialize the zfsvfs struct and the file system
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
 *	incore "master" object.  Verify version compatibility.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	extern int zfsfstype;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	objset_t	*os = zfsvfs->z_os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	int		i, error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	dmu_object_info_t doi;
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2856
diff changeset
   255
	uint64_t fsid_guid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	*zpp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	 * XXX - hack to auto-create the pool root filesystem at
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	 * the first attempted mount.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	if (dmu_object_info(os, MASTER_NODE_OBJ, &doi) == ENOENT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		dmu_tx_t *tx = dmu_tx_create(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   266
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* master */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   267
		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* del queue */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); /* root node */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
		error = dmu_tx_assign(tx, TXG_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
		ASSERT3U(error, ==, 0);
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
   271
		zfs_create_fs(os, cr, ZPL_VERSION, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
   275
	error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 8, 1,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
   276
	    &zfsvfs->z_version);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   277
	if (error) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   278
		return (error);
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
   279
	} else if (zfsvfs->z_version > ZPL_VERSION) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
		(void) printf("Mismatched versions:  File system "
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		    "is version %lld on-disk format, which is "
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
		    "incompatible with this software version %lld!",
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
   283
		    (u_longlong_t)zfsvfs->z_version, ZPL_VERSION);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
		return (ENOTSUP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
	 * The fsid is 64 bits, composed of an 8-bit fs type, which
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
	 * separates our fsid from any other filesystem types, and a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
	 * 56-bit objset unique ID.  The objset unique ID is unique to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
	 * all objsets open on this system, provided by unique_create().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
	 * The 8-bit fs type must be put in the low bits of fsid[1]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	 * because that's where other Solaris filesystems put it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	 */
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2856
diff changeset
   295
	fsid_guid = dmu_objset_fsid_guid(os);
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2856
diff changeset
   296
	ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0);
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2856
diff changeset
   297
	zfsvfs->z_vfs->vfs_fsid.val[0] = fsid_guid;
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2856
diff changeset
   298
	zfsvfs->z_vfs->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) |
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	    zfsfstype & 0xFF;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   301
	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   302
	    &zfsvfs->z_root);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   303
	if (error)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   304
		return (error);
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   305
	ASSERT(zfsvfs->z_root != 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   307
	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   308
	    &zfsvfs->z_unlinkedobj);
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   309
	if (error)
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   310
		return (error);
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   311
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	 * Initialize zget mutex's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
		mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   318
	error = zfs_zget(zfsvfs, zfsvfs->z_root, zpp);
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   319
	if (error) {
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   320
		/*
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   321
		 * On error, we destroy the mutexes here since it's not
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   322
		 * possible for the caller to determine if the mutexes were
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   323
		 * initialized properly.
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   324
		 */
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   325
		for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   326
			mutex_destroy(&zfsvfs->z_hold_mtx[i]);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   327
		return (error);
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4577
diff changeset
   328
	}
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   329
	ASSERT3U((*zpp)->z_id, ==, zfsvfs->z_root);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
/*
1816
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   334
 * define a couple of values we need available
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   335
 * for both 64 and 32 bit environments.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   336
 */
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   337
#ifndef NBITSMINOR64
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   338
#define	NBITSMINOR64	32
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   339
#endif
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   340
#ifndef MAXMAJ64
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   341
#define	MAXMAJ64	0xffffffffUL
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   342
#endif
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   343
#ifndef	MAXMIN64
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   344
#define	MAXMIN64	0xffffffffUL
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   345
#endif
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   346
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   347
/*
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   348
 * Create special expldev for ZFS private use.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   349
 * Can't use standard expldev since it doesn't do
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   350
 * what we want.  The standard expldev() takes a
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   351
 * dev32_t in LP64 and expands it to a long dev_t.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   352
 * We need an interface that takes a dev32_t in ILP32
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   353
 * and expands it to a long dev_t.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   354
 */
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   355
static uint64_t
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   356
zfs_expldev(dev_t dev)
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   357
{
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   358
#ifndef _LP64
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   359
	major_t major = (major_t)dev >> NBITSMINOR32 & MAXMAJ32;
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   360
	return (((uint64_t)major << NBITSMINOR64) |
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   361
	    ((minor_t)dev & MAXMIN32));
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   362
#else
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   363
	return (dev);
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   364
#endif
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   365
}
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   366
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   367
/*
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   368
 * Special cmpldev for ZFS private use.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   369
 * Can't use standard cmpldev since it takes
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   370
 * a long dev_t and compresses it to dev32_t in
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   371
 * LP64.  We need to do a compaction of a long dev_t
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   372
 * to a dev32_t in ILP32.
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   373
 */
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   374
dev_t
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   375
zfs_cmpldev(uint64_t dev)
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   376
{
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   377
#ifndef _LP64
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   378
	minor_t minor = (minor_t)dev & MAXMIN64;
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   379
	major_t major = (major_t)(dev >> NBITSMINOR64) & MAXMAJ64;
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   380
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   381
	if (major > MAXMAJ32 || minor > MAXMIN32)
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   382
		return (NODEV32);
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   383
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   384
	return (((dev32_t)major << NBITSMINOR32) | minor);
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   385
#else
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   386
	return (dev);
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   387
#endif
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   388
}
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   389
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   390
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
 * Construct a new znode/vnode and intialize.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
 * This does not do a call to dmu_set_user() that is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
 * up to the caller to do, in case you don't want to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
 * return the znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   397
static znode_t *
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, uint64_t obj_num, int blksz)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	znode_t	*zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	vnode_t *vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
	zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
	ASSERT(zp->z_dirlocks == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
	zp->z_phys = db->db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
	zp->z_zfsvfs = zfsvfs;
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   409
	zp->z_unlinked = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
	zp->z_atime_dirty = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
	zp->z_dbuf_held = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
	zp->z_mapcnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
	zp->z_last_itx = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
	zp->z_dbuf = db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
	zp->z_id = obj_num;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
	zp->z_blksz = blksz;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
	zp->z_seq = 0x7A4653;
3063
b252896b372b 6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents: 2885
diff changeset
   418
	zp->z_sync_cnt = 0;
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   419
	zp->z_gen = zp->z_phys->zp_gen;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
	mutex_enter(&zfsvfs->z_znodes_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
	list_insert_tail(&zfsvfs->z_all_znodes, zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	mutex_exit(&zfsvfs->z_znodes_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
	vp = ZTOV(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
	vn_reinit(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
	vp->v_vfsp = zfsvfs->z_parent->z_vfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
	switch (vp->v_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
	case VDIR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
		if (zp->z_phys->zp_flags & ZFS_XATTR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
			vn_setops(vp, zfs_xdvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
			vp->v_flag |= V_XATTRDIR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
		} else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
			vn_setops(vp, zfs_dvnodeops);
869
dc133b87dfb3 6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
perrin
parents: 789
diff changeset
   438
		zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	case VBLK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
	case VCHR:
1816
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   442
		vp->v_rdev = zfs_cmpldev(zp->z_phys->zp_rdev);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
		/*FALLTHROUGH*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
	case VFIFO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
	case VSOCK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	case VDOOR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
		vn_setops(vp, zfs_fvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	case VREG:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
		vp->v_flag |= VMODSORT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
		vn_setops(vp, zfs_fvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
	case VLNK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
		vn_setops(vp, zfs_symvnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
		vn_setops(vp, zfs_evnodeops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	return (zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
zfs_znode_dmu_init(znode_t *zp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	znode_t		*nzp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	dmu_buf_t	*db = zp->z_dbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
4105
d90754357495 6543706 znodes should be immediatley freed, allowing the ARC to hold onto less memory
ek110237
parents: 3898
diff changeset
   473
	nzp = dmu_buf_set_user_ie(db, zp, &zp->z_phys, znode_pageout_func);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
	 * there should be no
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	 * concurrent zgets on this object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
	ASSERT3P(nzp, ==, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	 * Slap on VROOT if we are the root znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
	if (zp->z_id == zfsvfs->z_root) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
		ZTOV(zp)->v_flag |= VROOT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	ASSERT(zp->z_dbuf_held == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	zp->z_dbuf_held = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
	VFS_HOLD(zfsvfs->z_vfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
	vn_exists(ZTOV(zp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
 * Create a new DMU object to hold a zfs znode.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
 *	IN:	dzp	- parent directory for new znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
 *		vap	- file attributes for new znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
 *		tx	- dmu transaction id for zap operations
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
 *		cr	- credentials of caller
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
 *		flag	- flags:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
 *			  IS_ROOT_NODE	- new object will be root
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
 *			  IS_XATTR	- new object is an attribute
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
 *			  IS_REPLAY	- intent log replay
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
 *	OUT:	oid	- ID of created object
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
zfs_mknode(znode_t *dzp, vattr_t *vap, uint64_t *oid, dmu_tx_t *tx, cred_t *cr,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
	uint_t flag, znode_t **zpp, int bonuslen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
	dmu_buf_t	*dbp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
	znode_phys_t	*pzp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	znode_t		*zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
	timestruc_t	now;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	uint64_t	gen;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	int		err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
	ASSERT(vap && (vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
	if (zfsvfs->z_assign >= TXG_INITIAL) {		/* ZIL replay */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
		*oid = vap->va_nodeid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
		flag |= IS_REPLAY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
		now = vap->va_ctime;		/* see zfs_replay_create() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
		gen = vap->va_nblocks;		/* ditto */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
		*oid = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
		gethrestime(&now);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
		gen = dmu_tx_get_txg(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	 * Create a new DMU object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   538
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   539
	 * There's currently no mechanism for pre-reading the blocks that will
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   540
	 * be to needed allocate a new object, so we accept the small chance
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   541
	 * that there will be an i/o error and we will fail one of the
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   542
	 * assertions below.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   543
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	if (vap->va_type == VDIR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
		if (flag & IS_REPLAY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
			err = zap_create_claim(zfsvfs->z_os, *oid,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
			    DMU_OT_DIRECTORY_CONTENTS,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
			    DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
			ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
			*oid = zap_create(zfsvfs->z_os,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
			    DMU_OT_DIRECTORY_CONTENTS,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
			    DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
		if (flag & IS_REPLAY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
			err = dmu_object_claim(zfsvfs->z_os, *oid,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
			    DMU_OT_PLAIN_FILE_CONTENTS, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
			    DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
			ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
			*oid = dmu_object_alloc(zfsvfs->z_os,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
			    DMU_OT_PLAIN_FILE_CONTENTS, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
			    DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   567
	VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, *oid, NULL, &dbp));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	dmu_buf_will_dirty(dbp, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
	 * Initialize the znode physical data to zero.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	ASSERT(dbp->db_size >= sizeof (znode_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
	bzero(dbp->db_data, dbp->db_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
	pzp = dbp->db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	 * If this is the root, fix up the half-initialized parent pointer
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	 * to reference the just-allocated physical data area.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	if (flag & IS_ROOT_NODE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
		dzp->z_phys = pzp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
		dzp->z_id = *oid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
	 * If parent is an xattr, so am I.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
	if (dzp->z_phys->zp_flags & ZFS_XATTR)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
		flag |= IS_XATTR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	if (vap->va_type == VBLK || vap->va_type == VCHR) {
1816
8c14b56c8515 6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents: 1760
diff changeset
   593
		pzp->zp_rdev = zfs_expldev(vap->va_rdev);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	if (vap->va_type == VDIR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
		pzp->zp_size = 2;		/* contents ("." and "..") */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
		pzp->zp_links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
	pzp->zp_parent = dzp->z_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	if (flag & IS_XATTR)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
		pzp->zp_flags |= ZFS_XATTR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	pzp->zp_gen = gen;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
	ZFS_TIME_ENCODE(&now, pzp->zp_crtime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	ZFS_TIME_ENCODE(&now, pzp->zp_ctime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	if (vap->va_mask & AT_ATIME) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
		ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
		ZFS_TIME_ENCODE(&now, pzp->zp_atime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
	if (vap->va_mask & AT_MTIME) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
		ZFS_TIME_ENCODE(&vap->va_mtime, pzp->zp_mtime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
		ZFS_TIME_ENCODE(&now, pzp->zp_mtime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
	zp = zfs_znode_alloc(zfsvfs, dbp, *oid, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	zfs_perm_init(zp, dzp, flag, vap, tx, cr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
	if (zpp) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
		kmutex_t *hash_mtx = ZFS_OBJ_MUTEX(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
		mutex_enter(hash_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
		zfs_znode_dmu_init(zp);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   632
		mutex_exit(hash_mtx);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   633
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
		*zpp = zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
		ZTOV(zp)->v_count = 0;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   637
		dmu_buf_rele(dbp, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
		zfs_znode_free(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
	dmu_object_info_t doi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
	dmu_buf_t	*db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
	znode_t		*zp;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   648
	int err;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
	*zpp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
	ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   654
	err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   655
	if (err) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   657
		return (err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
	dmu_object_info_from_db(db, &doi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
	if (doi.doi_bonus_type != DMU_OT_ZNODE ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	    doi.doi_bonus_size < sizeof (znode_phys_t)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   663
		dmu_buf_rele(db, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
	ASSERT(db->db_object == obj_num);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
	ASSERT(db->db_offset == -1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
	ASSERT(db->db_data != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
	zp = dmu_buf_get_user(db);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
	if (zp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
		mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
		ASSERT3U(zp->z_id, ==, obj_num);
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   678
		if (zp->z_unlinked) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   679
			dmu_buf_rele(db, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
			mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
			ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
			return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
		} else if (zp->z_dbuf_held) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   684
			dmu_buf_rele(db, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
			zp->z_dbuf_held = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
			VFS_HOLD(zfsvfs->z_vfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   690
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
		VN_HOLD(ZTOV(zp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
		mutex_exit(&zp->z_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   693
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
		*zpp = zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
	 * Not found create new znode/vnode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
	zp = zfs_znode_alloc(zfsvfs, db, obj_num, doi.doi_data_block_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
	ASSERT3U(zp->z_id, ==, obj_num);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	zfs_znode_dmu_init(zp);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   704
	ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	*zpp = zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   709
int
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   710
zfs_rezget(znode_t *zp)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   711
{
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   712
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   713
	dmu_object_info_t doi;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   714
	dmu_buf_t *db;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   715
	uint64_t obj_num = zp->z_id;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   716
	int err;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   717
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   718
	ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   719
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   720
	err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   721
	if (err) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   722
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   723
		return (err);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   724
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   725
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   726
	dmu_object_info_from_db(db, &doi);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   727
	if (doi.doi_bonus_type != DMU_OT_ZNODE ||
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   728
	    doi.doi_bonus_size < sizeof (znode_phys_t)) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   729
		dmu_buf_rele(db, NULL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   730
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   731
		return (EINVAL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   732
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   733
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   734
	ASSERT(db->db_object == obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   735
	ASSERT(db->db_offset == -1);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   736
	ASSERT(db->db_data != NULL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   737
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   738
	if (((znode_phys_t *)db->db_data)->zp_gen != zp->z_gen) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   739
		dmu_buf_rele(db, NULL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   740
		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   741
		return (EIO);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   742
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   743
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   744
	zp->z_dbuf = db;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   745
	zp->z_phys = db->db_data;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   746
	zfs_znode_dmu_init(zp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   747
	zp->z_unlinked = (zp->z_phys->zp_links == 0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   748
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   749
	/* release the hold from zfs_znode_dmu_init() */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   750
	VFS_RELE(zfsvfs->z_vfs);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   751
	ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   752
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   753
	return (0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   754
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4831
diff changeset
   755
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
zfs_znode_delete(znode_t *zp, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
	ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	if (zp->z_phys->zp_acl.z_acl_extern_obj) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
		error = dmu_object_free(zfsvfs->z_os,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
		    zp->z_phys->zp_acl.z_acl_extern_obj, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
		ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	error = dmu_object_free(zfsvfs->z_os, zp->z_id, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
	ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	zp->z_dbuf_held = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
	ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   772
	dmu_buf_rele(zp->z_dbuf, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
zfs_zinactive(znode_t *zp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	vnode_t	*vp = ZTOV(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
	uint64_t z_id = zp->z_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
	ASSERT(zp->z_dbuf_held && zp->z_phys);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
	 * Don't allow a zfs_zget() while were trying to release this znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
	ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
	mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
	mutex_enter(&vp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
	vp->v_count--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
	if (vp->v_count > 0 || vn_has_cached_data(vp)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
		 * If the hold count is greater than zero, somebody has
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
		 * obtained a new reference on this znode while we were
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
		 * processing it here, so we are done.  If we still have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
		 * mapped pages then we are also done, since we don't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
		 * want to inactivate the znode until the pages get pushed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
		 * XXX - if vn_has_cached_data(vp) is true, but count == 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
		 * this seems like it would leave the znode hanging with
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
		 * no chance to go inactive...
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
		mutex_exit(&vp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
		mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
		ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
	mutex_exit(&vp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
	 * If this was the last reference to a file with no links,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
	 * remove the file from the file system.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
	 */
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   815
	if (zp->z_unlinked) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
		mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
		ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id);
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
   818
		zfs_rmnode(zp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
		VFS_RELE(zfsvfs->z_vfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   822
	ASSERT(zp->z_phys);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   823
	ASSERT(zp->z_dbuf_held);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   825
	zp->z_dbuf_held = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
	mutex_exit(&zp->z_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   827
	dmu_buf_rele(zp->z_dbuf, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
	ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
   829
	VFS_RELE(zfsvfs->z_vfs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
zfs_znode_free(znode_t *zp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
	mutex_enter(&zfsvfs->z_znodes_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
	list_remove(&zfsvfs->z_all_znodes, zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	mutex_exit(&zfsvfs->z_znodes_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	kmem_cache_free(znode_cache, zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
zfs_time_stamper_locked(znode_t *zp, uint_t flag, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
	timestruc_t	now;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
	ASSERT(MUTEX_HELD(&zp->z_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
	gethrestime(&now);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	if (tx) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		dmu_buf_will_dirty(zp->z_dbuf, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
		zp->z_atime_dirty = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
		zp->z_seq++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
		zp->z_atime_dirty = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
	if (flag & AT_ATIME)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
		ZFS_TIME_ENCODE(&now, zp->z_phys->zp_atime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
	if (flag & AT_MTIME)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
		ZFS_TIME_ENCODE(&now, zp->z_phys->zp_mtime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
	if (flag & AT_CTIME)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		ZFS_TIME_ENCODE(&now, zp->z_phys->zp_ctime);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
 * Update the requested znode timestamps with the current time.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
 * If we are in a transaction, then go ahead and mark the znode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
 * dirty in the transaction so the timestamps will go to disk.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
 * Otherwise, we will get pushed next time the znode is updated
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
 * in a transaction, or when this znode eventually goes inactive.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
 * Why is this OK?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
 *  1 - Only the ACCESS time is ever updated outside of a transaction.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
 *  2 - Multiple consecutive updates will be collapsed into a single
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
 *	znode update by the transaction grouping semantics of the DMU.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
zfs_time_stamper(znode_t *zp, uint_t flag, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
	mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
	zfs_time_stamper_locked(zp, flag, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
/*
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   892
 * Grow the block size for a file.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
 *	IN:	zp	- znode of file to free data in.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
 *		size	- requested block size
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
 *		tx	- open transaction.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
 * NOTE: this function assumes that the znode is write locked.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
 */
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   900
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
	u_longlong_t	dummy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
	if (size <= zp->z_blksz)
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   907
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
	 * If the file size is already greater than the current blocksize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
	 * we will not grow.  If there is more than one block in a file,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
	 * the blocksize cannot change.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
	if (zp->z_blksz && zp->z_phys->zp_size > zp->z_blksz)
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   914
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
	error = dmu_object_set_blocksize(zp->z_zfsvfs->z_os, zp->z_id,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   917
	    size, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
	if (error == ENOTSUP)
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   919
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   920
	ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
	/* What blocksize did we actually get? */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
	dmu_object_size_from_db(zp->z_dbuf, &zp->z_blksz, &dummy);
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
 * This is a dummy interface used when pvn_vplist_dirty() should *not*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
 * be calling back into the fs for a putpage().  E.g.: when truncating
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
 * a file, the pages being "thrown away* don't need to be written out.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
    int flags, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
	ASSERT(0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
/*
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   941
 * Free space in a file.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
 *	IN:	zp	- znode of file to free data in.
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   944
 *		off	- start of section to free.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
 *		len	- length of section to free (0 => to EOF).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
 *		flag	- current file open mode flags.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
 * 	RETURN:	0 if success
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
 *		error code if failure
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
int
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   952
zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
	vnode_t *vp = ZTOV(zp);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   955
	dmu_tx_t *tx;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   956
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   957
	zilog_t *zilog = zfsvfs->z_log;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   958
	rl_t *rl;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   959
	uint64_t end = off + len;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   960
	uint64_t size, new_blksz;
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
   961
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
1394
e8d500b79ced 6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents: 869
diff changeset
   963
	if (ZTOV(zp)->v_type == VFIFO)
e8d500b79ced 6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents: 869
diff changeset
   964
		return (0);
e8d500b79ced 6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents: 869
diff changeset
   965
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
	/*
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   967
	 * If we will change zp_size then lock the whole file,
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   968
	 * otherwise just lock the range being freed.
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   969
	 */
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   970
	if (len == 0 || off + len > zp->z_phys->zp_size) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   971
		rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   972
	} else {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   973
		rl = zfs_range_lock(zp, off, len, RL_WRITER);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   974
		/* recheck, in case zp_size changed */
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   975
		if (off + len > zp->z_phys->zp_size) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   976
			/* lost race: file size changed, lock whole file */
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
   977
			zfs_range_unlock(rl);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   978
			rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   979
		}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   980
	}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   981
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   982
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
	 * Nothing to do if file already at desired length.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
	 */
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   985
	size = zp->z_phys->zp_size;
4144
068f395736ad 6465105 ZFS does not update timestamps upon the creat() of an existing file
peteh
parents: 4105
diff changeset
   986
	if (len == 0 && size == off && off != 0) {
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
   987
		zfs_range_unlock(rl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
	 * Check for any locks in the region to be freed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
	if (MANDLOCK(vp, (mode_t)zp->z_phys->zp_mode)) {
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   995
		uint64_t start = off;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   996
		uint64_t extent = len;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
   998
		if (off > size) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
			start = size;
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1000
			extent += off - size;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1001
		} else if (len == 0) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1002
			extent = size - off;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1003
		}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1004
		if (error = chklock(vp, FWRITE, start, extent, flag, NULL)) {
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
  1005
			zfs_range_unlock(rl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
			return (error);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1007
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1010
	tx = dmu_tx_create(zfsvfs->z_os);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1011
	dmu_tx_hold_bonus(tx, zp->z_id);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1012
	new_blksz = 0;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1013
	if (end > size &&
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1014
	    (!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
		 * We are growing the file past the current block size.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
		if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
			ASSERT(!ISP2(zp->z_blksz));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
			new_blksz = MIN(end, SPA_MAXBLOCKSIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
			new_blksz = MIN(end, zp->z_zfsvfs->z_max_blksz);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
		}
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1024
		dmu_tx_hold_write(tx, zp->z_id, 0, MIN(end, new_blksz));
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1025
	} else if (off < size) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1026
		/*
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1027
		 * If len == 0, we are truncating the file.
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1028
		 */
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1029
		dmu_tx_hold_free(tx, zp->z_id, off, len ? len : DMU_OBJECT_END);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1030
	}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1031
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1032
	error = dmu_tx_assign(tx, zfsvfs->z_assign);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1033
	if (error) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 1936
diff changeset
  1034
		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT)
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 1936
diff changeset
  1035
			dmu_tx_wait(tx);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1036
		dmu_tx_abort(tx);
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
  1037
		zfs_range_unlock(rl);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1038
		return (error);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1039
	}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1040
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1041
	if (new_blksz)
1669
3521dbbcb2e8 6343608 ZFS file range locking
perrin
parents: 1544
diff changeset
  1042
		zfs_grow_blocksize(zp, new_blksz, tx);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1043
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
	if (end > size || len == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
		zp->z_phys->zp_size = end;
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1046
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1047
	if (off < size) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1048
		objset_t *os = zfsvfs->z_os;
1936
b6ded90e4d4b 6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents: 1878
diff changeset
  1049
		uint64_t rlen = len;
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1050
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1051
		if (len == 0)
1936
b6ded90e4d4b 6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents: 1878
diff changeset
  1052
			rlen = -1;
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1053
		else if (end > size)
1936
b6ded90e4d4b 6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents: 1878
diff changeset
  1054
			rlen = size - off;
b6ded90e4d4b 6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents: 1878
diff changeset
  1055
		VERIFY(0 == dmu_free_range(os, zp->z_id, off, rlen, tx));
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1056
	}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1057
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1058
	if (log) {
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1059
		zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2597
diff changeset
  1060
		zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1061
	}
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1062
2237
45affe88ed99 6416482 filebench oltp workload hangs in zfs
maybee
parents: 2113
diff changeset
  1063
	zfs_range_unlock(rl);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1064
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1065
	dmu_tx_commit(tx);
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1066
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
	/*
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1068
	 * Clear any mapped pages in the truncated region.  This has to
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1069
	 * happen outside of the transaction to avoid the possibility of
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1070
	 * a deadlock with someone trying to push a page that we are
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1071
	 * about to invalidate.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
	rw_enter(&zp->z_map_lock, RW_WRITER);
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1074
	if (off < size && vn_has_cached_data(vp)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
		page_t *pp;
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1076
		uint64_t start = off & PAGEMASK;
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1077
		int poff = off & PAGEOFFSET;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1078
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1079
		if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
			 * We need to zero a partial page.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
			 */
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1083
			pagezero(pp, poff, PAGESIZE - poff);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
			start += PAGESIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
			page_unlock(pp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
		error = pvn_vplist_dirty(vp, start, zfs_no_putpage,
1878
c22df0f5603f 6413573 deadlock between fsflush() and zfs_create()
maybee
parents: 1816
diff changeset
  1088
		    B_INVAL | B_TRUNC, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
		ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
	rw_exit(&zp->z_map_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1094
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1095
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
void
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1097
zfs_create_fs(objset_t *os, cred_t *cr, uint64_t version, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
	zfsvfs_t	zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
	uint64_t	moid, doid, roid = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	znode_t		*rootzp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	vnode_t		*vp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
	vattr_t		vattr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	 * First attempt to create master node.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
  1109
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
  1110
	 * In an empty objset, there are no blocks to read and thus
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
  1111
	 * there can be no i/o errors (which we assert below).
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1394
diff changeset
  1112
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	moid = MASTER_NODE_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
	error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
	    DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
	 * Set starting attributes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1122
	error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
	ASSERT(error == 0);
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
	 * Create a delete queue.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
	 */
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
  1128
	doid = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
  1130
	error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &doid, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
	 * Create root znode.  Create minimal znode/vnode/zfsvfs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
	 * to allow zfs_mknode to work.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1136
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
	vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
	vattr.va_type = VDIR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
	vattr.va_mode = S_IFDIR|0755;
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4144
diff changeset
  1140
	vattr.va_uid = crgetuid(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4144
diff changeset
  1141
	vattr.va_gid = crgetgid(cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
	rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
	rootzp->z_zfsvfs = &zfsvfs;
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3444
diff changeset
  1145
	rootzp->z_unlinked = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
	rootzp->z_atime_dirty = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
	rootzp->z_dbuf_held = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
	vp = ZTOV(rootzp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	vn_reinit(vp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	vp->v_type = VDIR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	bzero(&zfsvfs, sizeof (zfsvfs_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
	zfsvfs.z_os = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
	zfsvfs.z_assign = TXG_NOWAIT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
	zfsvfs.z_parent = &zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
	mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
	list_create(&zfsvfs.z_all_znodes, sizeof (znode_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
	    offsetof(znode_t, z_link_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1163
	zfs_mknode(rootzp, &vattr, &roid, tx, cr, IS_ROOT_NODE, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
	ASSERT3U(rootzp->z_id, ==, roid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
	error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &roid, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	ZTOV(rootzp)->v_count = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
	kmem_cache_free(znode_cache, rootzp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
}
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1171
#endif /* _KERNEL */
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1172
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1173
/*
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1174
 * Given an object number, return its parent object number and whether
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1175
 * or not the object is an extended attribute directory.
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1176
 */
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1177
static int
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1178
zfs_obj_to_pobj(objset_t *osp, uint64_t obj, uint64_t *pobjp, int *is_xattrdir)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1179
{
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1180
	dmu_buf_t *db;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1181
	dmu_object_info_t doi;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1182
	znode_phys_t *zp;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1183
	int error;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1184
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1185
	if ((error = dmu_bonus_hold(osp, obj, FTAG, &db)) != 0)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1186
		return (error);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1187
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1188
	dmu_object_info_from_db(db, &doi);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1189
	if (doi.doi_bonus_type != DMU_OT_ZNODE ||
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1190
	    doi.doi_bonus_size < sizeof (znode_phys_t)) {
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1191
		dmu_buf_rele(db, FTAG);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1192
		return (EINVAL);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1193
	}
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1194
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1195
	zp = db->db_data;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1196
	*pobjp = zp->zp_parent;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1197
	*is_xattrdir = ((zp->zp_flags & ZFS_XATTR) != 0) &&
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1198
	    S_ISDIR(zp->zp_mode);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1199
	dmu_buf_rele(db, FTAG);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1200
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1201
	return (0);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1202
}
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1203
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1204
int
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1205
zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1206
{
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1207
	char *path = buf + len - 1;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1208
	int error;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1209
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1210
	*path = '\0';
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1211
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1212
	for (;;) {
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1213
		uint64_t pobj;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1214
		char component[MAXNAMELEN + 2];
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1215
		size_t complen;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1216
		int is_xattrdir;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1217
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1218
		if ((error = zfs_obj_to_pobj(osp, obj, &pobj,
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1219
		    &is_xattrdir)) != 0)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1220
			break;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1221
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1222
		if (pobj == obj) {
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1223
			if (path[0] != '/')
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1224
				*--path = '/';
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1225
			break;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1226
		}
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1227
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1228
		component[0] = '/';
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1229
		if (is_xattrdir) {
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1230
			(void) sprintf(component + 1, "<xattrdir>");
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1231
		} else {
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1232
			error = zap_value_search(osp, pobj, obj,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1233
			    ZFS_DIRENT_OBJ(-1ULL), component + 1);
3444
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1234
			if (error != 0)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1235
				break;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1236
		}
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1237
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1238
		complen = strlen(component);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1239
		path -= complen;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1240
		ASSERT(path >= buf);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1241
		bcopy(component, path, complen);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1242
		obj = pobj;
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1243
	}
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1244
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1245
	if (error == 0)
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1246
		(void) memmove(buf, path, buf + len - path);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1247
	return (error);
dc160a70a50d 6410433 'zpool status -v' would be more useful with filenames
ek110237
parents: 3063
diff changeset
  1248
}