zfs_znode.c revision 163eb7ff0acf105df4a6afcbbd919a066afe4a1b
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * Common Development and Distribution License (the "License").
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
893a6d32980d24be1349478f44169009d4801c25ahrens * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* Portions Copyright 2007 Jeremy Teo */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* _KERNEL */
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin * Define ZNODE_STATS to turn on statistic gathering. By default, it is only
fa9e4066f08beec538e775443c5be79dd423fcabahrens * turned on when DEBUG is also defined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DEBUG */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* ZNODE_STATS */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Functions needed for userland (ie: libzpool) are not put under
fa9e4066f08beec538e775443c5be79dd423fcabahrens * #ifdef_KERNEL; the rest of the functions have dependencies
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (such as VFS logic) that will not compile easily in userland.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Needed to close a small window in zfs_znode_move() that allows the zfsvfs to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * be freed before it can be safely accessed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We should never drop all dbuf refs without first clearing
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin * the eviction callback.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_znode_cache_constructor(void *buf, void *arg, int kmflags)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic struct {
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* ZNODE_STATS */
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin /* Copy fields. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Swap vnodes. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ozp->z_vnode = vp; /* let destructor free the overwritten vnode */
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */
fa9e4066f08beec538e775443c5be79dd423fcabahrens bcopy(ozp->z_atime, nzp->z_atime, sizeof (uint64_t) * 2);
6ce0521ac291be36119f359237066c4fb8088683perrin * Since this is just an idle znode and kmem is already dealing with
6ce0521ac291be36119f359237066c4fb8088683perrin * memory pressure, release any cached ACL.
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin * Invalidate the original znode by clearing fields that provide a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * pointer back to the znode. Set the low bit of the vfs pointer to
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * ensure that zfs_znode_move() recognizes the znode as invalid in any
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * subsequent callback.
6ce0521ac291be36119f359237066c4fb8088683perrin * Mark the znode.
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin/*ARGSUSED*/
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrinzfs_znode_move(void *buf, void *newbuf, size_t size, void *arg)
feb08c6bb47ceffa5bb7a70f2c0549113f40fcc5billm * The znode is on the file system's list of known znodes if the vfs
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * pointer is valid. We set the low bit of the vfs pointer when freeing
feb08c6bb47ceffa5bb7a70f2c0549113f40fcc5billm * the znode to invalidate it, and the memory patterns written by kmem
ec533521f091387e2911769818ae4be26219fca2fr * (baddcafe and deadbeef) set at least one of the two low bits. A newly
ec533521f091387e2911769818ae4be26219fca2fr * created znode sets the vfs pointer last of all to indicate that the
ec533521f091387e2911769818ae4be26219fca2fr * znode is known and in a valid state to be moved by this function.
6ce0521ac291be36119f359237066c4fb8088683perrin * Close a small window in which it's possible that the filesystem could
6ce0521ac291be36119f359237066c4fb8088683perrin * be unmounted and freed, and zfsvfs, though valid in the previous
6ce0521ac291be36119f359237066c4fb8088683perrin * statement, could point to unrelated memory by the time we try to
6ce0521ac291be36119f359237066c4fb8088683perrin * prevent the filesystem from being unmounted.
6ce0521ac291be36119f359237066c4fb8088683perrin ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck1);
feb08c6bb47ceffa5bb7a70f2c0549113f40fcc5billm * If the znode is still valid, then so is the file system. We know that
feb08c6bb47ceffa5bb7a70f2c0549113f40fcc5billm * no valid file system can be freed while we hold zfsvfs_lock, so we
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin * can safely ensure that the filesystem is not and will not be
feb08c6bb47ceffa5bb7a70f2c0549113f40fcc5billm * unmounted. The next statement is equivalent to ZFS_ENTER().
104e2ed78d9ef0a0f89f320108b8ca29ca3850d5perrin rrw_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG);
6ce0521ac291be36119f359237066c4fb8088683perrin ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted);
ec533521f091387e2911769818ae4be26219fca2fr * Recheck the vfs pointer in case the znode was removed just before
ec533521f091387e2911769818ae4be26219fca2fr * acquiring the lock.
6ce0521ac291be36119f359237066c4fb8088683perrin ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * At this point we know that as long as we hold z_znodes_lock, the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * znode cannot be freed and fields within the znode can be safely
fa9e4066f08beec538e775443c5be79dd423fcabahrens * accessed. Now, prevent a race with zfs_zget().
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Only move znodes that are referenced _only_ by the DNLC. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The znode is known and in a valid state to move. We're holding the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * locks needed to execute the critical section.
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin list_link_replace(&ozp->z_link_node, &nzp->z_link_node);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize zcache
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Cleanup vfs & vnode ops
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrin * Cleanup zcache
zfsfstype = 0;
if (zfs_dvnodeops)
if (zfs_fvnodeops)
if (zfs_symvnodeops)
if (zfs_xdvnodeops)
if (zfs_evnodeops)
if (zfs_sharevnodeops)
int error;
if (zfs_dvnodeops)
if (error)
return (error);
if (error)
return (error);
if (error)
return (error);
if (error)
return (error);
if (error)
return (error);
return (error);
int error;
return (error);
#ifndef NBITSMINOR64
#ifndef MAXMAJ64
#ifndef MAXMIN64
static uint64_t
#ifndef _LP64
return (dev);
#ifndef _LP64
return (NODEV32);
return (dev);
static znode_t *
int count = 0;
return (NULL);
case VDIR:
case VBLK:
case VCHR:
case VFIFO:
case VSOCK:
case VDOOR:
case VREG:
case VLNK:
return (zp);
int err;
int bonuslen;
int cnt = 0;
obj = 0;
pflags = 0;
&sa_hdl));
int err;
if (err) {
return (err);
return (EINVAL);
err = 0;
return (err);
return (err);
int err;
int count = 0;
if (err) {
return (err);
return (EINVAL);
return (EIO);
return (EIO);
if (acl_obj) {
int error;
ASSERT(0);
int error;
top:
newblksz = 0;
if (error) {
goto top;
return (error);
if (newblksz)
int error;
return (error);
int error;
int count = 0;
if (error) {
return (error);
top:
if (error) {
goto top;
return (error);
if (end == 0) {
int count = 0;
int error;
sizeof (mode))) != 0)
return (error);
goto log;
return (error);
return (error);
if (len == 0) {
return (error);
log:
if (error) {
goto log;
return (error);
int error;
char *name;
sa_obj = 0;
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
int error;
return (error);
return (error);
int error;
return (error);
return (ENOTSUP);
if (error != 0) {
return (error);
int *is_xattrdir)
int count = 0;
int error;
return (error);
int count = 0;
int error;
int is_xattrdir;
if (prevdb)
&is_xattrdir)) != 0)
if (is_xattrdir) {
if (error != 0)
if (error != 0) {
if (error == 0)
return (error);
int error;
if (error != 0)
return (error);
if (error != 0)
return (error);
return (error);
int error;
if (error != 0)
return (error);
if (error != 0)
return (error);
if (error != 0) {
return (error);
return (error);