usr/src/uts/common/fs/dcfs/dc_vnops.c
author John Levon <john.levon@sun.com>
Wed, 16 Jun 2010 10:02:44 -0700
changeset 12633 9f2cda0ed938
parent 7858 5697e5c3054e
child 12729 c5742d0d507e
permissions -rw-r--r--
PSARC 2010/144 lofi(7D) in non global zones 6354954 lofi support in non-global zones 6942891 prof_lookup_globaldev() leaks rootdir refs 6945005 lofiadm -a /dev/lofi/1: recursive mutex enter 6946486 lofi_ioctl() shouldn't allow disk ioctl()s on /dev/lofictl
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     1
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     2
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     3
 * CDDL HEADER START
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     4
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     5
 * The contents of this file are subject to the terms of the
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     6
 * Common Development and Distribution License (the "License").
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     7
 * You may not use this file except in compliance with the License.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     8
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    12
 * and limitations under the License.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    13
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    19
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    20
 * CDDL HEADER END
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    21
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    22
/*
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 7858
diff changeset
    23
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    24
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    25
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    26
/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    27
/*	  All Rights Reserved  	*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    28
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    29
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    30
 * University Copyright- Copyright (c) 1982, 1986, 1988
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    31
 * The Regents of the University of California
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    32
 * All Rights Reserved
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    33
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    34
 * University Acknowledgment- Portions of this document are derived from
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    35
 * software developed by the University of California, Berkeley, and its
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    36
 * contributors.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    37
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    38
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    39
#include <sys/types.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    40
#include <sys/thread.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    41
#include <sys/t_lock.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    42
#include <sys/param.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    43
#include <sys/systm.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    44
#include <sys/bitmap.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    45
#include <sys/buf.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    46
#include <sys/cmn_err.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    47
#include <sys/conf.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    48
#include <sys/ddi.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    49
#include <sys/debug.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    50
#include <sys/errno.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    51
#include <sys/time.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    52
#include <sys/fcntl.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    53
#include <sys/flock.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    54
#include <sys/file.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    55
#include <sys/kmem.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    56
#include <sys/mman.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    57
#include <sys/vmsystm.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    58
#include <sys/open.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    59
#include <sys/swap.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    60
#include <sys/sysmacros.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    61
#include <sys/uio.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    62
#include <sys/vfs.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    63
#include <sys/vfs_opreg.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    64
#include <sys/vnode.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    65
#include <sys/stat.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    66
#include <sys/poll.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    67
#include <sys/zmod.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    68
#include <sys/fs/decomp.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    69
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    70
#include <vm/hat.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    71
#include <vm/as.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    72
#include <vm/page.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    73
#include <vm/pvn.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    74
#include <vm/seg_vn.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    75
#include <vm/seg_kmem.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    76
#include <vm/seg_map.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    77
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    78
#include <fs/fs_subr.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    79
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    80
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    81
 * dcfs - A filesystem for automatic decompressing of fiocompressed files
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    82
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    83
 * This filesystem is a layered filesystem that sits on top of a normal
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    84
 * persistent filesystem and provides automatic decompression of files
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    85
 * that have been previously compressed and stored on the host file system.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    86
 * This is a pseudo filesystem in that it does not persist data, rather it
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    87
 * intercepts file lookup requests on the host filesystem and provides
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    88
 * transparent decompression of those files. Currently the only supported
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    89
 * host filesystem is ufs.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    90
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    91
 * A file is compressed via a userland utility (currently cmd/boot/fiocompress)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    92
 * and marked by fiocompress as a compressed file via a flag in the on-disk
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    93
 * inode (set via a ufs ioctl() - see `ufs_vnops.c`ufs_ioctl()`_FIO_COMPRESSED
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    94
 * ufs_lookup checks for this flag and if set, passes control to decompvp
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    95
 * a function defined in this (dcfs) filesystem. decomvp uncompresses the file
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    96
 * and returns a dcfs vnode to the VFS layer.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    97
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    98
 * dcfs is layered on top of ufs and passes requests involving persistence
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
    99
 * to the underlying ufs filesystem. The compressed files currently cannot be
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   100
 * written to.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   101
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   102
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   103
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   104
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   105
 * Define data structures within this file.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   106
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   107
#define	DCSHFT		5
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   108
#define	DCTABLESIZE	16
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   109
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   110
#if ((DCTABLESIZE & (DCTABLESIZE - 1)) == 0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   111
#define	DCHASH(vp) (((uintptr_t)(vp) >> DCSHFT) & (DCTABLESIZE - 1))
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   112
#else
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   113
#define	DCHASH(vp) (((uintptr_t)(vp) >> DCSHFT) % DTABLESIZEC)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   114
#endif
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   115
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   116
#define	DCLRUSIZE	16
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   117
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   118
#define	DCCACHESIZE	4
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   119
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   120
#define	rounddown(x, y)	((x) & ~((y) - 1))
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   121
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   122
struct dcnode	*dctable[DCTABLESIZE];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   123
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   124
struct dcnode	*dclru;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   125
static int	dclru_len;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   126
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   127
kmutex_t	dctable_lock;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   128
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   129
dev_t		dcdev;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   130
struct vfs	dc_vfs;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   131
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   132
struct kmem_cache *dcnode_cache;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   133
struct kmem_cache *dcbuf_cache[DCCACHESIZE];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   134
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   135
kmutex_t	dccache_lock;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   136
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   137
static int dcinit(int, char *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   138
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   139
static struct dcnode	*dcnode_alloc(void);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   140
static void		dcnode_free(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   141
static void		dcnode_recycle(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   142
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   143
static void		dcinsert(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   144
static void		dcdelete(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   145
static struct dcnode	*dcfind(struct vnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   146
static void		dclru_add(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   147
static void		dclru_sub(struct dcnode *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   148
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   149
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   150
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   151
 * This is the loadable module wrapper.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   152
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   153
#include <sys/modctl.h>
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   154
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   155
struct vfsops *dc_vfsops;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   156
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   157
static vfsdef_t vfw = {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   158
	VFSDEF_VERSION,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   159
	"dcfs",
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   160
	dcinit,
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 7858
diff changeset
   161
	VSW_ZMOUNT,
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   162
	NULL
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   163
};
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   164
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   165
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   166
 * Module linkage information for the kernel.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   167
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   168
extern struct mod_ops mod_fsops;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   169
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   170
static struct modlfs modlfs = {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   171
	&mod_fsops, "compressed filesystem", &vfw
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   172
};
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   173
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   174
static struct modlinkage modlinkage = {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   175
	MODREV_1, (void *)&modlfs, NULL
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   176
};
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   177
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   178
int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   179
_init()
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   180
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   181
	return (mod_install(&modlinkage));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   182
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   183
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   184
int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   185
_info(struct modinfo *modinfop)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   186
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   187
	return (mod_info(&modlinkage, modinfop));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   188
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   189
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   190
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   191
static int dc_open(struct vnode **, int, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   192
static int dc_close(struct vnode *, int, int, offset_t,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   193
    struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   194
static int dc_read(struct vnode *, struct uio *, int, struct cred *,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   195
    struct caller_context *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   196
static int dc_getattr(struct vnode *, struct vattr *, int,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   197
    struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   198
static int dc_setattr(struct vnode *, struct vattr *, int, struct cred *,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   199
    struct caller_context *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   200
static int dc_access(struct vnode *, int, int,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   201
    struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   202
static int dc_fsync(struct vnode *, int, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   203
static void dc_inactive(struct vnode *, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   204
static int dc_fid(struct vnode *, struct fid *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   205
static int dc_seek(struct vnode *, offset_t, offset_t *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   206
static int dc_frlock(struct vnode *, int, struct flock64 *, int, offset_t,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   207
    struct flk_callback *, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   208
static int dc_getpage(struct vnode *, offset_t, size_t, uint_t *,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   209
    struct page **, size_t, struct seg *, caddr_t, enum seg_rw,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   210
    struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   211
static int dc_putpage(struct vnode *, offset_t, size_t, int,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   212
    struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   213
static int dc_map(struct vnode *, offset_t, struct as *, caddr_t *, size_t,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   214
    uchar_t, uchar_t, uint_t, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   215
static int dc_addmap(struct vnode *, offset_t, struct as *, caddr_t, size_t,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   216
    uchar_t, uchar_t, uint_t, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   217
static int dc_delmap(struct vnode *, offset_t, struct as *, caddr_t, size_t,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   218
    uint_t, uint_t, uint_t, struct cred *, caller_context_t *);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   219
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   220
struct vnodeops *dc_vnodeops;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   221
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   222
const fs_operation_def_t dc_vnodeops_template[] = {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   223
	VOPNAME_OPEN,			{ .vop_open = dc_open },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   224
	VOPNAME_CLOSE,			{ .vop_close = dc_close },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   225
	VOPNAME_READ,			{ .vop_read = dc_read },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   226
	VOPNAME_GETATTR,		{ .vop_getattr =  dc_getattr },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   227
	VOPNAME_SETATTR,		{ .vop_setattr = dc_setattr },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   228
	VOPNAME_ACCESS,			{ .vop_access = dc_access },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   229
	VOPNAME_FSYNC,			{ .vop_fsync = dc_fsync },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   230
	VOPNAME_INACTIVE,		{ .vop_inactive = dc_inactive },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   231
	VOPNAME_FID,			{ .vop_fid = dc_fid },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   232
	VOPNAME_SEEK,			{ .vop_seek = dc_seek },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   233
	VOPNAME_FRLOCK,			{ .vop_frlock = dc_frlock },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   234
	VOPNAME_GETPAGE,		{ .vop_getpage = dc_getpage },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   235
	VOPNAME_PUTPAGE,		{ .vop_putpage = dc_putpage },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   236
	VOPNAME_MAP,			{ .vop_map = dc_map },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   237
	VOPNAME_ADDMAP,			{ .vop_addmap = dc_addmap },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   238
	VOPNAME_DELMAP,			{ .vop_delmap = dc_delmap },
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   239
	NULL,				NULL
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   240
};
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   241
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   242
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   243
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   244
dc_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   245
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   246
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   247
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   248
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   249
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   250
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   251
dc_close(struct vnode *vp, int flag, int count, offset_t off,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   252
    struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   253
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   254
	(void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   255
	cleanshares(vp, ttoproc(curthread)->p_pid);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   256
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   257
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   258
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   259
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   260
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   261
dc_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   262
	struct caller_context *ct)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   263
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   264
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   265
	size_t rdsize = MAX(MAXBSIZE, dp->dc_hdr->ch_blksize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   266
	size_t fsize = dp->dc_hdr->ch_fsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   267
	int error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   268
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   269
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   270
	 * Loop through file with segmap, decompression will occur
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   271
	 * in dc_getapage
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   272
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   273
	do {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   274
		caddr_t base;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   275
		size_t n;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   276
		offset_t mapon;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   277
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   278
		/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   279
		 * read to end of block or file
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   280
		 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   281
		mapon = uiop->uio_loffset & (rdsize - 1);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   282
		n = MIN(rdsize - mapon, uiop->uio_resid);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   283
		n = MIN(n, fsize - uiop->uio_loffset);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   284
		if (n == 0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   285
			return (0);	/* at EOF */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   286
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   287
		base = segmap_getmapflt(segkmap, vp, uiop->uio_loffset, n, 1,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   288
		    S_READ);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   289
		error = uiomove(base + mapon, n, UIO_READ, uiop);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   290
		if (!error) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   291
			uint_t flags;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   292
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   293
			if (n + mapon == rdsize || uiop->uio_loffset == fsize)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   294
				flags = SM_DONTNEED;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   295
			else
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   296
				flags = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   297
			error = segmap_release(segkmap, base, flags);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   298
		} else
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   299
			(void) segmap_release(segkmap, base, 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   300
	} while (!error && uiop->uio_resid);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   301
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   302
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   303
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   304
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   305
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   306
dc_getattr(struct vnode *vp, struct vattr *vap, int flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   307
    cred_t *cred, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   308
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   309
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   310
	struct vnode *subvp = dp->dc_subvp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   311
	int error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   312
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   313
	error = VOP_GETATTR(subvp, vap, flags, cred, ctp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   314
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   315
	/* substitute uncompressed size */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   316
	vap->va_size = dp->dc_hdr->ch_fsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   317
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   318
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   319
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   320
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   321
dc_setattr(struct vnode *vp, struct vattr *vap, int flags, cred_t *cred,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   322
    caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   323
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   324
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   325
	struct vnode *subvp = dp->dc_subvp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   326
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   327
	return (VOP_SETATTR(subvp, vap, flags, cred, ctp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   328
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   329
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   330
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   331
dc_access(struct vnode *vp, int mode, int flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   332
    cred_t *cred, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   333
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   334
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   335
	struct vnode *subvp = dp->dc_subvp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   336
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   337
	return (VOP_ACCESS(subvp, mode, flags, cred, ctp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   338
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   339
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   340
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   341
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   342
dc_fsync(vnode_t *vp, int syncflag, cred_t *cred, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   343
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   344
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   345
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   346
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   347
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   348
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   349
dc_inactive(struct vnode *vp, cred_t *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   350
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   351
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   352
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   353
	mutex_enter(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   354
	mutex_enter(&vp->v_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   355
	ASSERT(vp->v_count >= 1);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   356
	if (--vp->v_count != 0) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   357
		/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   358
		 * Somebody accessed the dcnode before we got a chance to
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   359
		 * remove it.  They will remove it when they do a vn_rele.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   360
		 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   361
		mutex_exit(&vp->v_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   362
		mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   363
		return;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   364
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   365
	mutex_exit(&vp->v_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   366
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   367
	dcnode_free(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   368
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   369
	mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   370
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   371
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   372
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   373
dc_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   374
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   375
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   376
	struct vnode *subvp = dp->dc_subvp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   377
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   378
	return (VOP_FID(subvp, fidp, ctp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   379
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   380
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   381
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   382
dc_seek(struct vnode *vp, offset_t oof, offset_t *noffp, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   383
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   384
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   385
	struct vnode *subvp = dp->dc_subvp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   386
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   387
	return (VOP_SEEK(subvp, oof, noffp, ctp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   388
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   389
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   390
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   391
dc_frlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   392
    offset_t offset, struct flk_callback *flk_cbp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   393
    cred_t *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   394
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   395
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   396
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   397
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   398
	 * If file is being mapped, disallow frlock.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   399
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   400
	if (dp->dc_mapcnt > 0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   401
		return (EAGAIN);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   402
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   403
	return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ctp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   404
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   405
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   406
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   407
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   408
dc_getblock_miss(struct vnode *vp, offset_t off, size_t len, struct page **ppp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   409
    struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   410
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   411
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   412
	struct comphdr *hdr = dp->dc_hdr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   413
	struct page *pp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   414
	struct buf *bp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   415
	caddr_t saddr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   416
	off_t cblkno;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   417
	size_t rdoff, rdsize, dsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   418
	long xlen;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   419
	int error, zerr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   420
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   421
	ASSERT(len == hdr->ch_blksize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   422
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   423
	 * Get destination pages and make them addressable
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   424
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   425
	pp = page_create_va(vp, off, len, PG_WAIT, seg, addr);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   426
	bp = pageio_setup(pp, len, vp, B_READ);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   427
	bp_mapin(bp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   428
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   429
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   430
	 * read compressed data from subordinate vnode
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   431
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   432
	saddr = kmem_cache_alloc(dp->dc_bufcache, KM_SLEEP);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   433
	cblkno = off / len;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   434
	rdoff = hdr->ch_blkmap[cblkno];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   435
	rdsize = hdr->ch_blkmap[cblkno + 1] - rdoff;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   436
	error = vn_rdwr(UIO_READ, dp->dc_subvp, saddr, rdsize, rdoff,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   437
	    UIO_SYSSPACE, 0, 0, cr, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   438
	if (error)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   439
		goto cleanup;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   440
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   441
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   442
	 * Uncompress
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   443
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   444
	dsize = len;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   445
	zerr = z_uncompress(bp->b_un.b_addr, &dsize, saddr, dp->dc_zmax);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   446
	if (zerr != Z_OK) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   447
		error = EIO;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   448
		goto cleanup;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   449
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   450
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   451
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   452
	 * Handle EOF
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   453
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   454
	xlen = hdr->ch_fsize - off;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   455
	if (xlen < len) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   456
		bzero(bp->b_un.b_addr + xlen, len - xlen);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   457
		if (dsize != xlen)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   458
			error = EIO;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   459
	} else if (dsize != len)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   460
		error = EIO;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   461
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   462
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   463
	 * Clean up
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   464
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   465
cleanup:
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   466
	kmem_cache_free(dp->dc_bufcache, saddr);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   467
	pageio_done(bp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   468
	*ppp = pp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   469
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   470
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   471
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   472
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   473
dc_getblock(struct vnode *vp, offset_t off, size_t len, struct page **ppp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   474
    struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   475
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   476
	struct page *pp, *plist = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   477
	offset_t pgoff;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   478
	int rdblk;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   479
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   480
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   481
	 * pvn_read_kluster() doesn't quite do what we want, since it
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   482
	 * thinks sub block reads are ok.  Here we always decompress
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   483
	 * a full block.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   484
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   485
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   486
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   487
	 * Check page cache
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   488
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   489
	rdblk = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   490
	for (pgoff = off; pgoff < off + len; pgoff += PAGESIZE) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   491
		pp = page_lookup(vp, pgoff, SE_EXCL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   492
		if (pp == NULL) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   493
			rdblk = 1;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   494
			break;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   495
		}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   496
		page_io_lock(pp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   497
		page_add(&plist, pp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   498
		plist = plist->p_next;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   499
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   500
	if (!rdblk) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   501
		*ppp = plist;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   502
		return (0);	/* all pages in cache */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   503
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   504
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   505
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   506
	 * Undo any locks so getblock_miss has an open field
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   507
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   508
	if (plist != NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   509
		pvn_io_done(plist);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   510
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   511
	return (dc_getblock_miss(vp, off, len, ppp, seg, addr, rw, cr));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   512
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   513
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   514
/*ARGSUSED10*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   515
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   516
dc_getpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   517
    struct page *pl[], size_t plsz, struct seg *seg, caddr_t addr,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   518
    enum seg_rw rw, struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   519
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   520
	struct dcnode *dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   521
	struct comphdr *hdr = dp->dc_hdr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   522
	struct page *pp, *plist = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   523
	caddr_t vp_baddr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   524
	offset_t vp_boff, vp_bend;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   525
	size_t bsize = hdr->ch_blksize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   526
	int nblks, error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   527
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   528
	/* does not support write */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   529
	if (rw == S_WRITE) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   530
		panic("write attempt on compressed file");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   531
		/*NOTREACHED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   532
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   533
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   534
	if (protp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   535
		*protp = PROT_ALL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   536
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   537
	 * We don't support asynchronous operation at the moment, so
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   538
	 * just pretend we did it.  If the pages are ever actually
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   539
	 * needed, they'll get brought in then.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   540
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   541
	if (pl == NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   542
		return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   543
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   544
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   545
	 * Calc block start and end offsets
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   546
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   547
	vp_boff = rounddown(off, bsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   548
	vp_bend = roundup(off + len, bsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   549
	vp_baddr = (caddr_t)rounddown((uintptr_t)addr, bsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   550
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   551
	nblks = (vp_bend - vp_boff) / bsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   552
	while (nblks--) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   553
		error = dc_getblock(vp, vp_boff, bsize, &pp, seg, vp_baddr,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   554
		    rw, cr);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   555
		page_list_concat(&plist, &pp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   556
		vp_boff += bsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   557
		vp_baddr += bsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   558
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   559
	if (!error)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   560
		pvn_plist_init(plist, pl, plsz, off, len, rw);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   561
	else
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   562
		pvn_read_done(plist, B_ERROR);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   563
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   564
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   565
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   566
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   567
 * This function should never be called. We need to have it to pass
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   568
 * it as an argument to other functions.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   569
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   570
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   571
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   572
dc_putapage(struct vnode *vp, struct page *pp, u_offset_t *offp, size_t *lenp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   573
    int flags, struct cred *cr)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   574
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   575
	/* should never happen */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   576
	cmn_err(CE_PANIC, "dcfs: dc_putapage: dirty page");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   577
	/*NOTREACHED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   578
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   579
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   580
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   581
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   582
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   583
 * The only flags we support are B_INVAL, B_FREE and B_DONTNEED.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   584
 * B_INVAL is set by:
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   585
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   586
 *	1) the MC_SYNC command of memcntl(2) to support the MS_INVALIDATE flag.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   587
 *	2) the MC_ADVISE command of memcntl(2) with the MADV_DONTNEED advice
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   588
 *	   which translates to an MC_SYNC with the MS_INVALIDATE flag.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   589
 *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   590
 * The B_FREE (as well as the B_DONTNEED) flag is set when the
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   591
 * MADV_SEQUENTIAL advice has been used. VOP_PUTPAGE is invoked
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   592
 * from SEGVN to release pages behind a pagefault.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   593
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   594
/*ARGSUSED5*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   595
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   596
dc_putpage(struct vnode *vp, offset_t off, size_t len, int flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   597
    struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   598
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   599
	int error = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   600
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   601
	if (vp->v_count == 0) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   602
		panic("dcfs_putpage: bad v_count");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   603
		/*NOTREACHED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   604
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   605
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   606
	if (vp->v_flag & VNOMAP)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   607
		return (ENOSYS);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   608
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   609
	if (!vn_has_cached_data(vp))	/* no pages mapped */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   610
		return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   611
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   612
	if (len == 0)		/* from 'off' to EOF */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   613
		error = pvn_vplist_dirty(vp, off, dc_putapage, flags, cr);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   614
	else {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   615
		offset_t io_off;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   616
		se_t se = (flags & (B_INVAL | B_FREE)) ? SE_EXCL : SE_SHARED;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   617
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   618
		for (io_off = off; io_off < off + len; io_off += PAGESIZE) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   619
			page_t *pp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   620
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   621
			/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   622
			 * We insist on getting the page only if we are
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   623
			 * about to invalidate, free or write it and
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   624
			 * the B_ASYNC flag is not set.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   625
			 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   626
			if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0))
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   627
				pp = page_lookup(vp, io_off, se);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   628
			else
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   629
				pp = page_lookup_nowait(vp, io_off, se);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   630
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   631
			if (pp == NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   632
				continue;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   633
			/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   634
			 * Normally pvn_getdirty() should return 0, which
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   635
			 * impies that it has done the job for us.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   636
			 * The shouldn't-happen scenario is when it returns 1.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   637
			 * This means that the page has been modified and
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   638
			 * needs to be put back.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   639
			 * Since we can't write to a dcfs compressed file,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   640
			 * we fake a failed I/O and force pvn_write_done()
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   641
			 * to destroy the page.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   642
			 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   643
			if (pvn_getdirty(pp, flags) == 1) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   644
				cmn_err(CE_NOTE, "dc_putpage: dirty page");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   645
				pvn_write_done(pp, flags |
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   646
				    B_ERROR | B_WRITE | B_INVAL | B_FORCE);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   647
			}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   648
		}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   649
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   650
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   651
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   652
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   653
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   654
dc_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   655
    size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   656
    struct cred *cred, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   657
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   658
	struct vattr vattr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   659
	struct segvn_crargs vn_a;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   660
	int error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   661
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   662
	if (vp->v_flag & VNOMAP)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   663
		return (ENOSYS);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   664
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   665
	if (off < (offset_t)0 || (offset_t)(off + len) < (offset_t)0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   666
		return (ENXIO);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   667
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   668
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   669
	 * If file is being locked, disallow mapping.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   670
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   671
	if (error = VOP_GETATTR(VTODC(vp)->dc_subvp, &vattr, 0, cred, ctp))
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   672
		return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   673
	if (vn_has_mandatory_locks(vp, vattr.va_mode))
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   674
		return (EAGAIN);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   675
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   676
	as_rangelock(as);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   677
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   678
	if ((flags & MAP_FIXED) == 0) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   679
		map_addr(addrp, len, off, 1, flags);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   680
		if (*addrp == NULL) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   681
			as_rangeunlock(as);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   682
			return (ENOMEM);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   683
		}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   684
	} else {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   685
		/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   686
		 * User specified address - blow away any previous mappings
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   687
		 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   688
		(void) as_unmap(as, *addrp, len);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   689
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   690
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   691
	vn_a.vp = vp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   692
	vn_a.offset = off;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   693
	vn_a.type = flags & MAP_TYPE;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   694
	vn_a.prot = prot;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   695
	vn_a.maxprot = maxprot;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   696
	vn_a.flags = flags & ~MAP_TYPE;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   697
	vn_a.cred = cred;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   698
	vn_a.amp = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   699
	vn_a.szc = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   700
	vn_a.lgrp_mem_policy_flags = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   701
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   702
	error = as_map(as, *addrp, len, segvn_create, &vn_a);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   703
	as_rangeunlock(as);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   704
	return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   705
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   706
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   707
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   708
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   709
dc_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   710
    size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   711
    struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   712
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   713
	struct dcnode *dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   714
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   715
	if (vp->v_flag & VNOMAP)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   716
		return (ENOSYS);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   717
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   718
	dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   719
	mutex_enter(&dp->dc_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   720
	dp->dc_mapcnt += btopr(len);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   721
	mutex_exit(&dp->dc_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   722
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   723
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   724
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   725
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   726
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   727
dc_delmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   728
    size_t len, uint_t prot, uint_t maxprot, uint_t flags,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   729
    struct cred *cr, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   730
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   731
	struct dcnode *dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   732
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   733
	if (vp->v_flag & VNOMAP)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   734
		return (ENOSYS);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   735
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   736
	dp = VTODC(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   737
	mutex_enter(&dp->dc_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   738
	dp->dc_mapcnt -= btopr(len);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   739
	ASSERT(dp->dc_mapcnt >= 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   740
	mutex_exit(&dp->dc_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   741
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   742
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   743
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   744
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   745
 * Constructor/destructor routines for dcnodes
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   746
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   747
/*ARGSUSED1*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   748
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   749
dcnode_constructor(void *buf, void *cdrarg, int kmflags)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   750
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   751
	struct dcnode *dp = buf;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   752
	struct vnode *vp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   753
6754
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   754
	vp = dp->dc_vp = vn_alloc(kmflags);
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   755
	if (vp == NULL) {
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   756
		return (-1);
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   757
	}
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   758
	vp->v_data = dp;
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   759
	vp->v_type = VREG;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   760
	vp->v_flag = VNOSWAP;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   761
	vp->v_vfsp = &dc_vfs;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   762
	vn_setops(vp, dc_vnodeops);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   763
	vn_exists(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   764
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   765
	mutex_init(&dp->dc_lock, NULL, MUTEX_DEFAULT, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   766
	dp->dc_mapcnt = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   767
	dp->dc_lrunext = dp->dc_lruprev = NULL;
6754
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   768
	dp->dc_hdr = NULL;
8c41f9218cb4 6708657 assertion failed: !(kmflags & 0x0001) in dcnode_constructor
tomee
parents: 5648
diff changeset
   769
	dp->dc_subvp = NULL;
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   770
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   771
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   772
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   773
/*ARGSUSED*/
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   774
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   775
dcnode_destructor(void *buf, void *cdrarg)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   776
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   777
	struct dcnode *dp = buf;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   778
	struct vnode *vp = DCTOV(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   779
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   780
	mutex_destroy(&dp->dc_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   781
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   782
	VERIFY(dp->dc_hdr == NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   783
	VERIFY(dp->dc_subvp == NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   784
	vn_invalid(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   785
	vn_free(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   786
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   787
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   788
static struct dcnode *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   789
dcnode_alloc(void)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   790
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   791
	struct dcnode *dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   792
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   793
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   794
	 * If the free list is above DCLRUSIZE
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   795
	 * re-use one from it
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   796
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   797
	mutex_enter(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   798
	if (dclru_len < DCLRUSIZE) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   799
		mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   800
		dp = kmem_cache_alloc(dcnode_cache, KM_SLEEP);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   801
	} else {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   802
		ASSERT(dclru != NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   803
		dp = dclru;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   804
		dclru_sub(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   805
		dcdelete(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   806
		mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   807
		dcnode_recycle(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   808
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   809
	return (dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   810
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   811
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   812
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   813
dcnode_free(struct dcnode *dp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   814
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   815
	struct vnode *vp = DCTOV(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   816
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   817
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   818
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   819
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   820
	 * If no cached pages, no need to put it on lru
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   821
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   822
	if (!vn_has_cached_data(vp)) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   823
		dcdelete(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   824
		dcnode_recycle(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   825
		kmem_cache_free(dcnode_cache, dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   826
		return;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   827
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   828
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   829
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   830
	 * Add to lru, if it's over the limit, free from head
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   831
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   832
	dclru_add(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   833
	if (dclru_len > DCLRUSIZE) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   834
		dp = dclru;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   835
		dclru_sub(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   836
		dcdelete(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   837
		dcnode_recycle(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   838
		kmem_cache_free(dcnode_cache, dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   839
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   840
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   841
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   842
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   843
dcnode_recycle(struct dcnode *dp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   844
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   845
	struct vnode *vp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   846
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   847
	vp = DCTOV(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   848
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   849
	VN_RELE(dp->dc_subvp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   850
	dp->dc_subvp = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   851
	(void) pvn_vplist_dirty(vp, 0, dc_putapage, B_INVAL, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   852
	kmem_free(dp->dc_hdr, dp->dc_hdrsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   853
	dp->dc_hdr = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   854
	dp->dc_hdrsize = dp->dc_zmax = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   855
	dp->dc_bufcache = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   856
	dp->dc_mapcnt = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   857
	vn_reinit(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   858
	vp->v_type = VREG;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   859
	vp->v_flag = VNOSWAP;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   860
	vp->v_vfsp = &dc_vfs;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   861
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   862
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   863
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   864
dcinit(int fstype, char *name)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   865
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   866
	static const fs_operation_def_t dc_vfsops_template[] = {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   867
		NULL, NULL
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   868
	};
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   869
	int error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   870
	major_t dev;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   871
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   872
	error = vfs_setfsops(fstype, dc_vfsops_template, &dc_vfsops);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   873
	if (error) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   874
		cmn_err(CE_WARN, "dcinit: bad vfs ops template");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   875
		return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   876
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   877
	VFS_INIT(&dc_vfs, dc_vfsops, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   878
	dc_vfs.vfs_flag = VFS_RDONLY;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   879
	dc_vfs.vfs_fstype = fstype;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   880
	if ((dev = getudev()) == (major_t)-1)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   881
		dev = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   882
	dcdev = makedevice(dev, 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   883
	dc_vfs.vfs_dev = dcdev;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   884
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   885
	error = vn_make_ops(name, dc_vnodeops_template, &dc_vnodeops);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   886
	if (error != 0) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   887
		(void) vfs_freevfsops_by_type(fstype);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   888
		cmn_err(CE_WARN, "dcinit: bad vnode ops template");
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   889
		return (error);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   890
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   891
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   892
	mutex_init(&dctable_lock, NULL, MUTEX_DEFAULT, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   893
	mutex_init(&dccache_lock, NULL, MUTEX_DEFAULT, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   894
	dcnode_cache = kmem_cache_create("dcnode_cache", sizeof (struct dcnode),
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   895
	    0, dcnode_constructor, dcnode_destructor, NULL, NULL, NULL, 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   896
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   897
	return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   898
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   899
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   900
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   901
 * Return shadow vnode with the given vp as its subordinate
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   902
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   903
struct vnode *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   904
decompvp(struct vnode *vp, cred_t *cred, caller_context_t *ctp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   905
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   906
	struct dcnode *dp, *ndp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   907
	struct comphdr thdr, *hdr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   908
	struct kmem_cache **cpp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   909
	struct vattr vattr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   910
	size_t hdrsize, bsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   911
	int error;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   912
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   913
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   914
	 * See if we have an existing shadow
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   915
	 * If none, we have to manufacture one
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   916
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   917
	mutex_enter(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   918
	dp = dcfind(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   919
	mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   920
	if (dp != NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   921
		return (DCTOV(dp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   922
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   923
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   924
	 * Make sure it's a valid compressed file
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   925
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   926
	hdr = &thdr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   927
	error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, sizeof (struct comphdr), 0,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   928
	    UIO_SYSSPACE, 0, 0, cred, NULL);
7858
5697e5c3054e 6755292 Fast reboot should support failsafe
Krishnendu Sadhukhan - Sun Microsystems <Krishnendu.Sadhukhan@Sun.COM>
parents: 6754
diff changeset
   929
	if (error || hdr->ch_magic != CH_MAGIC_ZLIB ||
5648
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   930
	    hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB ||
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   931
	    hdr->ch_fsize == 0 || hdr->ch_blksize < PAGESIZE ||
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   932
	    hdr->ch_blksize > ptob(DCCACHESIZE) ||
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   933
	    (hdr->ch_blksize & (hdr->ch_blksize - 1)) != 0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   934
		return (NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   935
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   936
	/* get underlying file size */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   937
	if (VOP_GETATTR(vp, &vattr, 0, cred, ctp) != 0)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   938
		return (NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   939
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   940
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   941
	 * Re-read entire header
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   942
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   943
	hdrsize = hdr->ch_blkmap[0] + sizeof (uint64_t);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   944
	hdr = kmem_alloc(hdrsize, KM_SLEEP);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   945
	error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, hdrsize, 0, UIO_SYSSPACE,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   946
	    0, 0, cred, NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   947
	if (error) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   948
		kmem_free(hdr, hdrsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   949
		return (NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   950
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   951
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   952
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   953
	 * add extra blkmap entry to make dc_getblock()'s
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   954
	 * life easier
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   955
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   956
	bsize = hdr->ch_blksize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   957
	hdr->ch_blkmap[((hdr->ch_fsize-1) / bsize) + 1] = vattr.va_size;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   958
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   959
	ndp = dcnode_alloc();
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   960
	ndp->dc_subvp = vp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   961
	VN_HOLD(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   962
	ndp->dc_hdr = hdr;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   963
	ndp->dc_hdrsize = hdrsize;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   964
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   965
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   966
	 * Allocate kmem cache if none there already
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   967
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   968
	ndp->dc_zmax = ZMAXBUF(bsize);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   969
	cpp = &dcbuf_cache[btop(bsize)];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   970
	mutex_enter(&dccache_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   971
	if (*cpp == NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   972
		*cpp = kmem_cache_create("dcbuf_cache", ndp->dc_zmax, 0, NULL,
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   973
		    NULL, NULL, NULL, NULL, 0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   974
	mutex_exit(&dccache_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   975
	ndp->dc_bufcache = *cpp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   976
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   977
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   978
	 * Recheck table in case someone else created shadow
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   979
	 * while we were blocked above.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   980
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   981
	mutex_enter(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   982
	dp = dcfind(vp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   983
	if (dp != NULL) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   984
		mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   985
		dcnode_recycle(ndp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   986
		kmem_cache_free(dcnode_cache, ndp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   987
		return (DCTOV(dp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   988
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   989
	dcinsert(ndp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   990
	mutex_exit(&dctable_lock);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   991
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   992
	return (DCTOV(ndp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   993
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   994
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   995
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   996
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   997
 * dcnode lookup table
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   998
 * These routines maintain a table of dcnodes hashed by their
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
   999
 * subordinate vnode so that they can be found if they already
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1000
 * exist in the vnode cache
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1001
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1002
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1003
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1004
 * Put a dcnode in the table.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1005
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1006
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1007
dcinsert(struct dcnode *newdp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1008
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1009
	int idx = DCHASH(newdp->dc_subvp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1010
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1011
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1012
	newdp->dc_hash = dctable[idx];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1013
	dctable[idx] = newdp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1014
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1015
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1016
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1017
 * Remove a dcnode from the hash table.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1018
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1019
void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1020
dcdelete(struct dcnode *deldp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1021
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1022
	int idx = DCHASH(deldp->dc_subvp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1023
	struct dcnode *dp, *prevdp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1024
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1025
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1026
	dp = dctable[idx];
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1027
	if (dp == deldp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1028
		dctable[idx] = dp->dc_hash;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1029
	else {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1030
		for (prevdp = dp, dp = dp->dc_hash; dp != NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1031
		    prevdp = dp, dp = dp->dc_hash) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1032
			if (dp == deldp) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1033
				prevdp->dc_hash = dp->dc_hash;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1034
				break;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1035
			}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1036
		}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1037
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1038
	ASSERT(dp != NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1039
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1040
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1041
/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1042
 * Find a shadow vnode in the dctable hash list.
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1043
 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1044
static struct dcnode *
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1045
dcfind(struct vnode *vp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1046
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1047
	struct dcnode *dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1048
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1049
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1050
	for (dp = dctable[DCHASH(vp)]; dp != NULL; dp = dp->dc_hash)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1051
		if (dp->dc_subvp == vp) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1052
			VN_HOLD(DCTOV(dp));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1053
			if (dp->dc_lrunext)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1054
				dclru_sub(dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1055
			return (dp);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1056
		}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1057
	return (NULL);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1058
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1059
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1060
#ifdef	DEBUG
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1061
static int
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1062
dclru_count(void)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1063
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1064
	struct dcnode *dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1065
	int i = 0;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1066
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1067
	if (dclru == NULL)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1068
		return (0);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1069
	for (dp = dclru; dp->dc_lrunext != dclru; dp = dp->dc_lrunext)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1070
		i++;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1071
	return (i + 1);
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1072
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1073
#endif
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1074
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1075
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1076
dclru_add(struct dcnode *dp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1077
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1078
	/*
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1079
	 * Add to dclru as double-link chain
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1080
	 */
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1081
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1082
	if (dclru == NULL) {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1083
		dclru = dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1084
		dp->dc_lruprev = dp->dc_lrunext = dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1085
	} else {
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1086
		struct dcnode *last = dclru->dc_lruprev;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1087
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1088
		dclru->dc_lruprev = dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1089
		last->dc_lrunext = dp;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1090
		dp->dc_lruprev = last;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1091
		dp->dc_lrunext = dclru;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1092
	}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1093
	dclru_len++;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1094
	ASSERT(dclru_len == dclru_count());
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1095
}
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1096
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1097
static void
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1098
dclru_sub(struct dcnode *dp)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1099
{
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1100
	ASSERT(MUTEX_HELD(&dctable_lock));
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1101
	dp->dc_lrunext->dc_lruprev = dp->dc_lruprev;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1102
	dp->dc_lruprev->dc_lrunext = dp->dc_lrunext;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1103
	if (dp == dclru)
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1104
		dclru = dp->dc_lrunext == dp ? NULL : dp->dc_lrunext;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1105
	dp->dc_lrunext = dp->dc_lruprev = NULL;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1106
	dclru_len--;
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1107
	ASSERT(dclru_len == dclru_count());
161f8007cab9 6521412 PSARC 2006/525: new boot sparc
setje
parents:
diff changeset
  1108
}