usr/src/uts/common/fs/nfs/nfs4_srv.c
author Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
Fri, 10 Apr 2009 22:57:35 -0700
changeset 9348 7155ecb17858
parent 8869 ebed8468e988
child 9871 6f02df7ca581
permissions -rw-r--r--
6760947 NFS/RDMA port should be changed to IANA assigned 20049 6762173 rdma panic on writes from linux client 6790590 readdir fails from Linux client against Solaris server 6790588 linux client fails to decode READ replies from Solaris server 6790586 Solaris server should better handle chunked RPC/RDMA messages 6826476 rpcib leaks memory registrations while handling multiple chunks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
     5
 * Common Development and Distribution License (the "License").
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8372
diff changeset
    22
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
 *	Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
 *	All Rights Reserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/buf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2038
diff changeset
    37
#include <sys/vfs_opreg.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/dirent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/systeminfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/flock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/nbmlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/share.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/fem.h>
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
    55
#include <sys/sdt.h>
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
    56
#include <sys/ddi.h>
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8372
diff changeset
    57
#include <sys/zone.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <rpc/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <rpc/auth.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <rpc/rpcsec_gss.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <rpc/svc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <nfs/nfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <nfs/export.h>
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
    66
#include <nfs/nfs_cmd.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <nfs/lm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <nfs/nfs4.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/strsubr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/strsun.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
#include <inet/common.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#include <inet/ip.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#include <inet/ip6.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
    77
#include <sys/tsol/label.h>
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
    78
#include <sys/tsol/tndb.h>
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
    79
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#define	RFS4_MAXLOCK_TRIES 4	/* Try to get the lock this many times */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
static int rfs4_maxlock_tries = RFS4_MAXLOCK_TRIES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
#define	RFS4_LOCK_DELAY 10	/* Milliseconds */
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
    83
static clock_t  rfs4_lock_delay = RFS4_LOCK_DELAY;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
    84
extern struct svc_ops rdma_svc_ops;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
/* End of Tunables */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
    87
static int rdma_setup_read_data4(READ4args *, READ4res *);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
    88
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * Used to bump the stateid4.seqid value and show changes in the stateid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
#define	next_stateid(sp) (++(sp)->bits.chgseq)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * RFS4_MINLEN_ENTRY4: XDR-encoded size of smallest possible dirent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 *	This is used to return NFS4ERR_TOOSMALL when clients specify
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 *	maxcount that isn't large enough to hold the smallest possible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 *	XDR encoded dirent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 *	    sizeof cookie (8 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 *	    sizeof name_len (4 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 *	    sizeof smallest (padded) name (4 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 *	    sizeof bitmap4_len (12 bytes) +   NOTE: we always encode len=2 bm4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 *	    sizeof attrlist4_len (4 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 *	    sizeof next boolean (4 bytes)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 * RFS4_MINLEN_RDDIR4: XDR-encoded size of READDIR op reply containing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 * the smallest possible entry4 (assumes no attrs requested).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 *	sizeof nfsstat4 (4 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 *	sizeof verifier4 (8 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 *	sizeof entry4list bool (4 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 *	sizeof entry4 	(36 bytes) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 *	sizeof eof bool  (4 bytes)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 * RFS4_MINLEN_RDDIR_BUF: minimum length of buffer server will provide to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *	VOP_READDIR.  Its value is the size of the maximum possible dirent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 *	for solaris.  The DIRENT64_RECLEN macro returns	the size of dirent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 *	required for a given name length.  MAXNAMELEN is the maximum
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 *	filename length allowed in Solaris.  The first two DIRENT64_RECLEN()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 *	macros are to allow for . and .. entries -- just a minor tweak to try
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *	and guarantee that buffer we give to VOP_READDIR will be large enough
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 *	to hold ., .., and the largest possible solaris dirent64.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
#define	RFS4_MINLEN_ENTRY4 36
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
#define	RFS4_MINLEN_RDDIR4 (4 + NFS4_VERIFIER_SIZE + 4 + RFS4_MINLEN_ENTRY4 + 4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
#define	RFS4_MINLEN_RDDIR_BUF \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
	(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2) + DIRENT64_RECLEN(MAXNAMELEN))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 * It would be better to pad to 4 bytes since that's what XDR would do,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 * but the dirents UFS gives us are already padded to 8, so just take
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * what we're given.  Dircount is only a hint anyway.  Currently the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 * solaris kernel is ASCII only, so there's no point in calling the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * UTF8 functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 * dirent64: named padded to provide 8 byte struct alignment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 *	d_ino(8) + d_off(8) + d_reclen(2) + d_name(namelen + null(1) + pad)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 * cookie: uint64_t   +  utf8namelen: uint_t  +   utf8name padded to 8 bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
#define	DIRENT64_TO_DIRCOUNT(dp) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	(3 * BYTES_PER_XDR_UNIT + DIRENT64_NAMELEN((dp)->d_reclen))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
time_t rfs4_start_time;			/* Initialized in rfs4_srvrinit */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
static sysid_t lockt_sysid;		/* dummy sysid for all LOCKT calls */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   149
u_longlong_t	nfs4_srv_caller_id;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   150
uint_t		nfs4_srv_vkey = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
verifier4	Write4verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
verifier4	Readdir4verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   155
void	rfs4_init_compound_state(struct compound_state *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
static void	nullfree(caddr_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
static void	rfs4_op_inval(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
static void	rfs4_op_access(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
static void	rfs4_op_close(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
static void	rfs4_op_commit(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
static void	rfs4_op_create(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
static void	rfs4_op_create_free(nfs_resop4 *resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
static void	rfs4_op_delegreturn(nfs_argop4 *, nfs_resop4 *,
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
   170
			struct svc_req *, struct compound_state *);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
   171
static void	rfs4_op_delegpurge(nfs_argop4 *, nfs_resop4 *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
   172
			struct svc_req *, struct compound_state *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
static void	rfs4_op_getattr(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
static void	rfs4_op_getattr_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
static void	rfs4_op_getfh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
static void	rfs4_op_getfh_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
static void	rfs4_op_illegal(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
static void	rfs4_op_link(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
static void	rfs4_op_lock(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
static void	lock_denied_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
static void	rfs4_op_locku(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
static void	rfs4_op_lockt(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
static void	rfs4_op_lookup(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
static void	rfs4_op_lookupp(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
static void	rfs4_op_openattr(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
				struct svc_req *req, struct compound_state *cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
static void	rfs4_op_nverify(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
static void	rfs4_op_open(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
static void	rfs4_op_open_confirm(nfs_argop4 *, nfs_resop4 *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
			struct svc_req *, struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
static void	rfs4_op_open_downgrade(nfs_argop4 *, nfs_resop4 *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
			struct svc_req *, struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
static void	rfs4_op_putfh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
static void	rfs4_op_putpubfh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
static void	rfs4_op_putrootfh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
static void	rfs4_op_read(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
static void	rfs4_op_read_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
static void	rfs4_op_readdir_free(nfs_resop4 *resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
static void	rfs4_op_readlink(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
static void	rfs4_op_readlink_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
static void	rfs4_op_release_lockowner(nfs_argop4 *, nfs_resop4 *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			struct svc_req *, struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
static void	rfs4_op_remove(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
static void	rfs4_op_rename(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
static void	rfs4_op_renew(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
static void	rfs4_op_restorefh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
static void	rfs4_op_savefh(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
static void	rfs4_op_setattr(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
static void	rfs4_op_verify(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
static void	rfs4_op_write(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
static void	rfs4_op_setclientid(nfs_argop4 *, nfs_resop4 *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
			struct svc_req *, struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
static void	rfs4_op_setclientid_confirm(nfs_argop4 *, nfs_resop4 *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
			struct svc_req *req, struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
static void	rfs4_op_secinfo(nfs_argop4 *, nfs_resop4 *, struct svc_req *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
			struct compound_state *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
static void	rfs4_op_secinfo_free(nfs_resop4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
static nfsstat4 check_open_access(uint32_t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
				struct compound_state *, struct svc_req *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
nfsstat4 rfs4_client_sysid(rfs4_client_t *, sysid_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
static int	vop_shrlock(vnode_t *, int, struct shrlock *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
static int 	rfs4_shrlock(rfs4_state_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
static int	rfs4_share(rfs4_state_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
void rfs4_ss_clid(rfs4_client_t *, struct svc_req *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
 * translation table for attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
struct nfs4_ntov_table {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	union nfs4_attr_u *na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	uint8_t amap[NFS4_MAXNUM_ATTRS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	int attrcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	bool_t vfsstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
static void	nfs4_ntov_table_init(struct nfs4_ntov_table *ntovp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
static void	nfs4_ntov_table_free(struct nfs4_ntov_table *ntovp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
				    struct nfs4_svgetit_arg *sargp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
static nfsstat4	do_rfs4_set_attrs(bitmap4 *resp, fattr4 *fattrp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		    struct compound_state *cs, struct nfs4_svgetit_arg *sargp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		    struct nfs4_ntov_table *ntovp, nfs4_attr_cmd_t cmd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   269
fem_t		*deleg_rdops;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   270
fem_t		*deleg_wrops;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   271
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   272
rfs4_servinst_t *rfs4_cur_servinst = NULL;	/* current server instance */
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   273
kmutex_t	rfs4_servinst_lock;	/* protects linked list */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
int		rfs4_seen_first_compound;	/* set first time we see one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
 * NFS4 op dispatch table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
struct rfsv4disp {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	void	(*dis_proc)();		/* proc to call */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	void	(*dis_resfree)();	/* frees space allocated by proc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	int	dis_flags;		/* RPC_IDEMPOTENT, etc... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
static struct rfsv4disp rfsv4disptab[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	 * NFS VERSION 4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	/* RFS_NULL = 0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	{rfs4_op_illegal, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	/* UNUSED = 1 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	{rfs4_op_illegal, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	/* UNUSED = 2 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	{rfs4_op_illegal, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
	/* OP_ACCESS = 3 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	{rfs4_op_access, nullfree, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	/* OP_CLOSE = 4 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	{rfs4_op_close, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	/* OP_COMMIT = 5 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	{rfs4_op_commit, nullfree, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	/* OP_CREATE = 6 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	{rfs4_op_create, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
	/* OP_DELEGPURGE = 7 */
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
   313
	{rfs4_op_delegpurge, nullfree, 0},
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
	/* OP_DELEGRETURN = 8 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	{rfs4_op_delegreturn, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	/* OP_GETATTR = 9 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	{rfs4_op_getattr, rfs4_op_getattr_free, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	/* OP_GETFH = 10 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	{rfs4_op_getfh, rfs4_op_getfh_free, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	/* OP_LINK = 11 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	{rfs4_op_link, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	/* OP_LOCK = 12 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	{rfs4_op_lock, lock_denied_free, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	/* OP_LOCKT = 13 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	{rfs4_op_lockt, lock_denied_free, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	/* OP_LOCKU = 14 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	{rfs4_op_locku, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	/* OP_LOOKUP = 15 */
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   337
	{rfs4_op_lookup, nullfree, (RPC_IDEMPOTENT | RPC_PUBLICFH_OK)},
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	/* OP_LOOKUPP = 16 */
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   340
	{rfs4_op_lookupp, nullfree, (RPC_IDEMPOTENT | RPC_PUBLICFH_OK)},
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	/* OP_NVERIFY = 17 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	{rfs4_op_nverify, nullfree, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	/* OP_OPEN = 18 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	{rfs4_op_open, rfs4_free_reply, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	/* OP_OPENATTR = 19 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
	{rfs4_op_openattr, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	/* OP_OPEN_CONFIRM = 20 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	{rfs4_op_open_confirm, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	/* OP_OPEN_DOWNGRADE = 21 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	{rfs4_op_open_downgrade, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	/* OP_OPEN_PUTFH = 22 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	{rfs4_op_putfh, nullfree, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	/* OP_PUTPUBFH = 23 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
	{rfs4_op_putpubfh, nullfree, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	/* OP_PUTROOTFH = 24 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	{rfs4_op_putrootfh, nullfree, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	/* OP_READ = 25 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	{rfs4_op_read, rfs4_op_read_free, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	/* OP_READDIR = 26 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
	{rfs4_op_readdir, rfs4_op_readdir_free, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	/* OP_READLINK = 27 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	{rfs4_op_readlink, rfs4_op_readlink_free, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	/* OP_REMOVE = 28 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
	{rfs4_op_remove, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	/* OP_RENAME = 29 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	{rfs4_op_rename, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
	/* OP_RENEW = 30 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	{rfs4_op_renew, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	/* OP_RESTOREFH = 31 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	{rfs4_op_restorefh, nullfree, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	/* OP_SAVEFH = 32 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	{rfs4_op_savefh, nullfree, RPC_ALL},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	/* OP_SECINFO = 33 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	{rfs4_op_secinfo, rfs4_op_secinfo_free, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	/* OP_SETATTR = 34 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	{rfs4_op_setattr, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	/* OP_SETCLIENTID = 35 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	{rfs4_op_setclientid, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	/* OP_SETCLIENTID_CONFIRM = 36 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	{rfs4_op_setclientid_confirm, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	/* OP_VERIFY = 37 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	{rfs4_op_verify, nullfree, RPC_IDEMPOTENT},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	/* OP_WRITE = 38 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
	{rfs4_op_write, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	/* OP_RELEASE_LOCKOWNER = 39 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	{rfs4_op_release_lockowner, nullfree, 0},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
static uint_t rfsv4disp_cnt = sizeof (rfsv4disptab) / sizeof (rfsv4disptab[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
#define	OP_ILLEGAL_IDX (rfsv4disp_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   418
int		rfs4_fillone_debug = 0;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   419
int		rfs4_shrlock_debug = 0;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   420
int		rfs4_no_stub_access = 1;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   421
int		rfs4_rddir_debug = 0;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   422
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   423
static char    *rfs4_op_string[] = {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	"rfs4_op_null",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	"rfs4_op_1 unused",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	"rfs4_op_2 unused",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	"rfs4_op_access",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	"rfs4_op_close",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	"rfs4_op_commit",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	"rfs4_op_create",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	"rfs4_op_delegpurge",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	"rfs4_op_delegreturn",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	"rfs4_op_getattr",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	"rfs4_op_getfh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	"rfs4_op_link",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	"rfs4_op_lock",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	"rfs4_op_lockt",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	"rfs4_op_locku",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	"rfs4_op_lookup",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	"rfs4_op_lookupp",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	"rfs4_op_nverify",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	"rfs4_op_open",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	"rfs4_op_openattr",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	"rfs4_op_open_confirm",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	"rfs4_op_open_downgrade",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	"rfs4_op_putfh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	"rfs4_op_putpubfh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	"rfs4_op_putrootfh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	"rfs4_op_read",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	"rfs4_op_readdir",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
	"rfs4_op_readlink",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	"rfs4_op_remove",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	"rfs4_op_rename",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	"rfs4_op_renew",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	"rfs4_op_restorefh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	"rfs4_op_savefh",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	"rfs4_op_secinfo",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	"rfs4_op_setattr",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
	"rfs4_op_setclientid",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	"rfs4_op_setclient_confirm",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	"rfs4_op_verify",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	"rfs4_op_write",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	"rfs4_op_release_lockowner",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	"rfs4_op_illegal"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   468
void	rfs4_ss_chkclid(rfs4_client_t *);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   469
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
   470
extern size_t   strlcpy(char *dst, const char *src, size_t dstsize);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   471
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
#ifdef	nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
#undef nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
#define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
static const fs_operation_def_t nfs4_rd_deleg_tmpl[] = {
5599
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   478
	VOPNAME_OPEN,		{ .femop_open = deleg_rd_open },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   479
	VOPNAME_WRITE,		{ .femop_write = deleg_rd_write },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   480
	VOPNAME_SETATTR,	{ .femop_setattr = deleg_rd_setattr },
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2038
diff changeset
   481
	VOPNAME_RWLOCK,		{ .femop_rwlock = deleg_rd_rwlock },
5599
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   482
	VOPNAME_SPACE,		{ .femop_space = deleg_rd_space },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   483
	VOPNAME_SETSECATTR,	{ .femop_setsecattr = deleg_rd_setsecattr },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   484
	VOPNAME_VNEVENT,	{ .femop_vnevent = deleg_rd_vnevent },
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2038
diff changeset
   485
	NULL,			NULL
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
static const fs_operation_def_t nfs4_wr_deleg_tmpl[] = {
5599
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   488
	VOPNAME_OPEN,		{ .femop_open = deleg_wr_open },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   489
	VOPNAME_READ,		{ .femop_read = deleg_wr_read },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   490
	VOPNAME_WRITE,		{ .femop_write = deleg_wr_write },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   491
	VOPNAME_SETATTR,	{ .femop_setattr = deleg_wr_setattr },
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2038
diff changeset
   492
	VOPNAME_RWLOCK,		{ .femop_rwlock = deleg_wr_rwlock },
5599
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   493
	VOPNAME_SPACE,		{ .femop_space = deleg_wr_space },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   494
	VOPNAME_SETSECATTR,	{ .femop_setsecattr = deleg_wr_setsecattr },
e83e6e5aa9d3 PSARC 2007/632 Caller context flags
jwahlig
parents: 5331
diff changeset
   495
	VOPNAME_VNEVENT,	{ .femop_vnevent = deleg_wr_vnevent },
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2038
diff changeset
   496
	NULL,			NULL
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
rfs4_srvrinit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	timespec32_t verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	extern void rfs4_attr_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	extern krwlock_t rfs4_deleg_policy_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	 * The following algorithm attempts to find a unique verifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	 * to be used as the write verifier returned from the server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	 * to the client.  It is important that this verifier change
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	 * whenever the server reboots.  Of secondary importance, it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	 * is important for the verifier to be unique between two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	 * different servers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
	 * Thus, an attempt is made to use the system hostid and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	 * current time in seconds when the nfssrv kernel module is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	 * loaded.  It is assumed that an NFS server will not be able
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	 * to boot and then to reboot in less than a second.  If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	 * hostid has not been set, then the current high resolution
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	 * time is used.  This will ensure different verifiers each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	 * time the server reboots and minimize the chances that two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	 * different servers will have the same verifier.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	 * XXX - this is broken on LP64 kernels.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	 */
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8372
diff changeset
   525
	verf.tv_sec = (time_t)zone_get_hostid(NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
	if (verf.tv_sec != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
		verf.tv_nsec = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
		timespec_t tverf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
		gethrestime(&tverf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		verf.tv_sec = (time_t)tverf.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
		verf.tv_nsec = tverf.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	Write4verf = *(uint64_t *)&verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	rfs4_attr_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	mutex_init(&rfs4_deleg_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	/* Used to manage create/destroy of server state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
	mutex_init(&rfs4_state_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
	/* Used to manage access to server instance linked list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
	mutex_init(&rfs4_servinst_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
	/* Used to manage access to rfs4_deleg_policy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
	rw_init(&rfs4_deleg_policy_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	error = fem_create("deleg_rdops", nfs4_rd_deleg_tmpl, &deleg_rdops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		rfs4_disable_delegation();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		error = fem_create("deleg_wrops", nfs4_wr_deleg_tmpl,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
   555
		    &deleg_wrops);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
			rfs4_disable_delegation();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
			fem_free(deleg_rdops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
	nfs4_srv_caller_id = fs_new_caller_id();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	lockt_sysid = lm_alloc_sysidt();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
   566
	vsd_create(&nfs4_srv_vkey, NULL);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
   567
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
rfs4_srvrfini(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	extern krwlock_t rfs4_deleg_policy_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	if (lockt_sysid != LM_NOSYSID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		lm_free_sysidt(lockt_sysid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
		lockt_sysid = LM_NOSYSID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
	mutex_destroy(&rfs4_deleg_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
	mutex_destroy(&rfs4_state_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
	rw_destroy(&rfs4_deleg_policy_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
	fem_free(deleg_rdops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	fem_free(deleg_wrops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
rfs4_init_compound_state(struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	bzero(cs, sizeof (*cs));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	cs->cont = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	cs->access = CS_ACCESS_DENIED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	cs->deleg = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	cs->mandlock = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	cs->fh.nfs_fh4_val = cs->fhbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
rfs4_grace_start(rfs4_servinst_t *sip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	rw_enter(&sip->rwlock, RW_WRITER);
8372
b77972214846 6372445 NFSv4 grace period code uses gethrestime_sec() where lbolt would be better.
Dai Ngo <dai.ngo@sun.com>
parents: 7961
diff changeset
   604
	sip->start_time = (time_t)TICK_TO_SEC(lbolt);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	sip->grace_period = rfs4_grace_period;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	rw_exit(&sip->rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
 * returns true if the instance's grace period has never been started
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
rfs4_servinst_grace_new(rfs4_servinst_t *sip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	time_t start_time;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	rw_enter(&sip->rwlock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	start_time = sip->start_time;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	rw_exit(&sip->rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	return (start_time == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
 * Indicates if server instance is within the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
 * grace period.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
rfs4_servinst_in_grace(rfs4_servinst_t *sip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	time_t grace_expiry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	rw_enter(&sip->rwlock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
	grace_expiry = sip->start_time + sip->grace_period;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
	rw_exit(&sip->rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
8372
b77972214846 6372445 NFSv4 grace period code uses gethrestime_sec() where lbolt would be better.
Dai Ngo <dai.ngo@sun.com>
parents: 7961
diff changeset
   637
	return (((time_t)TICK_TO_SEC(lbolt)) < grace_expiry);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
rfs4_clnt_in_grace(rfs4_client_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	ASSERT(rfs4_dbe_refcnt(cp->dbe) > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	return (rfs4_servinst_in_grace(cp->server_instance));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
 * reset all currently active grace periods
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
rfs4_grace_reset_all(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	rfs4_servinst_t *sip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	mutex_enter(&rfs4_servinst_lock);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   657
	for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev)
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   658
		if (rfs4_servinst_in_grace(sip))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			rfs4_grace_start(sip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
	mutex_exit(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
 * start any new instances' grace periods
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
rfs4_grace_start_new(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	rfs4_servinst_t *sip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	mutex_enter(&rfs4_servinst_lock);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   672
	for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		if (rfs4_servinst_grace_new(sip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
			rfs4_grace_start(sip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	mutex_exit(&rfs4_servinst_lock);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   676
}
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   677
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   678
static rfs4_dss_path_t *
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   679
rfs4_dss_newpath(rfs4_servinst_t *sip, char *path, unsigned index)
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   680
{
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   681
	size_t len;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   682
	rfs4_dss_path_t *dss_path;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   683
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   684
	dss_path = kmem_alloc(sizeof (rfs4_dss_path_t), KM_SLEEP);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   685
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   686
	/*
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   687
	 * Take a copy of the string, since the original may be overwritten.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   688
	 * Sadly, no strdup() in the kernel.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   689
	 */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   690
	/* allow for NUL */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   691
	len = strlen(path) + 1;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   692
	dss_path->path = kmem_alloc(len, KM_SLEEP);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   693
	(void) strlcpy(dss_path->path, path, len);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   694
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   695
	/* associate with servinst */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   696
	dss_path->sip = sip;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   697
	dss_path->index = index;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   698
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   699
	/*
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   700
	 * Add to list of served paths.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   701
	 * No locking required, as we're only ever called at startup.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   702
	 */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   703
	if (rfs4_dss_pathlist == NULL) {
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   704
		/* this is the first dss_path_t */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   705
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   706
		/* needed for insque/remque */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   707
		dss_path->next = dss_path->prev = dss_path;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   708
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   709
		rfs4_dss_pathlist = dss_path;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   710
	} else {
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   711
		insque(dss_path, rfs4_dss_pathlist);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   712
	}
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   713
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   714
	return (dss_path);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
 * Create a new server instance, and make it the currently active instance.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
 * Note that starting the grace period too early will reduce the clients'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
 * recovery window.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
void
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   723
rfs4_servinst_create(int start_grace, int dss_npaths, char **dss_paths)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
{
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   725
	unsigned i;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	rfs4_servinst_t *sip;
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   727
	rfs4_oldstate_t *oldstate;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	sip = kmem_alloc(sizeof (rfs4_servinst_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
	rw_init(&sip->rwlock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	sip->start_time = (time_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
	sip->grace_period = (time_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	sip->next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
	sip->prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   737
	rw_init(&sip->oldstate_lock, NULL, RW_DEFAULT, NULL);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   738
	/*
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   739
	 * This initial dummy entry is required to setup for insque/remque.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   740
	 * It must be skipped over whenever the list is traversed.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   741
	 */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   742
	oldstate = kmem_alloc(sizeof (rfs4_oldstate_t), KM_SLEEP);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   743
	/* insque/remque require initial list entry to be self-terminated */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   744
	oldstate->next = oldstate;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   745
	oldstate->prev = oldstate;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   746
	sip->oldstate = oldstate;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   747
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   748
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   749
	sip->dss_npaths = dss_npaths;
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   750
	sip->dss_paths = kmem_alloc(dss_npaths *
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   751
	    sizeof (rfs4_dss_path_t *), KM_SLEEP);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   752
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   753
	for (i = 0; i < dss_npaths; i++) {
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   754
		sip->dss_paths[i] = rfs4_dss_newpath(sip, dss_paths[i], i);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   755
	}
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   756
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	mutex_enter(&rfs4_servinst_lock);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   758
	if (rfs4_cur_servinst != NULL) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		/* add to linked list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
		sip->prev = rfs4_cur_servinst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
		rfs4_cur_servinst->next = sip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	if (start_grace)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
		rfs4_grace_start(sip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	/* make the new instance "current" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	rfs4_cur_servinst = sip;
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   767
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	mutex_exit(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
 * In future, we might add a rfs4_servinst_destroy(sip) but, for now, destroy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
 * all instances directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
rfs4_servinst_destroy_all(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	rfs4_servinst_t *sip, *prev, *current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	int n = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	mutex_enter(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	ASSERT(rfs4_cur_servinst != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	current = rfs4_cur_servinst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	rfs4_cur_servinst = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
	for (sip = current; sip != NULL; sip = prev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
		prev = sip->prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
		rw_destroy(&sip->rwlock);
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   790
		if (sip->oldstate)
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   791
			kmem_free(sip->oldstate, sizeof (rfs4_oldstate_t));
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   792
		if (sip->dss_paths)
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   793
			kmem_free(sip->dss_paths,
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
   794
			    sip->dss_npaths * sizeof (rfs4_dss_path_t *));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		kmem_free(sip, sizeof (rfs4_servinst_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
		n++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
	mutex_exit(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
 * Assign the current server instance to a client_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
 * Should be called with cp->dbe held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
rfs4_servinst_assign(rfs4_client_t *cp, rfs4_servinst_t *sip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	ASSERT(rfs4_dbe_refcnt(cp->dbe) > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	 * The lock ensures that if the current instance is in the process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
	 * of changing, we will see the new one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	mutex_enter(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
	cp->server_instance = sip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	mutex_exit(&rfs4_servinst_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
rfs4_servinst_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
rfs4_servinst(rfs4_client_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	ASSERT(rfs4_dbe_refcnt(cp->dbe) > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	return (cp->server_instance);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
nullfree(caddr_t resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
 * This is a fall-through for invalid or not implemented (yet) ops
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
rfs4_op_inval(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	*cs->statusp = *((nfsstat4 *)&(resop)->nfs_resop4_u) = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
 * Check if the security flavor, nfsnum, is in the flavor_list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
in_flavor_list(int nfsnum, int *flavor_list, int count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
		if (nfsnum == flavor_list[i])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
			return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
 * Used by rfs4_op_secinfo to get the security information from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
 * export structure associated with the component.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
do_rfs4_op_secinfo(struct compound_state *cs, char *nm, SECINFO4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	int error, different_export = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	vnode_t *dvp, *vp, *tvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	struct exportinfo *exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	uint_t count, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	secinfo4 *resok_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	struct secinfo *secp;
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
   876
	seconfig_t *si;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	bool_t did_traverse;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	int dotdot, walk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	dotdot = (nm[0] == '.' && nm[1] == '.' && nm[2] == '\0');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
	 * If dotdotting, then need to check whether it's above the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	 * root of a filesystem, or above an export point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	if (dotdot) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		 * If dotdotting at the root of a filesystem, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
		 * need to traverse back to the mounted-on filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		 * and do the dotdot lookup there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
		if (cs->vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
			 * If at the system root, then can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
			 * go up no further.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
			if (VN_CMP(dvp, rootdir))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
				return (puterrno4(ENOENT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
			 * Traverse back to the mounted-on filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
			dvp = untraverse(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
			 * Set the different_export flag so we remember
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
			 * to pick up a new exportinfo entry for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
			 * this new filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
			different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
			 * If dotdotting above an export point then set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
			 * the different_export to get new export info.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
			different_export = nfs_exported(cs->exi, cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	 * Get the vnode for the component "nm".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
   927
	error = VOP_LOOKUP(dvp, nm, &vp, NULL, 0, NULL, cs->cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
   928
	    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
	 * If the vnode is in a pseudo filesystem, or if the security flavor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
	 * used in the request is valid but not an explicitly shared flavor,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	 * or the access bit indicates that this is a limited access,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	 * check whether this vnode is visible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
	if (!different_export &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	    (PSEUDO(cs->exi) || ! is_exported_sec(cs->nfsflavor, cs->exi) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
	    cs->access & CS_ACCESS_LIMITED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
		if (! nfs_visible(cs->exi, vp, &different_export)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
			return (puterrno4(ENOENT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	 * If it's a mountpoint, then traverse it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	if (vn_ismntpt(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
		tvp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
		if ((error = traverse(&tvp)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
			return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
		/* remember that we had to traverse mountpoint */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
		did_traverse = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		vp = tvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
		different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
	} else if (vp->v_vfsp != dvp->v_vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
		 * If vp isn't a mountpoint and the vfs ptrs aren't the same,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
		 * then vp is probably an LOFS object.  We don't need the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		 * realvp, we just need to know that we might have crossed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
		 * a server fs boundary and need to call checkexport4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
		 * (LOFS lookup hides server fs mountpoints, and actually calls
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
		 * traverse)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
		different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
		did_traverse = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
	 * Get the export information for it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	if (different_export) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
			return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
		if (dotdot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
			exi = nfs_vptoexi(NULL, vp, cs->cr, &walk, NULL, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
		if (exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
			if (did_traverse == TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
				 * If this vnode is a mounted-on vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
				 * but the mounted-on file system is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
				 * exported, send back the secinfo for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
				 * the exported node that the mounted-on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
				 * vnode lives in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
				exi = cs->exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
				VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
				return (puterrno4(EACCES));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
		exi = cs->exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	ASSERT(exi != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
	 * Create the secinfo result based on the security information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
	 * from the exportinfo structure (exi).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
	 * Return all flavors for a pseudo node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
	 * For a real export node, return the flavor that the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
	 * has access with.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
	ASSERT(RW_LOCK_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
	if (PSEUDO(exi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
		count = exi->exi_export.ex_seccnt; /* total sec count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
		resok_val = kmem_alloc(count * sizeof (secinfo4), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
		secp = exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
		for (i = 0; i < count; i++) {
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1027
			si = &secp[i].s_secinfo;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1028
			resok_val[i].flavor = si->sc_rpcnum;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1029
			if (resok_val[i].flavor == RPCSEC_GSS) {
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1030
				rpcsec_gss_info *info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1031
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1032
				info = &resok_val[i].flavor_info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1033
				info->qop = si->sc_qop;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1034
				info->service = (rpc_gss_svc_t)si->sc_service;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1035
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1036
				/* get oid opaque data */
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1037
				info->oid.sec_oid4_len =
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1038
				    si->sc_gss_mech_type->length;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1039
				info->oid.sec_oid4_val = kmem_alloc(
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1040
				    si->sc_gss_mech_type->length, KM_SLEEP);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1041
				bcopy(
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1042
				    si->sc_gss_mech_type->elements,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1043
				    info->oid.sec_oid4_val,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1044
				    info->oid.sec_oid4_len);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1045
			}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		resp->SECINFO4resok_len = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
		resp->SECINFO4resok_val = resok_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
		int ret_cnt = 0, k = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
		int *flavor_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
		count = exi->exi_export.ex_seccnt; /* total sec count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
		secp = exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
		flavor_list = kmem_alloc(count * sizeof (int), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
		/* find out which flavors to return */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
		for (i = 0; i < count; i ++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
			int access, flavor, perm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
			flavor = secp[i].s_secinfo.sc_nfsnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
			perm = secp[i].s_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
			access = nfsauth4_secinfo_access(exi, cs->req,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1065
			    flavor, perm);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
			if (! (access & NFSAUTH_DENIED) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
			    ! (access & NFSAUTH_WRONGSEC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
				flavor_list[ret_cnt] = flavor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
				ret_cnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
		/* Create the returning SECINFO value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
		resok_val = kmem_alloc(ret_cnt * sizeof (secinfo4), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		for (i = 0; i < count; i++) {
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1078
			/*
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1079
			 * If the flavor is in the flavor list,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1080
			 * fill in resok_val.
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1081
			 */
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1082
			si = &secp[i].s_secinfo;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1083
			if (in_flavor_list(si->sc_nfsnum,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1084
			    flavor_list, ret_cnt)) {
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1085
				resok_val[k].flavor = si->sc_rpcnum;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1086
				if (resok_val[k].flavor == RPCSEC_GSS) {
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1087
					rpcsec_gss_info *info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1088
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1089
					info = &resok_val[k].flavor_info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1090
					info->qop = si->sc_qop;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1091
					info->service = (rpc_gss_svc_t)
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1092
					    si->sc_service;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1093
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1094
					/* get oid opaque data */
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1095
					info->oid.sec_oid4_len =
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1096
					    si->sc_gss_mech_type->length;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1097
					info->oid.sec_oid4_val = kmem_alloc(
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1098
					    si->sc_gss_mech_type->length,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1099
					    KM_SLEEP);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1100
					bcopy(si->sc_gss_mech_type->elements,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1101
					    info->oid.sec_oid4_val,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1102
					    info->oid.sec_oid4_len);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1103
				}
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1104
				k++;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
			}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1106
			if (k >= ret_cnt)
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1107
				break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
		resp->SECINFO4resok_len = ret_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
		resp->SECINFO4resok_val = resok_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
		kmem_free(flavor_list, count * sizeof (int));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
	return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
 * SECINFO (Operation 33): Obtain required security information on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
 * the component name in the format of (security-mechanism-oid, qop, service)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
 * triplets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
rfs4_op_secinfo(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
{
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1128
	SECINFO4args *args = &argop->nfs_argop4_u.opsecinfo;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	SECINFO4res *resp = &resop->nfs_resop4_u.opsecinfo;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1130
	utf8string *utfnm = &args->name;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	uint_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	char *nm;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1133
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1134
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1136
	DTRACE_NFSV4_2(op__secinfo__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1137
	    SECINFO4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1138
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	 * Current file handle (cfh) should have been set before getting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
	 * into this function. If not, return error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1145
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	if (cs->vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1150
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
	 * Verify the component name. If failed, error out, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
	 * do not error out if the component name is a "..".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	 * SECINFO will return its parents secinfo data for SECINFO "..".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	if (!utf8_dir_verify(utfnm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
		if (utfnm->utf8string_len != 2 ||
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1160
		    utfnm->utf8string_val[0] != '.' ||
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1161
		    utfnm->utf8string_val[1] != '.') {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
			*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1163
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	nm = utf8_to_str(utfnm, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1170
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1176
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
	}
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1178
	/* If necessary, convert to UTF-8 for illbehaved clients */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1179
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1180
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1181
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1182
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1183
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1184
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1185
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1186
		kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1187
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1188
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1189
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1190
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1191
	*cs->statusp = resp->status = do_rfs4_op_secinfo(cs, name, resp);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1192
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1193
	if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1194
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
	kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1196
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1197
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1198
	DTRACE_NFSV4_2(op__secinfo__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1199
	    SECINFO4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
 * Free SECINFO result.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
rfs4_op_secinfo_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	SECINFO4res *resp = &resop->nfs_resop4_u.opsecinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	int count, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	secinfo4 *resok_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	/* If this is not an Ok result, nothing to free. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	count = resp->SECINFO4resok_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	resok_val = resp->SECINFO4resok_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	for (i = 0; i < count; i++) {
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1222
		if (resok_val[i].flavor == RPCSEC_GSS) {
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1223
			rpcsec_gss_info *info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1224
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1225
			info = &resok_val[i].flavor_info;
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1226
			kmem_free(info->oid.sec_oid4_val,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1227
			    info->oid.sec_oid4_len);
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1228
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	kmem_free(resok_val, count * sizeof (secinfo4));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	resp->SECINFO4resok_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
	resp->SECINFO4resok_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
rfs4_op_access(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
	ACCESS4args *args = &argop->nfs_argop4_u.opaccess;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
	ACCESS4res *resp = &resop->nfs_resop4_u.opaccess;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
	int checkwriteperm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
	cred_t *cr = cs->cr;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1247
	bslabel_t *clabel, *slabel;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1248
	ts_label_t *tslabel;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1249
	boolean_t admin_low_client;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1251
	DTRACE_NFSV4_2(op__access__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1252
	    ACCESS4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1253
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
#if 0	/* XXX allow access even if !cs->access. Eventually only pseudo fs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1257
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1262
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	ASSERT(cr != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
	vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
	 * If the file system is exported read only, it is not appropriate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	 * to check write permissions for regular files and directories.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	 * Special files are interpreted by the client, so the underlying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	 * permissions are sent back to the client for interpretation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	if (rdonly4(cs->exi, cs->vp, req) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1276
	    (vp->v_type == VREG || vp->v_type == VDIR))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		checkwriteperm = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
		checkwriteperm = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	 * XXX
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	 * We need the mode so that we can correctly determine access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	 * permissions relative to a mandatory lock file.  Access to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	 * mandatory lock files is denied on the server, so it might
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	 * as well be reflected to the server during the open.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	va.va_mask = AT_MODE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1289
	error = VOP_GETATTR(vp, &va, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1292
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	resp->access = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	resp->supported = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1297
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1298
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1299
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1300
		DTRACE_PROBE2(tx__rfs4__log__info__opaccess__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1301
		    "got client label from request(1)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1302
		    struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1303
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  1304
			if ((tslabel = nfs_getflabel(vp)) == NULL) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1305
				*cs->statusp = resp->status = puterrno4(EACCES);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1306
				goto out;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1307
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1308
			slabel = label2bslabel(tslabel);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1309
			DTRACE_PROBE3(tx__rfs4__log__info__opaccess__slabel,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1310
			    char *, "got server label(1) for vp(2)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1311
			    bslabel_t *, slabel, vnode_t *, vp);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1312
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1313
			admin_low_client = B_FALSE;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1314
		} else
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1315
			admin_low_client = B_TRUE;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1316
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1317
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	if (args->access & ACCESS4_READ) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1319
		error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1320
		if (!error && !MANDLOCK(vp, va.va_mode) &&
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1321
		    (!is_system_labeled() || admin_low_client ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1322
		    bldominates(clabel, slabel)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
			resp->access |= ACCESS4_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
		resp->supported |= ACCESS4_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	if ((args->access & ACCESS4_LOOKUP) && vp->v_type == VDIR) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1327
		error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1328
		if (!error && (!is_system_labeled() || admin_low_client ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1329
		    bldominates(clabel, slabel)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
			resp->access |= ACCESS4_LOOKUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
		resp->supported |= ACCESS4_LOOKUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
	if (checkwriteperm &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	    (args->access & (ACCESS4_MODIFY|ACCESS4_EXTEND))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1335
		error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1336
		if (!error && !MANDLOCK(vp, va.va_mode) &&
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1337
		    (!is_system_labeled() || admin_low_client ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1338
		    blequal(clabel, slabel)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
			resp->access |=
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  1340
			    (args->access & (ACCESS4_MODIFY | ACCESS4_EXTEND));
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  1341
		resp->supported |= (ACCESS4_MODIFY | ACCESS4_EXTEND);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	if (checkwriteperm &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	    (args->access & ACCESS4_DELETE) && vp->v_type == VDIR) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1346
		error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1347
		if (!error && (!is_system_labeled() || admin_low_client ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1348
		    blequal(clabel, slabel)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
			resp->access |= ACCESS4_DELETE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		resp->supported |= ACCESS4_DELETE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	if (args->access & ACCESS4_EXECUTE && vp->v_type != VDIR) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1353
		error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1354
		if (!error && !MANDLOCK(vp, va.va_mode) &&
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1355
		    (!is_system_labeled() || admin_low_client ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1356
		    bldominates(clabel, slabel)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
			resp->access |= ACCESS4_EXECUTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
		resp->supported |= ACCESS4_EXECUTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1361
	if (is_system_labeled() && !admin_low_client)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1362
		label_rele(tslabel);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  1363
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1365
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1366
	DTRACE_NFSV4_2(op__access__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1367
	    ACCESS4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
rfs4_op_commit(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	COMMIT4args *args = &argop->nfs_argop4_u.opcommit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	COMMIT4res *resp = &resop->nfs_resop4_u.opcommit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
	vnode_t *vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	cred_t *cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	vattr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1382
	DTRACE_NFSV4_2(op__commit__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1383
	    COMMIT4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1384
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1387
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1391
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
	if (args->offset + args->count < args->offset) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1396
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
	va.va_mask = AT_UID;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1400
	error = VOP_GETATTR(vp, &va, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1408
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		*cs->statusp = resp->status = NFS4ERR_ROFS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1412
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
		if (vp->v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
			resp->status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
			resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		*cs->statusp = resp->status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1421
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	if (crgetuid(cr) != va.va_uid &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1425
	    (error = VOP_ACCESS(vp, VWRITE, 0, cs->cr, NULL))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1427
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1430
	error = VOP_PUTPAGE(vp, args->offset, args->count, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
	if (!error)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1432
		error = VOP_FSYNC(vp, FNODSYNC, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1436
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
	resp->writeverf = Write4verf;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1441
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1442
	DTRACE_NFSV4_2(op__commit__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1443
	    COMMIT4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
 * rfs4_op_mknod is called from rfs4_op_create after all initial verification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
 * was completed. It does the nfsv4 create for special files.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
static vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
do_rfs4_op_mknod(CREATE4args *args, CREATE4res *resp, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
	struct compound_state *cs, vattr_t *vap, char *nm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
	cred_t *cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	vnode_t *dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	vnode_t *vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	int mode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	enum vcexcl excl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
	switch (args->type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	case NF4CHR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	case NF4BLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
		if (secpolicy_sys_devices(cr) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
			*cs->statusp = resp->status = NFS4ERR_PERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
		if (args->type == NF4CHR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
			vap->va_type = VCHR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
			vap->va_type = VBLK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
		vap->va_rdev = makedevice(args->ftype4_u.devdata.specdata1,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1474
		    args->ftype4_u.devdata.specdata2);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
		vap->va_mask |= AT_RDEV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	case NF4SOCK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
		vap->va_type = VSOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
	case NF4FIFO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
		vap->va_type = VFIFO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
		*cs->statusp = resp->status = NFS4ERR_BADTYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	 * Must specify the mode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	if (!(vap->va_mask & AT_MODE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		*cs->statusp = resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
	excl = EXCL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
	mode = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1500
	error = VOP_CREATE(dvp, nm, vap, excl, mode, &vp, cr, 0, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
 * nfsv4 create is used to create non-regular files. For regular files,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
 * use nfsv4 open.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
rfs4_op_create(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	CREATE4args *args = &argop->nfs_argop4_u.opcreate;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	CREATE4res *resp = &resop->nfs_resop4_u.opcreate;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
	struct vattr bva, iva, iva2, ava, *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
	cred_t *cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	vnode_t *dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	vnode_t *vp = NULL;
6402
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1524
	vnode_t *realvp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	char *nm, *lnm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	uint_t len, llen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	int syncval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	nfsstat4 status;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1532
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1533
	char *name = NULL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1534
	char *lname = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1536
	DTRACE_NFSV4_2(op__create__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1537
	    CREATE4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1538
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	resp->attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1543
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
	 * do not allow to create an object in this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
	if (vn_ismntpt(dvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1552
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	/* Verify that type is correct */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	switch (args->type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
	case NF4LNK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
	case NF4BLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
	case NF4CHR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
	case NF4SOCK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
	case NF4FIFO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
	case NF4DIR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
		*cs->statusp = resp->status = NFS4ERR_BADTYPE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1566
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1571
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
	if (dvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1575
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	if (!utf8_dir_verify(&args->objname)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1579
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
		*cs->statusp = resp->status = NFS4ERR_ROFS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1584
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
	 * Name of newly created object
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
	nm = utf8_to_fn(&args->objname, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1593
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1599
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1602
	/* If necessary, convert to UTF-8 for poorly behaved clients */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1603
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1604
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1605
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1606
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1607
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1608
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1609
		kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1610
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1611
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1612
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	resp->attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
	nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	status = do_rfs4_set_attrs(&resp->attrset,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1619
	    &args->createattrs, cs, &sarg, &ntov, NFS4ATTR_SETIT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	if (sarg.vap->va_mask == 0 && status == NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
		status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
		*cs->statusp = resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
		kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
		nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
		resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1629
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	/* Get "before" change value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	bva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1634
	error = VOP_GETATTR(dvp, &bva, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
		kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
		nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
		resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1640
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.before, bva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	vap = sarg.vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	 * Set default initial values for attributes when not specified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
	 * in createattrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	if ((vap->va_mask & AT_UID) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
		vap->va_uid = crgetuid(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
		vap->va_mask |= AT_UID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
	if ((vap->va_mask & AT_GID) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
		vap->va_gid = crgetgid(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
		vap->va_mask |= AT_GID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	vap->va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
	switch (args->type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
	case NF4DIR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
		vap->va_type = VDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
		if ((vap->va_mask & AT_MODE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
			vap->va_mode = 0700;	/* default: owner rwx only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
			vap->va_mask |= AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1667
		error = VOP_MKDIR(dvp, nm, vap, &vp, cr, NULL, 0, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
		 * Get the initial "after" sequence number, if it fails,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
		 * set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
		iva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1676
		if (VOP_GETATTR(dvp, &iva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
			iva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
	case NF4LNK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
		vap->va_type = VLNK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
		if ((vap->va_mask & AT_MODE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
			vap->va_mode = 0700;	/* default: owner rwx only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
			vap->va_mask |= AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
		 * symlink names must be treated as data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
		lnm = utf8_to_str(&args->ftype4_u.linkdata, &llen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
		if (lnm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
			*cs->statusp = resp->status = NFS4ERR_INVAL;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1693
			if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1694
				kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
			kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
			nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
			resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1698
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
		if (llen > MAXPATHLEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
			*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1703
			if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1704
				kmem_free(name, MAXPATHLEN + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1705
			kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1706
			kmem_free(lnm, llen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1707
			nfs4_ntov_table_free(&ntov, &sarg);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1708
			resp->attrset = 0;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1709
			goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1710
		}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1711
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1712
		lname = nfscmd_convname(ca, cs->exi, lnm,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1713
		    NFSCMD_CONV_INBOUND, MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1714
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1715
		if (lname == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1716
			*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1717
			if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1718
				kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
			kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
			kmem_free(lnm, llen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
			nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
			resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1723
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1726
		error = VOP_SYMLINK(dvp, nm, vap, lnm, cr, NULL, 0);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1727
		if (lname != lnm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1728
			kmem_free(lname, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
		if (lnm != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
			kmem_free(lnm, llen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
		 * Get the initial "after" sequence number, if it fails,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
		 * set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
		iva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1739
		if (VOP_GETATTR(dvp, &iva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
			iva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1742
		error = VOP_LOOKUP(dvp, nm, &vp, NULL, 0, NULL, cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1743
		    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
		 * va_seq is not safe over VOP calls, check it again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
		 * if it has changed zero out iva to force atomic = FALSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
		iva2.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1752
		if (VOP_GETATTR(dvp, &iva2, 0, cs->cr, NULL) ||
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1753
		    iva2.va_seq != iva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
			iva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
		 * probably a special file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
		if ((vap->va_mask & AT_MODE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
			vap->va_mode = 0600;	/* default: owner rw only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
			vap->va_mask |= AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
		syncval = FNODSYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
		 * We know this will only generate one VOP call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
		vp = do_rfs4_op_mknod(args, resp, req, cs, vap, nm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
		if (vp == NULL) {
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1771
			if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1772
				kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
			kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
			nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
			resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1776
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
		 * Get the initial "after" sequence number, if it fails,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
		 * set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
		iva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1784
		if (VOP_GETATTR(dvp, &iva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
			iva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
	}
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1789
	if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  1790
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1800
	(void) VOP_FSYNC(dvp, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
		if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
		nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
		resp->attrset = 0;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1807
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	 * Finish setup of cinfo response, "before" value already set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	 * Get "after" change value, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
	ava.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  1816
	if (VOP_GETATTR(dvp, &ava, 0, cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
		ava.va_ctime = bva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
		ava.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.after, ava.va_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	 * True verification that object was created with correct
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
	 * attrs is impossible.  The attrs could have been changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
	 * immediately after object creation.  If attributes did
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	 * not verify, the only recourse for the server is to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
	 * destroy the object.  Maybe if some attrs (like gid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
	 * are set incorrectly, the object should be destroyed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
	 * however, seems bad as a default policy.  Do we really
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
	 * want to destroy an object over one of the times not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	 * verifying correctly?  For these reasons, the server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
	 * currently sets bits in attrset for createattrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
	 * that were set; however, no verification is done.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
	 * vmask_to_nmask accounts for vattr bits set on create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
	 *	[do_rfs4_set_attrs() only sets resp bits for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
	 *	 non-vattr/vfs bits.]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
	 * Mask off any bits set by default so as not to return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
	 * more attrset bits than were requested in createattrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	nfs4_vmask_to_nmask(sarg.vap->va_mask, &resp->attrset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
	resp->attrset &= args->createattrs.attrmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	error = makefh4(&cs->fh, vp, cs->exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	 * The cinfo.atomic = TRUE only if we got no errors, we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	 * non-zero va_seq's, and it has incremented by exactly one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	 * during the creation and it didn't change during the VOP_LOOKUP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	 * or VOP_FSYNC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	if (!error && bva.va_seq && iva.va_seq && ava.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  1857
	    iva.va_seq == (bva.va_seq + 1) && iva.va_seq == ava.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
		resp->cinfo.atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
		resp->cinfo.atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
6402
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1862
	/*
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1863
	 * Force modified metadata out to stable storage.
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1864
	 *
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1865
	 * if a underlying vp exists, pass it to VOP_FSYNC
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1866
	 */
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1867
	if (VOP_REALVP(vp, &realvp, NULL) == 0)
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1868
		(void) VOP_FSYNC(realvp, syncval, cr, NULL);
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1869
	else
b1d298e9ce79 6614416 panic in spec_fsync() when creating a device file via NFS
gt29601
parents: 6364
diff changeset
  1870
		(void) VOP_FSYNC(vp, syncval, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
		VN_RELE(vp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1874
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	if (cs->vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
	cs->vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1881
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1882
	DTRACE_NFSV4_2(op__create__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1883
	    CREATE4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1886
/*ARGSUSED*/
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1887
static void
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1888
rfs4_op_delegpurge(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1889
    struct compound_state *cs)
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1890
{
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1891
	DTRACE_NFSV4_2(op__delegpurge__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1892
	    DELEGPURGE4args *, &argop->nfs_argop4_u.opdelegpurge);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1893
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1894
	rfs4_op_inval(argop, resop, req, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1895
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1896
	DTRACE_NFSV4_2(op__delegpurge__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1897
	    DELEGPURGE4res *, &resop->nfs_resop4_u.opdelegpurge);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1898
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
rfs4_op_delegreturn(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	DELEGRETURN4args *args = &argop->nfs_argop4_u.opdelegreturn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
	DELEGRETURN4res *resp = &resop->nfs_resop4_u.opdelegreturn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
	rfs4_deleg_state_t *dsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1910
	DTRACE_NFSV4_2(op__delegreturn__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1911
	    DELEGRETURN4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1912
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	status = rfs4_get_deleg_state(&args->deleg_stateid, &dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
	resp->status = *cs->statusp = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
	if (status != NFS4_OK)
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1916
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
	if (cs->vp != dsp->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
		resp->status = *cs->statusp = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
		rfs4_return_deleg(dsp, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	rfs4_update_lease(dsp->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
	rfs4_deleg_state_rele(dsp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1927
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1928
	DTRACE_NFSV4_2(op__delegreturn__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  1929
	    DELEGRETURN4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
 * Check to see if a given "flavor" is an explicitly shared flavor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
 * The assumption of this routine is the "flavor" is already a valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
 * flavor in the secinfo list of "exi".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
 *	e.g.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
 *		# share -o sec=flavor1 /export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
 *		# share -o sec=flavor2 /export/home
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
 *		flavor2 is not an explicitly shared flavor for /export,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
 *		however it is in the secinfo list for /export thru the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
 *		server namespace setup.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
is_exported_sec(int flavor, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	struct secinfo *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	sp = exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	for (i = 0; i < exi->exi_export.ex_seccnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
		if (flavor == sp[i].s_secinfo.sc_nfsnum ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
		    sp[i].s_secinfo.sc_nfsnum == AUTH_NONE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
			return (SEC_REF_EXPORTED(&sp[i]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	/* Should not reach this point based on the assumption */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
 * Check if the security flavor used in the request matches what is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
 * required at the export point or at the root pseudo node (exi_root).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
 * returns 1 if there's a match or if exported with AUTH_NONE; 0 otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
secinfo_match_or_authnone(struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
	struct secinfo *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
	 * Check cs->nfsflavor (from the request) against
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
	 * the current export data in cs->exi.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
	sp = cs->exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
	for (i = 0; i < cs->exi->exi_export.ex_seccnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
		if (cs->nfsflavor == sp[i].s_secinfo.sc_nfsnum ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
		    sp[i].s_secinfo.sc_nfsnum == AUTH_NONE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
 * Check the access authority for the client and return the correct error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
call_checkauth4(struct compound_state *cs, struct svc_req *req)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
	int	authres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
	 * First, check if the security flavor used in the request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
	 * are among the flavors set in the server namespace.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
	if (!secinfo_match_or_authnone(cs)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
		*cs->statusp = NFS4ERR_WRONGSEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
		return (*cs->statusp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
	authres = checkauth4(cs, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	if (authres > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
		*cs->statusp = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
		if (! (cs->access & CS_ACCESS_LIMITED))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
			cs->access = CS_ACCESS_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
	} else if (authres == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
		*cs->statusp = NFS4ERR_ACCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	} else if (authres == -2) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
		*cs->statusp = NFS4ERR_WRONGSEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
		*cs->statusp = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	return (*cs->statusp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
 * bitmap4_to_attrmask is called by getattr and readdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
 * It sets up the vattr mask and determines whether vfsstat call is needed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
 * based on the input bitmap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
 * Returns nfsv4 status.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
bitmap4_to_attrmask(bitmap4 breq, struct nfs4_svgetit_arg *sargp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
	uint_t	va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
	struct statvfs64 *sbp = sargp->sbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	sargp->sbp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	sargp->flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
	sargp->rdattr_error = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	sargp->mntdfid_set = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	if (sargp->cs->vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
		sargp->xattr = get_fh4_flag(&sargp->cs->fh,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2042
		    FH4_ATTRDIR | FH4_NAMEDATTR);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
		sargp->xattr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
	 * Set rdattr_error_req to true if return error per
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
	 * failed entry rather than fail the readdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
	if (breq & FATTR4_RDATTR_ERROR_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
		sargp->rdattr_error_req = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
		sargp->rdattr_error_req = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
	 * generate the va_mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
	 * Handle the easy cases first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
	switch (breq) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
	case NFS4_NTOV_ATTR_MASK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
		sargp->vap->va_mask = NFS4_NTOV_ATTR_AT_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
	case NFS4_FS_ATTR_MASK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
		sargp->vap->va_mask = NFS4_FS_ATTR_AT_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
		sargp->sbp = sbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
	case NFS4_NTOV_ATTR_CACHE_MASK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
		sargp->vap->va_mask = NFS4_NTOV_ATTR_CACHE_AT_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
	case FATTR4_LEASE_TIME_MASK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
		sargp->vap->va_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
		va_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
		for (i = 0; i < nfs4_ntov_map_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
			if ((breq & nfs4_ntov_map[i].fbit) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2081
			    nfs4_ntov_map[i].vbit)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
				va_mask |= nfs4_ntov_map[i].vbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
		 * Check is vfsstat is needed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
		if (breq & NFS4_FS_ATTR_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
			sargp->sbp = sbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
		sargp->vap->va_mask = va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
 * bitmap4_get_sysattrs is called by getattr and readdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
 * It calls both VOP_GETATTR and VFS_STATVFS calls to get the attrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
 * Returns nfsv4 status.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
bitmap4_get_sysattrs(struct nfs4_svgetit_arg *sargp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	struct compound_state *cs = sargp->cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
	vnode_t *vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	if (sargp->sbp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
		if (error = VFS_STATVFS(vp->v_vfsp, sargp->sbp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
			sargp->sbp = NULL;	/* to identify error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
			return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
	return (rfs4_vop_getattr(vp, sargp->vap, 0, cs->cr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
nfs4_ntov_table_init(struct nfs4_ntov_table *ntovp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	ntovp->na = kmem_zalloc(sizeof (union nfs4_attr_u) * nfs4_ntov_map_size,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2123
	    KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	ntovp->attrcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
	ntovp->vfsstat = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
nfs4_ntov_table_free(struct nfs4_ntov_table *ntovp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
	struct nfs4_svgetit_arg *sargp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
	union nfs4_attr_u *na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
	uint8_t *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	 * XXX Should do the same checks for whether the bit is set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	for (i = 0, na = ntovp->na, amap = ntovp->amap;
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2140
	    i < ntovp->attrcnt; i++, na++, amap++) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
		(void) (*nfs4_ntov_map[*amap].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2142
		    NFS4ATTR_FREEIT, sargp, na);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
	if ((sargp->op == NFS4ATTR_SETIT) || (sargp->op == NFS4ATTR_VERIT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
		 * xdr_free for getattr will be done later
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
		for (i = 0, na = ntovp->na, amap = ntovp->amap;
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2149
		    i < ntovp->attrcnt; i++, na++, amap++) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
			xdr_free(nfs4_ntov_map[*amap].xfunc, (caddr_t)na);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
	kmem_free(ntovp->na, sizeof (union nfs4_attr_u) * nfs4_ntov_map_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
 * do_rfs4_op_getattr gets the system attrs and converts into fattr4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
do_rfs4_op_getattr(bitmap4 breq, fattr4 *fattrp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	struct nfs4_svgetit_arg *sargp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	int i, k;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
	XDR xdr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	ulong_t xdr_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	char *xdr_attrs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
	nfsstat4 status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	nfsstat4 prev_rdattr_error = sargp->rdattr_error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	union nfs4_attr_u *na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
	uint8_t *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
	sargp->op = NFS4ATTR_GETIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
	sargp->flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
	fattrp->attrmask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
	/* if no bits requested, then return empty fattr4 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
	if (breq == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
		fattrp->attrlist4_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
		fattrp->attrlist4 = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	 * return NFS4ERR_INVAL when client requests write-only attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
	if (breq & (FATTR4_TIME_ACCESS_SET_MASK | FATTR4_TIME_MODIFY_SET_MASK))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
	nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
	na = ntov.na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
	amap = ntov.amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
	 * Now loop to get or verify the attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
	for (i = 0; i < nfs4_ntov_map_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
		if (breq & nfs4_ntov_map[i].fbit) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
			if ((*nfs4_ntov_map[i].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2201
			    NFS4ATTR_SUPPORTED, sargp, NULL) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
				error = (*nfs4_ntov_map[i].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2204
				    NFS4ATTR_GETIT, sargp, na);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
				 * Possible error values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
				 * >0 if sv_getit failed to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
				 * get the attr; 0 if succeeded;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
				 * <0 if rdattr_error and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
				 * attribute cannot be returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
				if (error && !(sargp->rdattr_error_req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
					goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
				 * If error then just for entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
				if (error == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
					fattrp->attrmask |=
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2220
					    nfs4_ntov_map[i].fbit;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
					*amap++ =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2222
					    (uint8_t)nfs4_ntov_map[i].nval;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
					na++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
					(ntov.attrcnt)++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
				} else if ((error > 0) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2226
				    (sargp->rdattr_error == NFS4_OK)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
					sargp->rdattr_error = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
				error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
	 * If rdattr_error was set after the return value for it was assigned,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
	 * update it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
	if (prev_rdattr_error != sargp->rdattr_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
		na = ntov.na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
		amap = ntov.amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
		for (i = 0; i < ntov.attrcnt; i++, na++, amap++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
			k = *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
			if (k < FATTR4_RDATTR_ERROR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
			if ((k == FATTR4_RDATTR_ERROR) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
			    ((*nfs4_ntov_map[k].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2248
			    NFS4ATTR_SUPPORTED, sargp, NULL) == 0)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
				(void) (*nfs4_ntov_map[k].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2251
				    NFS4ATTR_GETIT, sargp, na);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
	xdr_size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
	na = ntov.na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
	amap = ntov.amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
	for (i = 0; i < ntov.attrcnt; i++, na++, amap++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
		xdr_size += xdr_sizeof(nfs4_ntov_map[*amap].xfunc, na);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
	fattrp->attrlist4_len = xdr_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	if (xdr_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
		/* freed by rfs4_op_getattr_free() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
		fattrp->attrlist4 = xdr_attrs = kmem_zalloc(xdr_size, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
		xdrmem_create(&xdr, xdr_attrs, xdr_size, XDR_ENCODE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
		na = ntov.na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
		amap = ntov.amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
		for (i = 0; i < ntov.attrcnt; i++, na++, amap++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
			if (!(*nfs4_ntov_map[*amap].xfunc)(&xdr, na)) {
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  2275
				DTRACE_PROBE1(nfss__e__getattr4_encfail,
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  2276
				    int, *amap);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
				status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
		/* xdrmem_destroy(&xdrs); */	/* NO-OP */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
		fattrp->attrlist4 = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
	nfs4_ntov_table_free(&ntov, sargp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
rfs4_op_getattr(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
	GETATTR4args *args = &argop->nfs_argop4_u.opgetattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
	GETATTR4res *resp = &resop->nfs_resop4_u.opgetattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2306
	DTRACE_NFSV4_2(op__getattr__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2307
	    GETATTR4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2308
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2311
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2316
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
	sarg.cs = cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
	status = bitmap4_to_attrmask(args->attr_request, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	if (status == NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
		status = bitmap4_get_sysattrs(&sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
		if (status == NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
			status = do_rfs4_op_getattr(args->attr_request,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2327
			    &resp->obj_attributes, &sarg);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
	*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2330
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2331
	DTRACE_NFSV4_2(op__getattr__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2332
	    GETATTR4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
rfs4_op_getattr_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
	GETATTR4res *resp = &resop->nfs_resop4_u.opgetattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	nfs4_fattr4_free(&resp->obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
rfs4_op_getfh(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
	GETFH4res *resp = &resop->nfs_resop4_u.opgetfh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2350
	DTRACE_NFSV4_1(op__getfh__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2351
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2354
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2358
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
	resp->object.nfs_fh4_val =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2362
	    kmem_alloc(cs->fh.nfs_fh4_len, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
	nfs_fh4_copy(&cs->fh, &resp->object);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2365
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2366
	DTRACE_NFSV4_2(op__getfh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2367
	    GETFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
rfs4_op_getfh_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
	GETFH4res *resp = &resop->nfs_resop4_u.opgetfh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
	if (resp->status == NFS4_OK &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
	    resp->object.nfs_fh4_val != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
		kmem_free(resp->object.nfs_fh4_val, resp->object.nfs_fh4_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
		resp->object.nfs_fh4_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
		resp->object.nfs_fh4_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
 * illegal: args: void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
 *	    res : status (NFS4ERR_OP_ILLEGAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
rfs4_op_illegal(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
	struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	ILLEGAL4res *resp = &resop->nfs_resop4_u.opillegal;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
	resop->resop = OP_ILLEGAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
	*cs->statusp = resp->status = NFS4ERR_OP_ILLEGAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
 * link: args: SAVED_FH: file, CURRENT_FH: target directory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
 *	 res: status. If success - CURRENT_FH unchanged, return change_info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
rfs4_op_link(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
	LINK4args *args = &argop->nfs_argop4_u.oplink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	LINK4res *resp = &resop->nfs_resop4_u.oplink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
	struct vattr bdva, idva, adva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
	char *nm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
	uint_t  len;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2415
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2416
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2418
	DTRACE_NFSV4_2(op__link__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2419
	    LINK4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2420
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	/* SAVED_FH: source object */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	vp = cs->saved_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2425
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
	/* CURRENT_FH: target directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
	dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2432
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
	 * If there is a non-shared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	 * do not allow to link any file in this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	if (vn_ismntpt(dvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2441
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2446
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	/* Check source object's type validity */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	if (vp->v_type == VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
		*cs->statusp = resp->status = NFS4ERR_ISDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2452
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
	/* Check target directory's type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
	if (dvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2458
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
	if (cs->saved_exi != cs->exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		*cs->statusp = resp->status = NFS4ERR_XDEV;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2463
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
	if (!utf8_dir_verify(&args->newname)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2468
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
	nm = utf8_to_fn(&args->newname, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2474
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2480
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
		*cs->statusp = resp->status = NFS4ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2486
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	/* Get "before" change value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
	bdva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2491
	error = VOP_GETATTR(dvp, &bdva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2495
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2498
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2499
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2500
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2501
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2502
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2503
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2504
		kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2505
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2506
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2507
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.before, bdva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2510
	error = VOP_LINK(dvp, vp, name, cs->cr, NULL, 0);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2511
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2512
	if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2513
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
	kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
	 * Get the initial "after" sequence number, if it fails, set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
	idva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2520
	if (VOP_GETATTR(dvp, &idva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		idva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2526
	(void) VOP_FSYNC(vp, FNODSYNC, cs->cr, NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2527
	(void) VOP_FSYNC(dvp, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2531
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
	 * Get "after" change value, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
	 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	adva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2539
	if (VOP_GETATTR(dvp, &adva, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
		adva.va_ctime = bdva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
		adva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.after, adva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
	 * The cinfo.atomic = TRUE only if we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
	 * non-zero va_seq's, and it has incremented by exactly one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
	 * during the VOP_LINK and it didn't change during the VOP_FSYNC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
	if (bdva.va_seq && idva.va_seq && adva.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  2552
	    idva.va_seq == (bdva.va_seq + 1) && idva.va_seq == adva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
		resp->cinfo.atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
		resp->cinfo.atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2558
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2559
	DTRACE_NFSV4_2(op__link__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2560
	    LINK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
 * Used by rfs4_op_lookup and rfs4_op_lookupp to do the actual work.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
do_rfs4_op_lookup(char *nm, uint_t buflen, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
	int different_export = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	vnode_t *vp, *tvp, *pre_tvp = NULL, *oldvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	struct exportinfo *exi = NULL, *pre_exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	nfsstat4 stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	int attrdir, dotdot, walk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
	bool_t is_newvp = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
	if (cs->vp->v_flag & V_XATTRDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
		attrdir = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
		ASSERT(get_fh4_flag(&cs->fh, FH4_ATTRDIR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
		attrdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
		ASSERT(! get_fh4_flag(&cs->fh, FH4_ATTRDIR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
	dotdot = (nm[0] == '.' && nm[1] == '.' && nm[2] == '\0');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
	 * If dotdotting, then need to check whether it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
	 * above the root of a filesystem, or above an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
	 * export point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
	if (dotdot) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
		 * If dotdotting at the root of a filesystem, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
		 * need to traverse back to the mounted-on filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
		 * and do the dotdot lookup there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
		if (cs->vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
			 * If at the system root, then can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
			 * go up no further.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
			if (VN_CMP(cs->vp, rootdir))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
				return (puterrno4(ENOENT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
			 * Traverse back to the mounted-on filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
			cs->vp = untraverse(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
			 * Set the different_export flag so we remember
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
			 * to pick up a new exportinfo entry for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
			 * this new filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
			different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
			 * If dotdotting above an export point then set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
			 * the different_export to get new export info.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
			different_export = nfs_exported(cs->exi, cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2633
	error = VOP_LOOKUP(cs->vp, nm, &vp, NULL, 0, NULL, cs->cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2634
	    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
	 * If the vnode is in a pseudo filesystem, check whether it is visible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
	 * XXX if the vnode is a symlink and it is not visible in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
	 * a pseudo filesystem, return ENOENT (not following symlink).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
	 * V4 client can not mount such symlink. This is a regression
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
	 * from V2/V3.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
	 * In the same exported filesystem, if the security flavor used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
	 * is not an explicitly shared flavor, limit the view to the visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
	 * list entries only. This is not a WRONGSEC case because it's already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
	 * checked via PUTROOTFH/PUTPUBFH or PUTFH.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
	if (!different_export &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	    (PSEUDO(cs->exi) || ! is_exported_sec(cs->nfsflavor, cs->exi) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	    cs->access & CS_ACCESS_LIMITED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
		if (! nfs_visible(cs->exi, vp, &different_export)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
			return (puterrno4(ENOENT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
	 * If it's a mountpoint, then traverse it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	if (vn_ismntpt(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
		pre_exi = cs->exi;	/* save pre-traversed exportinfo */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
		pre_tvp = vp;		/* save pre-traversed vnode	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
		 * hold pre_tvp to counteract rele by traverse.  We will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
		 * need pre_tvp below if checkexport4 fails
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
		VN_HOLD(pre_tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
		tvp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
		if ((error = traverse(&tvp)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
			VN_RELE(pre_tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
			return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
		vp = tvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
		different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	} else if (vp->v_vfsp != cs->vp->v_vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
		 * The vfsp comparison is to handle the case where
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
		 * a LOFS mount is shared.  lo_lookup traverses mount points,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
		 * and NFS is unaware of local fs transistions because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
		 * v_vfsmountedhere isn't set.  For this special LOFS case,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
		 * the dir and the obj returned by lookup will have different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
		 * vfs ptrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
		different_export = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
	if (different_export) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
			if (pre_tvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
				VN_RELE(pre_tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
			return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
		if (dotdot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
			exi = nfs_vptoexi(NULL, vp, cs->cr, &walk, NULL, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
		if (exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
			if (pre_tvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
				 * If this vnode is a mounted-on vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
				 * but the mounted-on file system is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
				 * exported, send back the filehandle for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
				 * the mounted-on vnode, not the root of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
				 * the mounted-on file system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
				VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
				vp = pre_tvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
				exi = pre_exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
				VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
				return (puterrno4(EACCES));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
		} else if (pre_tvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
			/* we're done with pre_tvp now. release extra hold */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
			VN_RELE(pre_tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
		cs->exi = exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
		 * Now we do a checkauth4. The reason is that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
		 * this client/user may not have access to the new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
		 * exported file system, and if he does,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
		 * the client/user may be mapped to a different uid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
		 * We start with a new cr, because the checkauth4 done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
		 * in the PUT*FH operation over wrote the cred's uid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
		 * gid, etc, and we want the real thing before calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
		 * checkauth4()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
		crfree(cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
		cs->cr = crdup(cs->basecr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
		if (cs->vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
			oldvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
		cs->vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
		is_newvp = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
		stat = call_checkauth4(cs, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
		if (stat != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
			VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
			cs->vp = oldvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
			return (stat);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2759
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2760
	 * After various NFS checks, do a label check on the path
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2761
	 * component. The label on this path should either be the
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2762
	 * global zone's label or a zone's label. We are only
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2763
	 * interested in the zone's label because exported files
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2764
	 * in global zone is accessible (though read-only) to
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2765
	 * clients. The exportability/visibility check is already
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2766
	 * done before reaching this code.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2767
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2768
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2769
		bslabel_t *clabel;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2770
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2771
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2772
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2773
		DTRACE_PROBE2(tx__rfs4__log__info__oplookup__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2774
		    "got client label from request(1)", struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2775
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2776
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  2777
			if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK)) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2778
				error = EACCES;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2779
				goto err_out;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2780
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2781
		} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2782
			/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2783
			 * We grant access to admin_low label clients
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2784
			 * only if the client is trusted, i.e. also
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2785
			 * running Solaris Trusted Extension.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2786
			 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2787
			struct sockaddr	*ca;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2788
			int		addr_type;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2789
			void		*ipaddr;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2790
			tsol_tpc_t	*tp;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2791
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2792
			ca = (struct sockaddr *)svc_getrpccaller(
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2793
			    req->rq_xprt)->buf;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2794
			if (ca->sa_family == AF_INET) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2795
				addr_type = IPV4_VERSION;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2796
				ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2797
			} else if (ca->sa_family == AF_INET6) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2798
				addr_type = IPV6_VERSION;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2799
				ipaddr = &((struct sockaddr_in6 *)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2800
				    ca)->sin6_addr;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2801
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2802
			tp = find_tpc(ipaddr, addr_type, B_FALSE);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2803
			if (tp == NULL || tp->tpc_tp.tp_doi !=
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2804
			    l_admin_low->tsl_doi || tp->tpc_tp.host_type !=
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2805
			    SUN_CIPSO) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  2806
				if (tp != NULL)
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  2807
					TPC_RELE(tp);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2808
				error = EACCES;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2809
				goto err_out;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2810
			}
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  2811
			TPC_RELE(tp);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2812
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2813
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2814
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	error = makefh4(&cs->fh, vp, cs->exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  2817
err_out:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
		if (is_newvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
			VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
			cs->vp = oldvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
	if (!is_newvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
		if (cs->vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
			VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
		cs->vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	} else if (oldvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
		VN_RELE(oldvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
	 * if did lookup on attrdir and didn't lookup .., set named
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
	 * attr fh flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
	if (attrdir && ! dotdot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
		set_fh4_flag(&cs->fh, FH4_NAMEDATTR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
	/* Assume false for now, open proc will set this */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
	cs->mandlock = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
	return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
rfs4_op_lookup(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
	LOOKUP4args *args = &argop->nfs_argop4_u.oplookup;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
	LOOKUP4res *resp = &resop->nfs_resop4_u.oplookup;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
	char *nm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
	uint_t len;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2856
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2857
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2859
	DTRACE_NFSV4_2(op__lookup__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2860
	    LOOKUP4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2861
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2864
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
	if (cs->vp->v_type == VLNK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
		*cs->statusp = resp->status = NFS4ERR_SYMLINK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2869
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
	if (cs->vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2874
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
	if (!utf8_dir_verify(&args->objname)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2879
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
	nm = utf8_to_str(&args->objname, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2885
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2891
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2894
	/* If necessary, convert to UTF-8 for illbehaved clients */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2895
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2896
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2897
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2898
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2899
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2900
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2901
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2902
		kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2903
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2904
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2905
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2906
	*cs->statusp = resp->status = do_rfs4_op_lookup(name, len, req, cs);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2907
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2908
	if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  2909
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
	kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2911
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2912
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2913
	DTRACE_NFSV4_2(op__lookup__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2914
	    LOOKUP4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
rfs4_op_lookupp(nfs_argop4 *args, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
	LOOKUPP4res *resp = &resop->nfs_resop4_u.oplookupp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2924
	DTRACE_NFSV4_1(op__lookupp__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2925
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2928
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
	if (cs->vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2933
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2934
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2936
	*cs->statusp = resp->status = do_rfs4_op_lookup("..", 3, req, cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
	 * From NFSV4 Specification, LOOKUPP should not check for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
	 * NFS4ERR_WRONGSEC. Retrun NFS4_OK instead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
	if (resp->status == NFS4ERR_WRONGSEC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
	}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2945
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2946
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2947
	DTRACE_NFSV4_2(op__lookupp__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2948
	    LOOKUPP4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
/*ARGSUSED2*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
rfs4_op_openattr(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
	OPENATTR4args	*args = &argop->nfs_argop4_u.opopenattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
	OPENATTR4res	*resp = &resop->nfs_resop4_u.opopenattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
	vnode_t		*avp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
	int		lookup_flags = LOOKUP_XATTR, error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
	int		exp_ro = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2963
	DTRACE_NFSV4_2(op__openattr__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2964
	    OPENATTR4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2965
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2968
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  2971
	if ((cs->vp->v_vfsp->vfs_flag & VFS_XATTR) == 0 &&
7757
bf4a45ecb669 PSARC/2008/588 VFSFT_SYSATTR_VIEWS
Janice Chang <Janice.Chang@Sun.COM>
parents: 7387
diff changeset
  2972
	    !vfs_has_feature(cs->vp->v_vfsp, VFSFT_SYSATTR_VIEWS)) {
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2973
		*cs->statusp = resp->status = puterrno4(ENOTSUP);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2974
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
7067
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2977
	/*
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2978
	 * If file system supports passing ACE mask to VOP_ACCESS then
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2979
	 * check for ACE_READ_NAMED_ATTRS, otherwise do legacy checks
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2980
	 */
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2981
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2982
	if (vfs_has_feature(cs->vp->v_vfsp, VFSFT_ACEMASKONACCESS))
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2983
		error = VOP_ACCESS(cs->vp, ACE_READ_NAMED_ATTRS,
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2984
		    V_ACE_MASK, cs->cr, NULL);
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2985
	else
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2986
		error = ((VOP_ACCESS(cs->vp, VREAD, 0, cs->cr, NULL) != 0) &&
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2987
		    (VOP_ACCESS(cs->vp, VWRITE, 0, cs->cr, NULL) != 0) &&
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2988
		    (VOP_ACCESS(cs->vp, VEXEC, 0, cs->cr, NULL) != 0));
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2989
09d6b97e1874 6683575 Revisit handling of CREATE_XATTR_DIR
marks
parents: 6976
diff changeset
  2990
	if (error) {
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2991
		*cs->statusp = resp->status = puterrno4(EACCES);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  2992
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
	 * The CREATE_XATTR_DIR VOP flag cannot be specified if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
	 * the file system is exported read-only -- regardless of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
	 * createdir flag.  Otherwise the attrdir would be created
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
	 * (assuming server fs isn't mounted readonly locally).  If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	 * VOP_LOOKUP returns ENOENT in this case, the error will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
	 * be translated into EROFS.  ENOSYS is mapped to ENOTSUP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
	 * because specfs has no VOP_LOOKUP op, so the macro would
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
	 * return ENOSYS.  EINVAL is returned by all (current)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
	 * Solaris file system implementations when any of their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
	 * restrictions are violated (xattr(dir) can't have xattrdir).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
	 * Returning NOTSUPP is more appropriate in this case
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
	 * because the object will never be able to have an attrdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
	if (args->createdir && ! (exp_ro = rdonly4(cs->exi, cs->vp, req)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
		lookup_flags |= CREATE_XATTR_DIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3012
	error = VOP_LOOKUP(cs->vp, "", &avp, NULL, lookup_flags, NULL, cs->cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3013
	    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
		if (error == ENOENT && args->createdir && exp_ro)
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3017
			*cs->statusp = resp->status = puterrno4(EROFS);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
		else if (error == EINVAL || error == ENOSYS)
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3019
			*cs->statusp = resp->status = puterrno4(ENOTSUP);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3020
		else
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3021
			*cs->statusp = resp->status = puterrno4(error);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3022
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
	ASSERT(avp->v_flag & V_XATTRDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
	error = makefh4(&cs->fh, avp, cs->exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
		VN_RELE(avp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3031
		*cs->statusp = resp->status = puterrno4(error);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3032
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
	VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
	cs->vp = avp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
	 * There is no requirement for an attrdir fh flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
	 * because the attrdir has a vnode flag to distinguish
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
	 * it from regular (non-xattr) directories.  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
	 * FH4_ATTRDIR flag is set for future sanity checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
	set_fh4_flag(&cs->fh, FH4_ATTRDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3046
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3047
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3048
	DTRACE_NFSV4_2(op__openattr__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3049
	    OPENATTR4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3053
do_io(int direction, vnode_t *vp, struct uio *uio, int ioflag, cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3054
    caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
	clock_t delaytime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
	delaytime = MSEC_TO_TICK_ROUNDUP(rfs4_lock_delay);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
	 * Don't block on mandatory locks. If this routine returns
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
	 * EAGAIN, the caller should return NFS4ERR_LOCKED.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
	uio->uio_fmode = FNONBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
	for (i = 0; i < rfs4_maxlock_tries; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
		if (direction == FREAD) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3072
			(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, ct);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3073
			error = VOP_READ(vp, uio, ioflag, cred, ct);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3074
			VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
		} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3076
			(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, ct);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3077
			error = VOP_WRITE(vp, uio, ioflag, cred, ct);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3078
			VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
		if (error != EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
		if (i < rfs4_maxlock_tries - 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
			delay(delaytime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
			delaytime *= 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
rfs4_op_read(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
	READ4args *args = &argop->nfs_argop4_u.opread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
	READ4res *resp = &resop->nfs_resop4_u.opread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
	int verror;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
	u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
	bool_t *deleg = &cs->deleg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
	nfsstat4 stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
	mblk_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
	int alloc_err = 0;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3112
	caller_context_t ct;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3114
	DTRACE_NFSV4_2(op__read__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3115
	    READ4args, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3116
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
	vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3120
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3124
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3127
	if ((stat = rfs4_check_stateid(FREAD, vp, &args->stateid, FALSE,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3128
	    deleg, TRUE, &ct)) != NFS4_OK) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3129
		*cs->statusp = resp->status = stat;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3130
		goto out;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3131
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3132
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
	 * Enter the critical region before calling VOP_RWLOCK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
	 * to avoid a deadlock with write requests.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
	if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
		nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
		in_crit = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3140
		if (nbl_conflict(vp, NBL_READ, args->offset, args->count, 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3141
		    &ct)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
			*cs->statusp = resp->status = NFS4ERR_LOCKED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	if ((stat = rfs4_check_stateid(FREAD, vp, &args->stateid, FALSE,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3148
	    deleg, TRUE, &ct)) != NFS4_OK) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
		*cs->statusp = resp->status = stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
	va.va_mask = AT_MODE|AT_SIZE|AT_UID;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3154
	verror = VOP_GETATTR(vp, &va, 0, cs->cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
	if (verror) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
		*cs->statusp = resp->status = puterrno4(verror);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  3167
		    ((vp->v_type == VDIR) ? NFS4ERR_ISDIR : NFS4ERR_INVAL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
	if (crgetuid(cs->cr) != va.va_uid &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3172
	    (error = VOP_ACCESS(vp, VREAD, 0, cs->cr, &ct)) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3173
	    (error = VOP_ACCESS(vp, VEXEC, 0, cs->cr, &ct))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
	if (MANDLOCK(vp, va.va_mode)) { /* XXX - V4 supports mand locking */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
	offset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
	if (offset >= va.va_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
		resp->eof = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
		resp->data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
		resp->data_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
		resp->mblk = NULL;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3190
		/* RDMA */
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3191
		resp->wlist = args->wlist;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3192
		resp->wlist_len = resp->data_len;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
		*cs->statusp = resp->status = NFS4_OK;
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  3194
		if (resp->wlist)
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  3195
			clist_zero_len(resp->wlist);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
	if (args->count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
		resp->eof = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
		resp->data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
		resp->data_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
		resp->mblk = NULL;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3205
		/* RDMA */
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3206
		resp->wlist = args->wlist;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3207
		resp->wlist_len = resp->data_len;
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  3208
		if (resp->wlist)
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  3209
			clist_zero_len(resp->wlist);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
	 * Do not allocate memory more than maximum allowed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
	 * transfer size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
	if (args->count > rfs4_tsize(req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
		args->count = rfs4_tsize(req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
	/*
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3221
	 * If returning data via RDMA Write, then grab the chunk list. If we
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3222
	 * aren't returning READ data w/RDMA_WRITE, then grab a mblk.
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3223
	 */
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3224
	if (args->wlist) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3225
		mp = NULL;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3226
		(void) rdma_get_wchunk(req, &iov, args->wlist);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3227
	} else {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3228
		/*
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3229
		 * mp will contain the data to be sent out in the read reply.
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3230
		 * It will be freed after the reply has been sent. Let's
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3231
		 * roundup the data to a BYTES_PER_XDR_UNIT multiple, so that
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3232
		 * the call to xdrmblk_putmblk() never fails. If the first
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3233
		 * alloc of the requested size fails, then decrease the size to
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3234
		 * something more reasonable and wait for the allocation to
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3235
		 * occur.
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3236
		 */
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3237
		mp = allocb(RNDUP(args->count), BPRI_MED);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3238
		if (mp == NULL) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3239
			if (args->count > MAXBSIZE)
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3240
				args->count = MAXBSIZE;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3241
			mp = allocb_wait(RNDUP(args->count), BPRI_MED,
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3242
			    STR_NOSIG, &alloc_err);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3243
		}
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3244
		ASSERT(mp != NULL);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3245
		ASSERT(alloc_err == 0);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3246
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3247
		iov.iov_base = (caddr_t)mp->b_datap->db_base;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3248
		iov.iov_len = args->count;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3249
	}
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3250
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
	uio.uio_loffset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
	uio.uio_resid = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3258
	error = do_io(FREAD, vp, &uio, 0, cs->cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
	va.va_mask = AT_SIZE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3261
	verror = VOP_GETATTR(vp, &va, 0, cs->cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
		freeb(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
	ASSERT(uio.uio_resid >= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	resp->data_len = args->count - uio.uio_resid;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3273
	if (mp) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3274
		resp->data_val = (char *)mp->b_datap->db_base;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3275
	} else {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3276
		resp->data_val = (caddr_t)iov.iov_base;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3277
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
	resp->mblk = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
	if (!verror && offset + resp->data_len == va.va_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
		resp->eof = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
		resp->eof = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3285
	if (args->wlist) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3286
		if (!rdma_setup_read_data4(args, resp)) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3287
			*cs->statusp = resp->status = NFS4ERR_INVAL;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3288
		}
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3289
	} else {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3290
		resp->wlist = NULL;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3291
	}
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3292
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
		nbl_end_crit(vp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3296
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3297
	DTRACE_NFSV4_2(op__read__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3298
	    READ4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
rfs4_op_read_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
{
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3304
	READ4res	*resp = &resop->nfs_resop4_u.opread;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
	if (resp->status == NFS4_OK && resp->mblk != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
		freeb(resp->mblk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
		resp->mblk = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
		resp->data_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
		resp->data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
static void
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3315
rfs4_op_readdir_free(nfs_resop4 * resop)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
{
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3317
	READDIR4res    *resp = &resop->nfs_resop4_u.opreaddir;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
	if (resp->status == NFS4_OK && resp->mblk != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
		freeb(resp->mblk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
		resp->mblk = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
		resp->data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
rfs4_op_putpubfh(nfs_argop4 *args, nfs_resop4 *resop, struct svc_req *req,
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3330
    struct compound_state *cs)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
{
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3332
	PUTPUBFH4res	*resp = &resop->nfs_resop4_u.opputpubfh;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3333
	int		error;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3334
	vnode_t		*vp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
	struct exportinfo *exi, *sav_exi;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  3336
	nfs_fh4_fmt_t	*fh_fmtp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3338
	DTRACE_NFSV4_1(op__putpubfh__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3339
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	if (cs->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
		cs->vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
	if (cs->cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
		crfree(cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
	cs->cr = crdup(cs->basecr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
	vp = exi_public->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
		*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3353
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3356
	if (is_system_labeled()) {
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3357
		bslabel_t *clabel;
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3358
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3359
		ASSERT(req->rq_label != NULL);
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3360
		clabel = req->rq_label;
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3361
		DTRACE_PROBE2(tx__rfs4__log__info__opputpubfh__clabel, char *,
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3362
		    "got client label from request(1)",
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3363
		    struct svc_req *, req);
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3364
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3365
			if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK)) {
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3366
				*cs->statusp = resp->status =
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3367
				    NFS4ERR_SERVERFAULT;
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3368
				return;
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3369
			}
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3370
		}
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3371
	}
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  3372
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
	error = makefh4(&cs->fh, vp, exi_public);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3376
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
	sav_exi = cs->exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
	if (exi_public == exi_root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
		 * No filesystem is actually shared public, so we default
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
		 * to exi_root. In this case, we must check whether root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
		 * is exported.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
		fh_fmtp = (nfs_fh4_fmt_t *)cs->fh.nfs_fh4_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
		 * if root filesystem is exported, the exportinfo struct that we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
		 * should use is what checkexport4 returns, because root_exi is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
		 * actually a mostly empty struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
		exi = checkexport4(&fh_fmtp->fh4_fsid,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  3393
		    (fid_t *)&fh_fmtp->fh4_xlen, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
		cs->exi = ((exi != NULL) ? exi : exi_public);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
		 * it's a properly shared filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
		cs->exi = exi_public;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
	cs->vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
	if ((resp->status = call_checkauth4(cs, req)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
		cs->vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
		cs->exi = sav_exi;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3409
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3413
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3414
	DTRACE_NFSV4_2(op__putpubfh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3415
	    PUTPUBFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
 * XXX - issue with put*fh operations. Suppose /export/home is exported.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
 * Suppose an NFS client goes to mount /export/home/joe. If /export, home,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
 * or joe have restrictive search permissions, then we shouldn't let
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
 * the client get a file handle. This is easy to enforce. However, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
 * don't know what security flavor should be used until we resolve the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
 * path name. Another complication is uid mapping. If root is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
 * the user, then it will be mapped to the anonymous user by default,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
 * but we won't know that till we've resolved the path name. And we won't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
 * know what the anonymous user is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
 * Luckily, SECINFO is specified to take a full filename.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
 * So what we will have to in rfs4_op_lookup is check that flavor of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
 * the target object matches that of the request, and if root was the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
 * caller, check for the root= and anon= options, and if necessary,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
 * repeat the lookup using the right cred_t. But that's not done yet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
rfs4_op_putfh(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
	PUTFH4args *args = &argop->nfs_argop4_u.opputfh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
	PUTFH4res *resp = &resop->nfs_resop4_u.opputfh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
	nfs_fh4_fmt_t *fh_fmtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3443
	DTRACE_NFSV4_2(op__putfh__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3444
	    PUTFH4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3445
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
	if (cs->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
		cs->vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
	if (cs->cr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
		crfree(cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
		cs->cr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
	if (args->object.nfs_fh4_len < NFS_FH4_LEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
		*cs->statusp = resp->status = NFS4ERR_BADHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3459
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
	fh_fmtp = (nfs_fh4_fmt_t *)args->object.nfs_fh4_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
	cs->exi = checkexport4(&fh_fmtp->fh4_fsid, (fid_t *)&fh_fmtp->fh4_xlen,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  3464
	    NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
	if (cs->exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
		*cs->statusp = resp->status = NFS4ERR_STALE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3468
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
	cs->cr = crdup(cs->basecr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
	ASSERT(cs->cr != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
	if (! (cs->vp = nfs4_fhtovp(&args->object, cs->exi, &resp->status))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
		*cs->statusp = resp->status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3477
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
	if ((resp->status = call_checkauth4(cs, req)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
		cs->vp = NULL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3483
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
	nfs_fh4_copy(&args->object, &cs->fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
	cs->deleg = FALSE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3489
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3490
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3491
	DTRACE_NFSV4_2(op__putfh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3492
	    PUTFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
rfs4_op_putrootfh(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
	PUTROOTFH4res *resp = &resop->nfs_resop4_u.opputrootfh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
	struct exportinfo *exi, *sav_exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3506
	DTRACE_NFSV4_1(op__putrootfh__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3507
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
	if (cs->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
		cs->vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
	if (cs->cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
		crfree(cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
	cs->cr = crdup(cs->basecr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
	 * Using rootdir, the system root vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
	 * get its fid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
	error = vop_fid_pseudo(rootdir, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3527
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
	 * Then use the root fsid & fid it to find out if it's exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
	 * If the server root isn't exported directly, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
	 * it should at least be a pseudo export based on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
	 * one or more exports further down in the server's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
	 * file tree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
	exi = checkexport4(&rootdir->v_vfsp->vfs_fsid, &fid, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
	if (exi == NULL || exi->exi_export.ex_flags & EX_PUBLIC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
		NFS4_DEBUG(rfs4_debug,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
			(CE_WARN, "rfs4_op_putrootfh: export check failure"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
		*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3543
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
	 * Now make a filehandle based on the root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
	 * export and root vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
	error = makefh4(&cs->fh, rootdir, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3553
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
	sav_exi = cs->exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
	cs->exi = exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
	VN_HOLD(rootdir);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
	cs->vp = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
	if ((resp->status = call_checkauth4(cs, req)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
		VN_RELE(rootdir);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
		cs->vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
		cs->exi = sav_exi;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3566
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
	cs->deleg = FALSE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3571
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3572
	DTRACE_NFSV4_2(op__putrootfh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3573
	    PUTROOTFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
 * A directory entry is a valid nfsv4 entry if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
 * - it has a non-zero ino
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
 * - it is not a dot or dotdot name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
 * - it is visible in a pseudo export or in a real export that can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
 *   only have a limited view.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
static bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
valid_nfs4_entry(struct exportinfo *exi, struct dirent64 *dp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
		int *expseudo, int check_visible)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
	if (dp->d_ino == 0 || NFS_IS_DOTNAME(dp->d_name)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
	if (! check_visible) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
		return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
	return (nfs_visible_inode(exi, dp->d_ino, expseudo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
 * set_rdattr_params sets up the variables used to manage what information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
 * to get for each directory entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
set_rdattr_params(struct nfs4_svgetit_arg *sargp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
		bitmap4 attrs, bool_t *need_to_lookup)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
	uint_t	va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
	bitmap4 objbits;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
	status = bitmap4_to_attrmask(attrs, sargp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
		 * could not even figure attr mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
		return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
	va_mask = sargp->vap->va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
	 * dirent's d_ino is always correct value for mounted_on_fileid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
	 * mntdfid_set is set once here, but mounted_on_fileid is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
	 * set in main dirent processing loop for each dirent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
	 * The mntdfid_set is a simple optimization that lets the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
	 * server attr code avoid work when caller is readdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
	sargp->mntdfid_set = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
	 * Lookup entry only if client asked for any of the following:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
	 * a) vattr attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
	 * b) vfs attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
	 * c) attrs w/per-object scope requested (change, filehandle, etc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
	 *    other than mounted_on_fileid (which we can take from dirent)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
	objbits = attrs ? attrs & NFS4_VP_ATTR_MASK : 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
	if (va_mask || sargp->sbp || (objbits & ~FATTR4_MOUNTED_ON_FILEID_MASK))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
		*need_to_lookup = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
		*need_to_lookup = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
	if (sargp->sbp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
		return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
	 * If filesystem attrs are requested, get them now from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
	 * directory vp, as most entries will have same filesystem. The only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
	 * exception are mounted over entries but we handle
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
	 * those as we go (XXX mounted over detection not yet implemented).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
	sargp->vap->va_mask = 0;	/* to avoid VOP_GETATTR */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
	status = bitmap4_get_sysattrs(sargp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
	sargp->vap->va_mask = va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
	if ((status != NFS4_OK) && sargp->rdattr_error_req) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
		 * Failed to get filesystem attributes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
		 * Return a rdattr_error for each entry, but don't fail.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
		 * However, don't get any obj-dependent attrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
		sargp->rdattr_error = status;	/* for rdattr_error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
		*need_to_lookup = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
		 * At least get fileid for regular readdir output
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
		sargp->vap->va_mask &= AT_NODEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
		status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
 * readlink: args: CURRENT_FH.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
 *	res: status. If success - CURRENT_FH unchanged, return linktext.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
rfs4_op_readlink(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
	READLINK4res *resp = &resop->nfs_resop4_u.opreadlink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
	char *data;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3692
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3693
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3695
	DTRACE_NFSV4_1(op__readlink__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3696
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
	/* CURRENT_FH: directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
	vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3701
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3706
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
	if (vp->v_type == VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
		*cs->statusp = resp->status = NFS4ERR_ISDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3711
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
	if (vp->v_type != VLNK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3716
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
	va.va_mask = AT_MODE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3720
	error = VOP_GETATTR(vp, &va, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3723
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
	if (MANDLOCK(vp, va.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3728
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
	data = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
	iov.iov_base = data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
	iov.iov_len = MAXPATHLEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
	uio.uio_loffset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
	uio.uio_resid = MAXPATHLEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3742
	error = VOP_READLINK(vp, &uio, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
		kmem_free((caddr_t)data, (uint_t)MAXPATHLEN + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3747
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3749
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
	*(data + MAXPATHLEN - uio.uio_resid) = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3752
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3753
	name = nfscmd_convname(ca, cs->exi, data, NFSCMD_CONV_OUTBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3754
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3755
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3756
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3757
		/*
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3758
		 * Even though the conversion failed, we return
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3759
		 * something. We just don't translate it.
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3760
		 */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3761
		name = data;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3762
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3763
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
	 * treat link name as data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
	 */
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3767
	(void) str_to_utf8(name, &resp->link);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3768
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3769
	if (name != data)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3770
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
	kmem_free((caddr_t)data, (uint_t)MAXPATHLEN + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3773
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3774
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3775
	DTRACE_NFSV4_2(op__readlink__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3776
	    READLINK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
rfs4_op_readlink_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
	READLINK4res *resp = &resop->nfs_resop4_u.opreadlink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
	utf8string *symlink = &resp->link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
	if (symlink->utf8string_val) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
		UTF8STRING_FREE(*symlink)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
 * release_lockowner:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
 *	Release any state associated with the supplied
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
 *	lockowner. Note if any lo_state is holding locks we will not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
 *	rele that lo_state and thus the lockowner will not be destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
 *	A client using lock after the lock owner stateid has been released
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
 *	will suffer the consequence of NFS4ERR_BAD_STATEID and would have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
 *	to reissue the lock with new_lock_owner set to TRUE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
 *	args: lock_owner
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
 *	res:  status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3801
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
rfs4_op_release_lockowner(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
	struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
	RELEASE_LOCKOWNER4args *ap = &argop->nfs_argop4_u.oprelease_lockowner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
	RELEASE_LOCKOWNER4res *resp = &resop->nfs_resop4_u.oprelease_lockowner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
	rfs4_lockowner_t *lo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
	rfs4_openowner_t *oop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
	rfs4_state_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
	rfs4_lo_state_t *lsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
	bool_t create = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
	locklist_t *llist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
	sysid_t sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3817
	DTRACE_NFSV4_2(op__release__lockowner__start, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3818
	    cs, RELEASE_LOCKOWNER4args *, ap);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3819
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
	/* Make sure there is a clientid around for this request */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
	cp = rfs4_findclient_by_id(ap->lock_owner.clientid, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
	if (cp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  3825
		    rfs4_check_clientid(&ap->lock_owner.clientid, 0);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3826
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
	rfs4_client_rele(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
	lo = rfs4_findlockowner(&ap->lock_owner, &create);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
	if (lo == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
		*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3833
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
	ASSERT(lo->client != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
	 * Check for EXPIRED client. If so will reap state with in a lease
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
	 * period or on next set_clientid_confirm step
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
	if (rfs4_lease_expired(lo->client)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
		rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3844
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
	 * If no sysid has been assigned, then no locks exist; just return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
	rfs4_dbe_lock(lo->client->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
	if (lo->client->sysidt == LM_NOSYSID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
		rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
		rfs4_dbe_unlock(lo->client->dbe);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3854
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3856
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3857
	sysid = lo->client->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
	rfs4_dbe_unlock(lo->client->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
	 * Mark the lockowner invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
	rfs4_dbe_hide(lo->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
	 * sysid-pid pair should now not be used since the lockowner is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
	 * invalid. If the client were to instantiate the lockowner again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
	 * it would be assigned a new pid. Thus we can get the list of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
	 * current locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
	llist = flk_get_active_locks(sysid, lo->pid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	/* If we are still holding locks fail */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
	if (llist != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
		*cs->statusp = resp->status = NFS4ERR_LOCKS_HELD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
		flk_free_locklist(llist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
		 * We need to unhide the lockowner so the client can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
		 * try it again. The bad thing here is if the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
		 * has a logic error that took it here in the first place
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
		 * he probably has lost accounting of the locks that it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
		 * is holding. So we may have dangling state until the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
		 * open owner state is reaped via close. One scenario
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
		 * that could possibly occur is that the client has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
		 * sent the unlock request(s) in separate threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
		 * and has not waited for the replies before sending the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
		 * RELEASE_LOCKOWNER request. Presumably, it would expect
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
		 * and deal appropriately with NFS4ERR_LOCKS_HELD, by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
		 * reissuing the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
		rfs4_dbe_unhide(lo->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
		rfs4_lockowner_rele(lo);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3895
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3898
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3899
	 * For the corresponding client we need to check each open
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3900
	 * owner for any opens that have lockowner state associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3901
	 * with this lockowner.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3902
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3903
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3904
	rfs4_dbe_lock(lo->client->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3905
	for (oop = lo->client->openownerlist.next->oop; oop != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3906
	    oop = oop->openownerlist.next->oop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
		rfs4_dbe_lock(oop->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
		for (sp = oop->ownerstateids.next->sp; sp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
		    sp = sp->ownerstateids.next->sp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
			rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
			for (lsp = sp->lockownerlist.next->lsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
			    lsp != NULL; lsp = lsp->lockownerlist.next->lsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
				if (lsp->locker == lo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
					rfs4_dbe_lock(lsp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
					rfs4_dbe_invalidate(lsp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
					rfs4_dbe_unlock(lsp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
			rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
		rfs4_dbe_unlock(oop->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
	rfs4_dbe_unlock(lo->client->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
	rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3930
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3931
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3932
	DTRACE_NFSV4_2(op__release__lockowner__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3933
	    cs, RELEASE_LOCKOWNER4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
 * short utility function to lookup a file and recall the delegation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
static rfs4_file_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
rfs4_lookup_and_findfile(vnode_t *dvp, char *nm, vnode_t **vpp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
	int *lkup_error, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
	rfs4_file_t *fp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
	bool_t fcreate = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
	if (vpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
		*vpp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3951
	if ((error = VOP_LOOKUP(dvp, nm, &vp, NULL, 0, NULL, cr, NULL, NULL,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  3952
	    NULL)) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
		if (vp->v_type == VREG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
			fp = rfs4_findfile(vp, NULL, &fcreate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
		if (vpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
			*vpp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
	if (lkup_error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
		*lkup_error = error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
	return (fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
 * remove: args: CURRENT_FH: directory; name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
 *	res: status. If success - CURRENT_FH unchanged, return change_info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
 *		for directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
rfs4_op_remove(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
	REMOVE4args *args = &argop->nfs_argop4_u.opremove;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
	REMOVE4res *resp = &resop->nfs_resop4_u.opremove;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
	vnode_t *dvp, *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
	struct vattr bdva, idva, adva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
	char *nm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
	uint_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
	rfs4_file_t *fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
	int in_crit = 0;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  3986
	bslabel_t *clabel;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3987
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  3988
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3990
	DTRACE_NFSV4_2(op__remove__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3991
	    REMOVE4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3992
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
	/* CURRENT_FH: directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
	dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  3997
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4002
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
	 * Do not allow to remove anything in this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4008
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4009
	if (vn_ismntpt(dvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4010
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4011
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
	if (dvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4016
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4018
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4019
	if (!utf8_dir_verify(&args->target)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4020
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4021
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
	 * Lookup the file so that we can check if it's a directory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
	nm = utf8_to_fn(&args->target, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4029
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4030
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4036
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4037
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4039
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4040
		*cs->statusp = resp->status = NFS4ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4042
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4045
	/* If necessary, convert to UTF-8 for illbehaved clients */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4046
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4047
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4048
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4049
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4050
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4051
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4052
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4053
		kmem_free(nm, len);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4054
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4055
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4056
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4057
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4058
	 * Lookup the file to determine type and while we are see if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4059
	 * there is a file struct around and check for delegation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
	 * We don't need to acquire va_seq before this lookup, if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
	 * it causes an update, cinfo.before will not match, which will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
	 * trigger a cache flush even if atomic is TRUE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
	 */
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4064
	if (fp = rfs4_lookup_and_findfile(dvp, name, &vp, &error, cs->cr)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
		if (rfs4_check_delegated_byfp(FWRITE, fp, TRUE, TRUE, TRUE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4066
		    NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
			rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
			*cs->statusp = resp->status = NFS4ERR_DELAY;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4070
			if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4071
				kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
			kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4073
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
	/* Didn't find anything to remove */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
		*cs->statusp = resp->status = error;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4080
		if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4081
			kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
		kmem_free(nm, len);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4083
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
	if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
		nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
		in_crit = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4089
		if (nbl_conflict(vp, NBL_REMOVE, 0, 0, 0, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
			*cs->statusp = resp->status = NFS4ERR_FILE_OPEN;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4091
			if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4092
				kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
			kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
			if (fp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
				rfs4_clear_dont_grant(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
				rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
			}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4100
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4104
	/* check label before allowing removal */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4105
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4106
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4107
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4108
		DTRACE_PROBE2(tx__rfs4__log__info__opremove__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4109
		    "got client label from request(1)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4110
		    struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4111
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  4112
			if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK)) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4113
				*cs->statusp = resp->status = NFS4ERR_ACCESS;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4114
				if (name != nm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4115
					kmem_free(name, MAXPATHLEN + 1);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4116
				kmem_free(nm, len);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4117
				if (in_crit)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4118
					nbl_end_crit(vp);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4119
				VN_RELE(vp);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4120
				if (fp) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4121
					rfs4_clear_dont_grant(fp);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4122
					rfs4_file_rele(fp);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4123
				}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4124
				goto out;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4125
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4126
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4127
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4128
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
	/* Get dir "before" change value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
	bdva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4131
	error = VOP_GETATTR(dvp, &bdva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
		*cs->statusp = resp->status = puterrno4(error);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4134
		if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4135
			kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
		kmem_free(nm, len);
8869
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4137
		if (in_crit)
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4138
			nbl_end_crit(vp);
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4139
		VN_RELE(vp);
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4140
		if (fp) {
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4141
			rfs4_clear_dont_grant(fp);
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4142
			rfs4_file_rele(fp);
ebed8468e988 6806417 missing VN_RELE in rfs4_op_remove
James Wahlig <James.Wahlig@Sun.COM>
parents: 8662
diff changeset
  4143
		}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4144
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.before, bdva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
	/* Actually do the REMOVE operation */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
	if (vp->v_type == VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
		 * Can't remove a directory that has a mounted-on filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
		if (vn_ismntpt(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
			error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
			 * System V defines rmdir to return EEXIST,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
			 * not * ENOTEMPTY, if the directory is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
			 * empty.  A System V NFS server needs to map
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
			 * NFS4ERR_EXIST to NFS4ERR_NOTEMPTY to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
			 * transmit over the wire.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
			 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4163
			if ((error = VOP_RMDIR(dvp, nm, rootdir, cs->cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4164
			    NULL, 0)) == EEXIST)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
				error = ENOTEMPTY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
	} else {
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4168
		if ((error = VOP_REMOVE(dvp, name, cs->cr, NULL, 0)) == 0 &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4169
		    fp != NULL) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
			struct vattr va;
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4171
			vnode_t *tvp;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4172
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4173
			rfs4_dbe_lock(fp->dbe);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4174
			tvp = fp->vp;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4175
			if (tvp)
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4176
				VN_HOLD(tvp);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4177
			rfs4_dbe_unlock(fp->dbe);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4178
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4179
			if (tvp) {
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4180
				/*
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4181
				 * This is va_seq safe because we are not
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4182
				 * manipulating dvp.
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4183
				 */
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4184
				va.va_mask = AT_NLINK;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4185
				if (!VOP_GETATTR(tvp, &va, 0, cs->cr, NULL) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4186
				    va.va_nlink == 0) {
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4187
					/* Remove state on file remove */
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4188
					if (in_crit) {
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4189
						nbl_end_crit(vp);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4190
						in_crit = 0;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4191
					}
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4192
					rfs4_close_all_state(fp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4193
				}
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4194
				VN_RELE(tvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4195
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4196
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4199
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4200
		nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4201
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4203
	if (fp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4204
		rfs4_clear_dont_grant(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4205
		rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4206
	}
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4207
	if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4208
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4209
	kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4210
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4211
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4212
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4213
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4214
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4216
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4217
	 * Get the initial "after" sequence number, if it fails, set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4218
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4219
	idva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4220
	if (VOP_GETATTR(dvp, &idva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4221
		idva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4223
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4224
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4225
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4226
	(void) VOP_FSYNC(dvp, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4228
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4229
	 * Get "after" change value, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4230
	 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4231
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
	adva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4233
	if (VOP_GETATTR(dvp, &adva, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
		adva.va_ctime = bdva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
		adva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
	NFS4_SET_FATTR4_CHANGE(resp->cinfo.after, adva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
	 * The cinfo.atomic = TRUE only if we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
	 * non-zero va_seq's, and it has incremented by exactly one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
	 * during the VOP_REMOVE/RMDIR and it didn't change during
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
	 * the VOP_FSYNC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
	if (bdva.va_seq && idva.va_seq && adva.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4247
	    idva.va_seq == (bdva.va_seq + 1) && idva.va_seq == adva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
		resp->cinfo.atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
		resp->cinfo.atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4253
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4254
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4255
	DTRACE_NFSV4_2(op__remove__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4256
	    REMOVE4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4260
 * rename: args: SAVED_FH: from directory, CURRENT_FH: target directory,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
 *		oldname and newname.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4262
 *	res: status. If success - CURRENT_FH unchanged, return change_info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4263
 *		for both from and target directories.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4264
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4265
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4266
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4267
rfs4_op_rename(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4268
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4269
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4270
	RENAME4args *args = &argop->nfs_argop4_u.oprename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4271
	RENAME4res *resp = &resop->nfs_resop4_u.oprename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4272
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4273
	vnode_t *odvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4274
	vnode_t *ndvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4275
	vnode_t *srcvp, *targvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4276
	struct vattr obdva, oidva, oadva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4277
	struct vattr nbdva, nidva, nadva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4278
	char *onm, *nnm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4279
	uint_t olen, nlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4280
	rfs4_file_t *fp, *sfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4281
	int in_crit_src, in_crit_targ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4282
	int fp_rele_grant_hold, sfp_rele_grant_hold;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4283
	bslabel_t *clabel;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4284
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4285
	char *converted_onm = NULL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4286
	char *converted_nnm = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4287
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4288
	DTRACE_NFSV4_2(op__rename__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4289
	    RENAME4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4290
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4291
	fp = sfp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4292
	srcvp = targvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4293
	in_crit_src = in_crit_targ = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4294
	fp_rele_grant_hold = sfp_rele_grant_hold = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4296
	/* CURRENT_FH: target directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4297
	ndvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4298
	if (ndvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4299
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4300
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4301
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4303
	/* SAVED_FH: from directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4304
	odvp = cs->saved_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4305
	if (odvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4306
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4307
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4308
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4310
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4311
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4312
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4313
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4315
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4316
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4317
	 * do not allow to rename objects in this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4318
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4319
	if (vn_ismntpt(odvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4320
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4321
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4322
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4324
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4325
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
	 * do not allow to rename to this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
	if (vn_ismntpt(ndvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4330
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
	if (odvp->v_type != VDIR || ndvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
		*cs->statusp = resp->status = NFS4ERR_NOTDIR;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4335
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
	if (cs->saved_exi != cs->exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
		*cs->statusp = resp->status = NFS4ERR_XDEV;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4340
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
	if (!utf8_dir_verify(&args->oldname)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4344
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4345
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
	if (!utf8_dir_verify(&args->newname)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4349
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4350
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4353
	onm = utf8_to_fn(&args->oldname, &olen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4354
	if (onm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4356
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
	}
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4358
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4359
	nlen = MAXPATHLEN + 1;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4360
	converted_onm = nfscmd_convname(ca, cs->exi, onm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4361
	    nlen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4362
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4363
	if (converted_onm == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4364
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4365
		kmem_free(onm, olen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4366
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4367
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
	nnm = utf8_to_fn(&args->newname, &nlen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4370
	if (nnm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4371
		*cs->statusp = resp->status = NFS4ERR_INVAL;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4372
		if (onm != converted_onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4373
			kmem_free(converted_onm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4374
		kmem_free(onm, olen);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4375
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4376
	}
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4377
	converted_nnm = nfscmd_convname(ca, cs->exi, nnm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4378
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4379
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4380
	if (converted_nnm == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4381
		*cs->statusp = resp->status = NFS4ERR_INVAL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4382
		kmem_free(nnm, nlen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4383
		nnm = NULL;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4384
		if (onm != converted_onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4385
			kmem_free(converted_onm, MAXPATHLEN + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4386
		kmem_free(onm, olen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4387
		goto out;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4388
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4389
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4391
	if (olen > MAXNAMELEN || nlen > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4392
		*cs->statusp = resp->status = NFS4ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4393
		kmem_free(onm, olen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
		kmem_free(nnm, nlen);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4395
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
		*cs->statusp = resp->status = NFS4ERR_ROFS;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4401
		if (onm != converted_onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4402
			kmem_free(converted_onm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
		kmem_free(onm, olen);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4404
		if (nnm != converted_nnm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4405
			kmem_free(converted_nnm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
		kmem_free(nnm, nlen);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4407
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4410
	/* check label of the target dir */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4411
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4412
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4413
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4414
		DTRACE_PROBE2(tx__rfs4__log__info__oprename__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4415
		    "got client label from request(1)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4416
		    struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4417
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  4418
			if (!do_rfs_label_check(clabel, ndvp,
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4419
			    EQUALITY_CHECK)) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4420
				*cs->statusp = resp->status = NFS4ERR_ACCESS;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4421
				goto err_out;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4422
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4423
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4424
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  4425
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
	 * Is the source a file and have a delegation?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
	 * We don't need to acquire va_seq before these lookups, if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
	 * it causes an update, cinfo.before will not match, which will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
	 * trigger a cache flush even if atomic is TRUE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
	 */
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4432
	if (sfp = rfs4_lookup_and_findfile(odvp, converted_onm, &srcvp,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4433
	    &error, cs->cr)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
		if (rfs4_check_delegated_byfp(FWRITE, sfp, TRUE, TRUE, TRUE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4435
		    NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4436
			*cs->statusp = resp->status = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
			goto err_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4439
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4441
	if (srcvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4442
		*cs->statusp = resp->status = puterrno4(error);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4443
		if (onm != converted_onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4444
			kmem_free(converted_onm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
		kmem_free(onm, olen);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4446
		if (nnm != converted_nnm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4447
			kmem_free(converted_onm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
		kmem_free(nnm, nlen);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4449
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
	sfp_rele_grant_hold = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
	/* Does the destination exist and a file and have a delegation? */
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4455
	if (fp = rfs4_lookup_and_findfile(ndvp, converted_nnm, &targvp,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4456
	    NULL, cs->cr)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
		if (rfs4_check_delegated_byfp(FWRITE, fp, TRUE, TRUE, TRUE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4458
		    NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
			*cs->statusp = resp->status = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
			goto err_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4463
	fp_rele_grant_hold = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4466
	/* Check for NBMAND lock on both source and target */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4467
	if (nbl_need_check(srcvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4468
		nbl_start_crit(srcvp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4469
		in_crit_src = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4470
		if (nbl_conflict(srcvp, NBL_RENAME, 0, 0, 0, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
			*cs->statusp = resp->status = NFS4ERR_FILE_OPEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4472
			goto err_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4476
	if (targvp && nbl_need_check(targvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4477
		nbl_start_crit(targvp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4478
		in_crit_targ = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4479
		if (nbl_conflict(targvp, NBL_REMOVE, 0, 0, 0, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4480
			*cs->statusp = resp->status = NFS4ERR_FILE_OPEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4481
			goto err_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4482
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4483
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4485
	/* Get source "before" change value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4486
	obdva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4487
	error = VOP_GETATTR(odvp, &obdva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4488
	if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4489
		nbdva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4490
		error = VOP_GETATTR(ndvp, &nbdva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4491
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4492
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4493
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4494
		goto err_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4495
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4496
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4497
	NFS4_SET_FATTR4_CHANGE(resp->source_cinfo.before, obdva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4498
	NFS4_SET_FATTR4_CHANGE(resp->target_cinfo.before, nbdva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4499
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4500
	if ((error = VOP_RENAME(odvp, converted_onm, ndvp, converted_nnm,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4501
	    cs->cr, NULL, 0)) == 0 && fp != NULL) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4502
		struct vattr va;
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4503
		vnode_t *tvp;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4504
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4505
		rfs4_dbe_lock(fp->dbe);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4506
		tvp = fp->vp;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4507
		if (tvp)
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4508
			VN_HOLD(tvp);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4509
		rfs4_dbe_unlock(fp->dbe);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4510
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4511
		if (tvp) {
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4512
			va.va_mask = AT_NLINK;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4513
			if (!VOP_GETATTR(tvp, &va, 0, cs->cr, NULL) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4514
			    va.va_nlink == 0) {
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4515
				/* The file is gone and so should the state */
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4516
				if (in_crit_targ) {
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4517
					nbl_end_crit(targvp);
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4518
					in_crit_targ = 0;
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4519
				}
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4520
				rfs4_close_all_state(fp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4521
			}
154
7a745d3804a2 6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
shepler
parents: 0
diff changeset
  4522
			VN_RELE(tvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4523
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4524
	}
6976
cae5f06df471 PSARC 2008/388 Short circuit for vdev probe failure
eschrock
parents: 6786
diff changeset
  4525
	if (error == 0)
cae5f06df471 PSARC 2008/388 Short circuit for vdev probe failure
eschrock
parents: 6786
diff changeset
  4526
		vn_renamepath(ndvp, srcvp, nnm, nlen - 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4528
	if (in_crit_src)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4529
		nbl_end_crit(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4530
	if (srcvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4531
		VN_RELE(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4532
	if (in_crit_targ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4533
		nbl_end_crit(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4534
	if (targvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4535
		VN_RELE(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4537
	if (sfp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4538
		rfs4_clear_dont_grant(sfp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4539
		rfs4_file_rele(sfp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4540
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4541
	if (fp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4542
		rfs4_clear_dont_grant(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4543
		rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4544
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4545
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4546
	if (converted_onm != onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4547
		kmem_free(converted_onm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4548
	kmem_free(onm, olen);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4549
	if (converted_nnm != nnm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4550
		kmem_free(converted_nnm, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4551
	kmem_free(nnm, nlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4552
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4553
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4554
	 * Get the initial "after" sequence number, if it fails, set to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4555
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4556
	oidva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4557
	if (VOP_GETATTR(odvp, &oidva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
		oidva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4560
	nidva.va_mask = AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4561
	if (VOP_GETATTR(ndvp, &nidva, 0, cs->cr, NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
		nidva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4566
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4567
	(void) VOP_FSYNC(odvp, 0, cs->cr, NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4568
	(void) VOP_FSYNC(ndvp, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4570
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4571
		*cs->statusp = resp->status = puterrno4(error);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4572
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4575
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4576
	 * Get "after" change values, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4577
	 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4578
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4579
	oadva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4580
	if (VOP_GETATTR(odvp, &oadva, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4581
		oadva.va_ctime = obdva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4582
		oadva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4583
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4585
	nadva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4586
	if (VOP_GETATTR(odvp, &nadva, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4587
		nadva.va_ctime = nbdva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4588
		nadva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4589
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4591
	NFS4_SET_FATTR4_CHANGE(resp->source_cinfo.after, oadva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4592
	NFS4_SET_FATTR4_CHANGE(resp->target_cinfo.after, nadva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4594
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4595
	 * The cinfo.atomic = TRUE only if we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4596
	 * non-zero va_seq's, and it has incremented by exactly one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4597
	 * during the VOP_RENAME and it didn't change during the VOP_FSYNC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4598
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4599
	if (obdva.va_seq && oidva.va_seq && oadva.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4600
	    oidva.va_seq == (obdva.va_seq + 1) && oidva.va_seq == oadva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4601
		resp->source_cinfo.atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4602
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4603
		resp->source_cinfo.atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4605
	if (nbdva.va_seq && nidva.va_seq && nadva.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4606
	    nidva.va_seq == (nbdva.va_seq + 1) && nidva.va_seq == nadva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4607
		resp->target_cinfo.atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4608
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4609
		resp->target_cinfo.atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4611
#ifdef	VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4612
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4613
	extern void add_volrnm_fh(struct exportinfo *, vnode_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4615
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4616
	 * Add the renamed file handle to the volatile rename list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4617
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4618
	if (cs->exi->exi_export.ex_flags & EX_VOLRNM) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4619
		/* file handles may expire on rename */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4620
		vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4622
		nnm = utf8_to_fn(&args->newname, &nlen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4623
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4624
		 * Already know that nnm will be a valid string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4625
		 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4626
		error = VOP_LOOKUP(ndvp, nnm, &vp, NULL, 0, NULL, cs->cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4627
		    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4628
		kmem_free(nnm, nlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4629
		if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4630
			add_volrnm_fh(cs->exi, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4631
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4632
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4633
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4634
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4635
#endif	/* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4637
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4638
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4639
	DTRACE_NFSV4_2(op__rename__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4640
	    RENAME4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4641
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4643
err_out:
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4644
	if (onm != converted_onm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4645
		kmem_free(converted_onm, MAXPATHLEN + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4646
	if (onm != NULL)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4647
		kmem_free(onm, olen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4648
	if (nnm != converted_nnm)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4649
		kmem_free(converted_nnm, MAXPATHLEN + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4650
	if (nnm != NULL)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  4651
		kmem_free(nnm, nlen);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4652
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4653
	if (in_crit_src) nbl_end_crit(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4654
	if (in_crit_targ) nbl_end_crit(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4655
	if (targvp) VN_RELE(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4656
	if (srcvp) VN_RELE(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4657
	if (sfp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4658
		if (sfp_rele_grant_hold) rfs4_clear_dont_grant(sfp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4659
		rfs4_file_rele(sfp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4660
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4661
	if (fp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4662
		if (fp_rele_grant_hold) rfs4_clear_dont_grant(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4663
		rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4664
	}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4665
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4666
	DTRACE_NFSV4_2(op__rename__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4667
	    RENAME4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4668
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4670
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4671
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4672
rfs4_op_renew(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4673
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4674
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4675
	RENEW4args *args = &argop->nfs_argop4_u.oprenew;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4676
	RENEW4res *resp = &resop->nfs_resop4_u.oprenew;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4677
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4678
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4679
	DTRACE_NFSV4_2(op__renew__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4680
	    RENEW4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4681
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4682
	if ((cp = rfs4_findclient_by_id(args->clientid, FALSE)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4683
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4684
		    rfs4_check_clientid(&args->clientid, 0);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4685
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4686
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4688
	if (rfs4_lease_expired(cp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4689
		rfs4_client_rele(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4690
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4691
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4692
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4694
	rfs4_update_lease(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4696
	mutex_enter(cp->cbinfo.cb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4697
	if (cp->cbinfo.cb_notified_of_cb_path_down == FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4698
		cp->cbinfo.cb_notified_of_cb_path_down = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4699
		*cs->statusp = resp->status = NFS4ERR_CB_PATH_DOWN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4700
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4701
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4702
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4703
	mutex_exit(cp->cbinfo.cb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4705
	rfs4_client_rele(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4706
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4707
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4708
	DTRACE_NFSV4_2(op__renew__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4709
	    RENEW4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4710
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4712
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4713
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4714
rfs4_op_restorefh(nfs_argop4 *args, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4715
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4716
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4717
	RESTOREFH4res *resp = &resop->nfs_resop4_u.oprestorefh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4718
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4719
	DTRACE_NFSV4_1(op__restorefh__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4720
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4721
	/* No need to check cs->access - we are not accessing any object */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4722
	if ((cs->saved_vp == NULL) || (cs->saved_fh.nfs_fh4_val == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4723
		*cs->statusp = resp->status = NFS4ERR_RESTOREFH;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4724
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4725
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4726
	if (cs->vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4727
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4728
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4729
	cs->vp = cs->saved_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4730
	cs->saved_vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4731
	cs->exi = cs->saved_exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4732
	nfs_fh4_copy(&cs->saved_fh, &cs->fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4733
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4734
	cs->deleg = FALSE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4735
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4736
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4737
	DTRACE_NFSV4_2(op__restorefh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4738
	    RESTOREFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4739
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4741
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4742
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4743
rfs4_op_savefh(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4744
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4745
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4746
	SAVEFH4res *resp = &resop->nfs_resop4_u.opsavefh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4747
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4748
	DTRACE_NFSV4_1(op__savefh__start, struct compound_state *, cs);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4749
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4750
	/* No need to check cs->access - we are not accessing any object */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4751
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4752
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4753
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4754
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4755
	if (cs->saved_vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4756
		VN_RELE(cs->saved_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4757
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4758
	cs->saved_vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4759
	VN_HOLD(cs->saved_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4760
	cs->saved_exi = cs->exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4761
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4762
	 * since SAVEFH is fairly rare, don't alloc space for its fh
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4763
	 * unless necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4764
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4765
	if (cs->saved_fh.nfs_fh4_val == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4766
		cs->saved_fh.nfs_fh4_val = kmem_alloc(NFS4_FHSIZE, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4767
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4768
	nfs_fh4_copy(&cs->fh, &cs->saved_fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4769
	*cs->statusp = resp->status = NFS4_OK;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4770
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4771
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4772
	DTRACE_NFSV4_2(op__savefh__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  4773
	    SAVEFH4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4774
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4776
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4777
 * rfs4_verify_attr is called when nfsv4 Setattr failed, but we wish to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4778
 * return the bitmap of attrs that were set successfully. It is also
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4779
 * called by Verify/Nverify to test the vattr/vfsstat attrs. It should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4780
 * always be called only after rfs4_do_set_attrs().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4781
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4782
 * Verify that the attributes are same as the expected ones. sargp->vap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4783
 * and sargp->sbp contain the input attributes as translated from fattr4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4784
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4785
 * This function verifies only the attrs that correspond to a vattr or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4786
 * vfsstat struct. That is because of the extra step needed to get the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4787
 * corresponding system structs. Other attributes have already been set or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4788
 * verified by do_rfs4_set_attrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4789
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4790
 * Return 0 if all attrs match, -1 if some don't, error if error processing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4791
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4792
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4793
rfs4_verify_attr(struct nfs4_svgetit_arg *sargp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4794
	bitmap4 *resp, struct nfs4_ntov_table *ntovp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4795
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4796
	int error, ret_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4797
	int i, k;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4798
	uint_t sva_mask = sargp->vap->va_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4799
	uint_t vbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4800
	union nfs4_attr_u *na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4801
	uint8_t *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4802
	bool_t getsb = ntovp->vfsstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4804
	if (sva_mask != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4805
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4806
		 * Okay to overwrite sargp->vap because we verify based
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4807
		 * on the incoming values.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4808
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4809
		ret_error = VOP_GETATTR(sargp->cs->vp, sargp->vap, 0,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  4810
		    sargp->cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4811
		if (ret_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4812
			if (resp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4813
				return (ret_error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4814
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4815
			 * Must return bitmap of successful attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4816
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4817
			sva_mask = 0;	/* to prevent checking vap later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4818
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4819
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4820
			 * Some file systems clobber va_mask. it is probably
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4821
			 * wrong of them to do so, nonethless we practice
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4822
			 * defensive coding.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4823
			 * See bug id 4276830.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4824
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4825
			sargp->vap->va_mask = sva_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4826
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4827
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4829
	if (getsb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4830
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4831
		 * Now get the superblock and loop on the bitmap, as there is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4832
		 * no simple way of translating from superblock to bitmap4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4833
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4834
		ret_error = VFS_STATVFS(sargp->cs->vp->v_vfsp, sargp->sbp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4835
		if (ret_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4836
			if (resp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4837
				goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4838
			getsb = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4839
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4840
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4842
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4843
	 * Now loop and verify each attribute which getattr returned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4844
	 * whether it's the same as the input.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4845
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4846
	if (resp == NULL && !getsb && (sva_mask == 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4847
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4848
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4849
	na = ntovp->na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4850
	amap = ntovp->amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4851
	k = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4852
	for (i = 0; i < ntovp->attrcnt; i++, na++, amap++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4853
		k = *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4854
		ASSERT(nfs4_ntov_map[k].nval == k);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4855
		vbit = nfs4_ntov_map[k].vbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4856
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4857
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4858
		 * If vattr attribute but VOP_GETATTR failed, or it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4859
		 * superblock attribute but VFS_STATVFS failed, skip
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4860
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4861
		if (vbit) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4862
			if ((vbit & sva_mask) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4863
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4864
		} else if (!(getsb && nfs4_ntov_map[k].vfsstat)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4865
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4866
		}
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4867
		error = (*nfs4_ntov_map[k].sv_getit)(NFS4ATTR_VERIT, sargp, na);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4868
		if (resp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4869
			if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4870
				ret_error = -1;	/* not all match */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4871
			else	/* update response bitmap */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4872
				*resp |= nfs4_ntov_map[k].fbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4873
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4874
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4875
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4876
			ret_error = -1;	/* not all match */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4877
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4878
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4879
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4880
errout:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4881
	return (ret_error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4882
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4884
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4885
 * Decode the attribute to be set/verified. If the attr requires a sys op
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4886
 * (VOP_GETATTR, VFS_VFSSTAT), and the request is to verify, then don't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4887
 * call the sv_getit function for it, because the sys op hasn't yet been done.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4888
 * Return 0 for success, error code if failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4889
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4890
 * Note: the decoded arg is not freed here but in nfs4_ntov_table_free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4891
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4892
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4893
decode_fattr4_attr(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sargp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4894
	int k, XDR *xdrp, bitmap4 *resp_bval, union nfs4_attr_u *nap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4895
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4896
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4897
	bool_t set_later;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4899
	sargp->vap->va_mask |= nfs4_ntov_map[k].vbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4901
	if ((*nfs4_ntov_map[k].xfunc)(xdrp, nap)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4902
		set_later = nfs4_ntov_map[k].vbit || nfs4_ntov_map[k].vfsstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4903
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4904
		 * don't verify yet if a vattr or sb dependent attr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4905
		 * because we don't have their sys values yet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4906
		 * Will be done later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4907
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4908
		if (! (set_later && (cmd == NFS4ATTR_VERIT))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4909
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4910
			 * ACLs are a special case, since setting the MODE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4911
			 * conflicts with setting the ACL.  We delay setting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4912
			 * the ACL until all other attributes have been set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4913
			 * The ACL gets set in do_rfs4_op_setattr().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4914
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4915
			if (nfs4_ntov_map[k].fbit != FATTR4_ACL_MASK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4916
				error = (*nfs4_ntov_map[k].sv_getit)(cmd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4917
				    sargp, nap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4918
				if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4919
					xdr_free(nfs4_ntov_map[k].xfunc,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4920
					    (caddr_t)nap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4921
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4922
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4923
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4924
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4925
#ifdef  DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4926
		cmn_err(CE_NOTE, "decode_fattr4_attr: error "
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  4927
		    "decoding attribute %d\n", k);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4928
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4929
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4930
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4931
	if (!error && resp_bval && !set_later) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4932
		*resp_bval |= nfs4_ntov_map[k].fbit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4933
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4934
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4935
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4936
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4937
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4938
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4939
 * Set vattr based on incoming fattr4 attrs - used by setattr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4940
 * Set response mask. Ignore any values that are not writable vattr attrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4941
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4942
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4943
do_rfs4_set_attrs(bitmap4 *resp, fattr4 *fattrp, struct compound_state *cs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4944
		struct nfs4_svgetit_arg *sargp, struct nfs4_ntov_table *ntovp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4945
		nfs4_attr_cmd_t cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4946
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4947
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4948
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4949
	char *attrs = fattrp->attrlist4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4950
	uint32_t attrslen = fattrp->attrlist4_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4951
	XDR xdr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4952
	nfsstat4 status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4953
	vnode_t *vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4954
	union nfs4_attr_u *na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4955
	uint8_t *amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4957
#ifndef lint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4958
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4959
	 * Make sure that maximum attribute number can be expressed as an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4960
	 * 8 bit quantity.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4961
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4962
	ASSERT(NFS4_MAXNUM_ATTRS <= (UINT8_MAX + 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4963
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4965
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4966
		if (resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4967
			*resp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4968
		return (NFS4ERR_NOFILEHANDLE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4969
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4970
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4971
		if (resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4972
			*resp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4973
		return (NFS4ERR_ACCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4974
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4976
	sargp->op = cmd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4977
	sargp->cs = cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4978
	sargp->flag = 0;	/* may be set later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4979
	sargp->vap->va_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4980
	sargp->rdattr_error = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4981
	sargp->rdattr_error_req = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4982
	/* sargp->sbp is set by the caller */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4983
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4984
	xdrmem_create(&xdr, attrs, attrslen, XDR_DECODE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4986
	na = ntovp->na;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4987
	amap = ntovp->amap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4989
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4990
	 * The following loop iterates on the nfs4_ntov_map checking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4991
	 * if the fbit is set in the requested bitmap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4992
	 * If set then we process the arguments using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4993
	 * rfs4_fattr4 conversion functions to populate the setattr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4994
	 * vattr and va_mask. Any settable attrs that are not using vattr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4995
	 * will be set in this loop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4996
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4997
	for (i = 0; i < nfs4_ntov_map_size; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4998
		if (!(fattrp->attrmask & nfs4_ntov_map[i].fbit)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4999
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5000
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5001
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5002
		 * If setattr, must be a writable attr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5003
		 * If verify/nverify, must be a readable attr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5004
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5005
		if ((error = (*nfs4_ntov_map[i].sv_getit)(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5006
		    NFS4ATTR_SUPPORTED, sargp, NULL)) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5007
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5008
			 * Client tries to set/verify an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5009
			 * unsupported attribute, tries to set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5010
			 * a read only attr or verify a write
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5011
			 * only one - error!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5012
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5013
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5014
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5015
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5016
		 * Decode the attribute to set/verify
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5017
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5018
		error = decode_fattr4_attr(cmd, sargp, nfs4_ntov_map[i].nval,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5019
		    &xdr, resp ? resp : NULL, na);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5020
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5021
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5022
		*amap++ = (uint8_t)nfs4_ntov_map[i].nval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5023
		na++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5024
		(ntovp->attrcnt)++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5025
		if (nfs4_ntov_map[i].vfsstat)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5026
			ntovp->vfsstat = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5027
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5028
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5029
	if (error != 0)
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5030
		status = (error == ENOTSUP ? NFS4ERR_ATTRNOTSUPP :
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5031
		    puterrno4(error));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5032
	/* xdrmem_destroy(&xdrs); */	/* NO-OP */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5033
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5034
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5036
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5037
do_rfs4_op_setattr(bitmap4 *resp, fattr4 *fattrp, struct compound_state *cs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5038
		stateid4 *stateid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5039
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5040
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5041
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5042
	bool_t trunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5043
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5044
	nfsstat4 status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5045
	cred_t *cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5046
	vnode_t *vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5047
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5048
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5049
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5050
	struct flock64 bf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5051
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5052
	uint_t saved_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5053
	caller_context_t ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5055
	*resp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5056
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5057
	nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5058
	status = do_rfs4_set_attrs(resp, fattrp, cs, &sarg, &ntov,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5059
	    NFS4ATTR_SETIT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5060
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5061
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5062
		 * failed set attrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5063
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5064
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5065
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5066
	if ((sarg.vap->va_mask == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5067
	    (! (fattrp->attrmask & FATTR4_ACL_MASK))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5068
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5069
		 * no further work to be done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5070
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5071
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5072
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5074
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5075
	 * If we got a request to set the ACL and the MODE, only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5076
	 * allow changing VSUID, VSGID, and VSVTX.  Attempting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5077
	 * to change any other bits, along with setting an ACL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5078
	 * gives NFS4ERR_INVAL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5079
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5080
	if ((fattrp->attrmask & FATTR4_ACL_MASK) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5081
	    (fattrp->attrmask & FATTR4_MODE_MASK)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5082
		vattr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5084
		va.va_mask = AT_MODE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5085
		error = VOP_GETATTR(vp, &va, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5086
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5087
			status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5088
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5089
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5090
		if ((sarg.vap->va_mode ^ va.va_mode) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5091
		    ~(VSUID | VSGID | VSVTX)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5092
			status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5093
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5094
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5095
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5097
	/* Check stateid only if size has been set */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5098
	if (sarg.vap->va_mask & AT_SIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5099
		trunc = (sarg.vap->va_size == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5100
		status = rfs4_check_stateid(FWRITE, cs->vp, stateid,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5101
		    trunc, &cs->deleg, sarg.vap->va_mask & AT_SIZE, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5102
		if (status != NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5103
			goto done;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5104
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5105
		ct.cc_sysid = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5106
		ct.cc_pid = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5107
		ct.cc_caller_id = nfs4_srv_caller_id;
5798
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5108
		ct.cc_flags = CC_DONTBLOCK;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5109
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5110
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5111
	/* XXX start of possible race with delegations */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5113
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5114
	 * We need to specially handle size changes because it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5115
	 * possible for the client to create a file with read-only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5116
	 * modes, but with the file opened for writing. If the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5117
	 * then tries to set the file size, e.g. ftruncate(3C),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5118
	 * fcntl(F_FREESP), the normal access checking done in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5119
	 * VOP_SETATTR would prevent the client from doing it even though
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5120
	 * it should be allowed to do so.  To get around this, we do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5121
	 * access checking for ourselves and use VOP_SPACE which doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5122
	 * do the access checking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5123
	 * Also the client should not be allowed to change the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5124
	 * size if there is a conflicting non-blocking mandatory lock in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5125
	 * the region of the change.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5126
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5127
	if (vp->v_type == VREG && (sarg.vap->va_mask & AT_SIZE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5128
		u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5129
		ssize_t length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5131
		/*
602
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5132
		 * ufs_setattr clears AT_SIZE from vap->va_mask, but
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5133
		 * before returning, sarg.vap->va_mask is used to
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5134
		 * generate the setattr reply bitmap.  We also clear
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5135
		 * AT_SIZE below before calling VOP_SPACE.  For both
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5136
		 * of these cases, the va_mask needs to be saved here
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5137
		 * and restored after calling VOP_SETATTR.
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5138
		 */
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5139
		saved_mask = sarg.vap->va_mask;
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5140
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5141
		/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5142
		 * Check any possible conflict due to NBMAND locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5143
		 * Get into critical region before VOP_GETATTR, so the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5144
		 * size attribute is valid when checking conflicts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5145
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5146
		if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5147
			nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5148
			in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5149
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5151
		bva.va_mask = AT_UID|AT_SIZE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5152
		if (error = VOP_GETATTR(vp, &bva, 0, cr, &ct)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5153
			status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5154
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5155
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5157
		if (in_crit) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5158
			if (sarg.vap->va_size < bva.va_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5159
				offset = sarg.vap->va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5160
				length = bva.va_size - sarg.vap->va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5161
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5162
				offset = bva.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5163
				length = sarg.vap->va_size - bva.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5164
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5165
			if (nbl_conflict(vp, NBL_WRITE, offset, length, 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5166
			    &ct)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5167
				status = NFS4ERR_LOCKED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5168
				goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5169
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5170
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5172
		if (crgetuid(cr) == bva.va_uid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5173
			sarg.vap->va_mask &= ~AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5174
			bf.l_type = F_WRLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5175
			bf.l_whence = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5176
			bf.l_start = (off64_t)sarg.vap->va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5177
			bf.l_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5178
			bf.l_sysid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5179
			bf.l_pid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5180
			error = VOP_SPACE(vp, F_FREESP, &bf, FWRITE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5181
			    (offset_t)sarg.vap->va_size, cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5182
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5183
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5185
	if (!error && sarg.vap->va_mask != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5186
		error = VOP_SETATTR(vp, sarg.vap, sarg.flag, cr, &ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5187
602
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5188
	/* restore va_mask -- ufs_setattr clears AT_SIZE */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5189
	if (saved_mask & AT_SIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5190
		sarg.vap->va_mask |= AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5191
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5192
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5193
	 * If an ACL was being set, it has been delayed until now,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5194
	 * in order to set the mode (via the VOP_SETATTR() above) first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5195
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5196
	if ((! error) && (fattrp->attrmask & FATTR4_ACL_MASK)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5197
		int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5199
		for (i = 0; i < NFS4_MAXNUM_ATTRS; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5200
			if (ntov.amap[i] == FATTR4_ACL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5201
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5202
		if (i < NFS4_MAXNUM_ATTRS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5203
			error = (*nfs4_ntov_map[FATTR4_ACL].sv_getit)(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5204
			    NFS4ATTR_SETIT, &sarg, &ntov.na[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5205
			if (error == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5206
				*resp |= FATTR4_ACL_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5207
			} else if (error == ENOTSUP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5208
				(void) rfs4_verify_attr(&sarg, resp, &ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5209
				status = NFS4ERR_ATTRNOTSUPP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5210
				goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5211
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5212
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5213
			NFS4_DEBUG(rfs4_debug,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5214
			    (CE_NOTE, "do_rfs4_op_setattr: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5215
			    "unable to find ACL in fattr4"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5216
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5217
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5218
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5220
	if (error) {
5798
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5221
		/* check if a monitor detected a delegation conflict */
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5222
		if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK))
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5223
			status = NFS4ERR_DELAY;
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5224
		else
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  5225
			status = puterrno4(error);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5227
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5228
		 * Set the response bitmap when setattr failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5229
		 * If VOP_SETATTR partially succeeded, test by doing a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5230
		 * VOP_GETATTR on the object and comparing the data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5231
		 * to the setattr arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5232
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5233
		(void) rfs4_verify_attr(&sarg, resp, &ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5234
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5235
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5236
		 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5237
		 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5238
		(void) VOP_FSYNC(vp, FNODSYNC, cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5239
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5240
		 * Set response bitmap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5241
		 */
602
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5242
		nfs4_vmask_to_nmask_set(sarg.vap->va_mask, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5243
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5245
/* Return early and already have a NFSv4 error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5246
done:
602
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5247
	/*
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5248
	 * Except for nfs4_vmask_to_nmask_set(), vattr --> fattr
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5249
	 * conversion sets both readable and writeable NFS4 attrs
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5250
	 * for AT_MTIME and AT_ATIME.  The line below masks out
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5251
	 * unrequested attrs from the setattr result bitmap.  This
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5252
	 * is placed after the done: label to catch the ATTRNOTSUP
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5253
	 * case.
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5254
	 */
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5255
	*resp &= fattrp->attrmask;
4ef537c7acd0 6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents: 254
diff changeset
  5256
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5257
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5258
		nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5259
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5260
	nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5262
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5263
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5265
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5266
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5267
rfs4_op_setattr(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5268
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5269
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5270
	SETATTR4args *args = &argop->nfs_argop4_u.opsetattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5271
	SETATTR4res *resp = &resop->nfs_resop4_u.opsetattr;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5272
	bslabel_t *clabel;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5273
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5274
	DTRACE_NFSV4_2(op__setattr__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5275
	    SETATTR4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5276
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5277
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5278
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5279
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5280
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5282
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5283
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5284
	 * do not allow to setattr on this vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5285
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5286
	if (vn_ismntpt(cs->vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5287
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5288
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5289
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5291
	resp->attrsset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5293
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5294
		*cs->statusp = resp->status = NFS4ERR_ROFS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5295
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5296
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5297
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5298
	/* check label before setting attributes */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5299
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5300
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5301
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5302
		DTRACE_PROBE2(tx__rfs4__log__info__opsetattr__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5303
		    "got client label from request(1)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5304
		    struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5305
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  5306
			if (!do_rfs_label_check(clabel, cs->vp,
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5307
			    EQUALITY_CHECK)) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5308
				*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5309
				goto out;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5310
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5311
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5312
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5313
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5314
	*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5315
	    do_rfs4_op_setattr(&resp->attrsset, &args->obj_attributes, cs,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5316
	    &args->stateid);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5317
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5318
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5319
	DTRACE_NFSV4_2(op__setattr__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5320
	    SETATTR4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5321
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5323
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5324
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5325
rfs4_op_verify(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5326
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5327
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5328
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5329
	 * verify and nverify are exactly the same, except that nverify
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5330
	 * succeeds when some argument changed, and verify succeeds when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5331
	 * when none changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5332
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5334
	VERIFY4args  *args = &argop->nfs_argop4_u.opverify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5335
	VERIFY4res *resp = &resop->nfs_resop4_u.opverify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5337
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5338
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5339
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5340
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5341
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5342
	DTRACE_NFSV4_2(op__verify__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5343
	    VERIFY4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5344
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5345
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5346
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5347
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5348
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5350
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5351
	nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5352
	resp->status = do_rfs4_set_attrs(NULL, &args->obj_attributes, cs,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5353
	    &sarg, &ntov, NFS4ATTR_VERIT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5354
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5355
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5356
		 * do_rfs4_set_attrs will try to verify systemwide attrs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5357
		 * so could return -1 for "no match".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5358
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5359
		if (resp->status == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5360
			resp->status = NFS4ERR_NOT_SAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5361
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5362
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5363
	error = rfs4_verify_attr(&sarg, NULL, &ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5364
	switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5365
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5366
		resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5367
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5368
	case -1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5369
		resp->status = NFS4ERR_NOT_SAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5370
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5371
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5372
		resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5373
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5374
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5375
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5376
	*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5377
	nfs4_ntov_table_free(&ntov, &sarg);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5378
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5379
	DTRACE_NFSV4_2(op__verify__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5380
	    VERIFY4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5381
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5383
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5384
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5385
rfs4_op_nverify(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5386
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5387
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5388
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5389
	 * verify and nverify are exactly the same, except that nverify
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5390
	 * succeeds when some argument changed, and verify succeeds when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5391
	 * when none changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5392
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5394
	NVERIFY4args  *args = &argop->nfs_argop4_u.opnverify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5395
	NVERIFY4res *resp = &resop->nfs_resop4_u.opnverify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5397
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5398
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5399
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5400
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5401
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5402
	DTRACE_NFSV4_2(op__nverify__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5403
	    NVERIFY4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5404
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5405
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5406
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5407
		DTRACE_NFSV4_2(op__nverify__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5408
		    NVERIFY4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5409
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5410
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5411
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5412
	nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5413
	resp->status = do_rfs4_set_attrs(NULL, &args->obj_attributes, cs,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5414
	    &sarg, &ntov, NFS4ATTR_VERIT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5415
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5416
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5417
		 * do_rfs4_set_attrs will try to verify systemwide attrs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5418
		 * so could return -1 for "no match".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5419
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5420
		if (resp->status == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5421
			resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5422
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5424
	error = rfs4_verify_attr(&sarg, NULL, &ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5425
	switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5426
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5427
		resp->status = NFS4ERR_SAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5428
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5429
	case -1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5430
		resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5431
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5432
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5433
		resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5434
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5435
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5436
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5437
	*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5438
	nfs4_ntov_table_free(&ntov, &sarg);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5439
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5440
	DTRACE_NFSV4_2(op__nverify__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5441
	    NVERIFY4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5442
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5444
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5445
 * XXX - This should live in an NFS header file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5446
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5447
#define	MAX_IOVECS	12
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5449
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5450
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5451
rfs4_op_write(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5452
	struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5453
{
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5454
	WRITE4args *args = &argop->nfs_argop4_u.opwrite;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5455
	WRITE4res *resp = &resop->nfs_resop4_u.opwrite;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5456
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5457
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5458
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5459
	u_offset_t rlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5460
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5461
	struct iovec iov[MAX_IOVECS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5462
	struct iovec *iovp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5463
	int iovcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5464
	int ioflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5465
	cred_t *savecred, *cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5466
	bool_t *deleg = &cs->deleg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5467
	nfsstat4 stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5468
	int in_crit = 0;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5469
	caller_context_t ct;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5470
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5471
	DTRACE_NFSV4_2(op__write__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5472
	    WRITE4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5473
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5474
	vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5475
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5476
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5477
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5478
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5479
	if (cs->access == CS_ACCESS_DENIED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5480
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5481
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5482
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5484
	cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5485
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5486
	if ((stat = rfs4_check_stateid(FWRITE, vp, &args->stateid, FALSE,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5487
	    deleg, TRUE, &ct)) != NFS4_OK) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5488
		*cs->statusp = resp->status = stat;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5489
		goto out;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5490
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5491
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5492
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5493
	 * We have to enter the critical region before calling VOP_RWLOCK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5494
	 * to avoid a deadlock with ufs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5495
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5496
	if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5497
		nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5498
		in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5499
		if (nbl_conflict(vp, NBL_WRITE,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5500
		    args->offset, args->data_len, 0, &ct)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5501
			*cs->statusp = resp->status = NFS4ERR_LOCKED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5502
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5503
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5504
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5506
	bva.va_mask = AT_MODE | AT_UID;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5507
	error = VOP_GETATTR(vp, &bva, 0, cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5509
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5510
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5511
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5512
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5513
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5514
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5515
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5516
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5518
	if (rdonly4(cs->exi, cs->vp, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5519
		*cs->statusp = resp->status = NFS4ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5520
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5521
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5523
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5524
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5525
		    ((vp->v_type == VDIR) ? NFS4ERR_ISDIR : NFS4ERR_INVAL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5526
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5527
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5529
	if (crgetuid(cr) != bva.va_uid &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5530
	    (error = VOP_ACCESS(vp, VWRITE, 0, cr, &ct))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5531
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5532
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5533
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5535
	if (MANDLOCK(vp, bva.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5536
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5537
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5538
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5539
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5540
	if (args->data_len == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5541
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5542
		resp->count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5543
		resp->committed = args->stable;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5544
		resp->writeverf = Write4verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5545
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5546
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5548
	if (args->mblk != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5549
		mblk_t *m;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5550
		uint_t bytes, round_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5551
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5552
		iovcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5553
		bytes = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5554
		round_len = roundup(args->data_len, BYTES_PER_XDR_UNIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5555
		for (m = args->mblk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5556
		    m != NULL && bytes < round_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5557
		    m = m->b_cont) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5558
			iovcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5559
			bytes += MBLKL(m);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5560
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5561
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5562
		/* should have ended on an mblk boundary */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5563
		if (bytes != round_len) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5564
			printf("bytes=0x%x, round_len=0x%x, req len=0x%x\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5565
			    bytes, round_len, args->data_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5566
			printf("args=%p, args->mblk=%p, m=%p", (void *)args,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5567
			    (void *)args->mblk, (void *)m);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5568
			ASSERT(bytes == round_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5569
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5570
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5571
		if (iovcnt <= MAX_IOVECS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5572
			iovp = iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5573
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5574
			iovp = kmem_alloc(sizeof (*iovp) * iovcnt, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5575
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5576
		mblk_to_iov(args->mblk, iovcnt, iovp);
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  5577
	} else if (args->rlist != NULL) {
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  5578
		iovcnt = 1;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  5579
		iovp = iov;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  5580
		iovp->iov_base = (char *)((args->rlist)->u.c_daddr3);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  5581
		iovp->iov_len = args->data_len;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5582
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5583
		iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5584
		iovp = iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5585
		iovp->iov_base = args->data_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5586
		iovp->iov_len = args->data_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5587
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5589
	uio.uio_iov = iovp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5590
	uio.uio_iovcnt = iovcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5592
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5593
	uio.uio_extflg = UIO_COPY_DEFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5594
	uio.uio_loffset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5595
	uio.uio_resid = args->data_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5596
	uio.uio_llimit = curproc->p_fsz_ctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5597
	rlimit = uio.uio_llimit - args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5598
	if (rlimit < (u_offset_t)uio.uio_resid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5599
		uio.uio_resid = (int)rlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5600
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5601
	if (args->stable == UNSTABLE4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5602
		ioflag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5603
	else if (args->stable == FILE_SYNC4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5604
		ioflag = FSYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5605
	else if (args->stable == DATA_SYNC4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5606
		ioflag = FDSYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5607
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5608
		if (iovp != iov)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5609
			kmem_free(iovp, sizeof (*iovp) * iovcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5610
		*cs->statusp = resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5611
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5612
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5613
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5614
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5615
	 * We're changing creds because VM may fault and we need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5616
	 * the cred of the current thread to be used if quota
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5617
	 * checking is enabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5618
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5619
	savecred = curthread->t_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5620
	curthread->t_cred = cr;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5621
	error = do_io(FWRITE, vp, &uio, ioflag, cr, &ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5622
	curthread->t_cred = savecred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5624
	if (iovp != iov)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5625
		kmem_free(iovp, sizeof (*iovp) * iovcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5627
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5628
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5629
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5630
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5632
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5633
	resp->count = args->data_len - uio.uio_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5635
	if (ioflag == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5636
		resp->committed = UNSTABLE4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5637
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5638
		resp->committed = FILE_SYNC4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5640
	resp->writeverf = Write4verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5642
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5643
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5644
		nbl_end_crit(vp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5645
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5646
	DTRACE_NFSV4_2(op__write__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5647
	    WRITE4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5648
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5651
/* XXX put in a header file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5652
extern int	sec_svc_getcred(struct svc_req *, cred_t *,  caddr_t *, int *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5654
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5655
rfs4_compound(COMPOUND4args *args, COMPOUND4res *resp, struct exportinfo *exi,
6786
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5656
	struct svc_req *req, cred_t *cr, int *rv)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5657
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5658
	uint_t i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5659
	struct compound_state cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5660
6786
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5661
	if (rv != NULL)
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5662
		*rv = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5663
	rfs4_init_compound_state(&cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5664
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5665
	 * Form a reply tag by copying over the reqeuest tag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5666
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5667
	resp->tag.utf8string_val =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5668
	    kmem_alloc(args->tag.utf8string_len, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5669
	resp->tag.utf8string_len = args->tag.utf8string_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5670
	bcopy(args->tag.utf8string_val, resp->tag.utf8string_val,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5671
	    resp->tag.utf8string_len);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5673
	cs.statusp = &resp->status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5674
	cs.req = req;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5676
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5677
	 * XXX for now, minorversion should be zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5678
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5679
	if (args->minorversion != NFS4_MINORVERSION) {
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5680
		DTRACE_NFSV4_2(compound__start, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5681
		    &cs, COMPOUND4args *, args);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5682
		resp->array_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5683
		resp->array = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5684
		resp->status = NFS4ERR_MINOR_VERS_MISMATCH;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5685
		DTRACE_NFSV4_2(compound__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5686
		    &cs, COMPOUND4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5687
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5688
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5690
	ASSERT(exi == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5691
	ASSERT(cr == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5692
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5693
	cr = crget();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5694
	ASSERT(cr != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5696
	if (sec_svc_getcred(req, cr, &cs.principal, &cs.nfsflavor) == 0) {
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5697
		DTRACE_NFSV4_2(compound__start, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5698
		    &cs, COMPOUND4args *, args);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5699
		crfree(cr);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5700
		DTRACE_NFSV4_2(compound__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5701
		    &cs, COMPOUND4res *, resp);
6786
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5702
		svcerr_badcred(req->rq_xprt);
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5703
		if (rv != NULL)
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5704
			*rv = 1;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5705
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5706
	}
6786
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5707
	resp->array_len = args->array_len;
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5708
	resp->array = kmem_zalloc(args->array_len * sizeof (nfs_resop4),
8978aafca942 6700655 NFSv4.0 server silently drops reply on sec_svc_getcred() failure
rmesta
parents: 6634
diff changeset
  5709
	    KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5710
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5711
	cs.basecr = cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5712
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5713
	DTRACE_NFSV4_2(compound__start, struct compound_state *, &cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5714
	    COMPOUND4args *, args);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5716
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5717
	 * For now, NFS4 compound processing must be protected by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5718
	 * exported_lock because it can access more than one exportinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5719
	 * per compound and share/unshare can now change multiple
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5720
	 * exinfo structs.  The NFS2/3 code only refs 1 exportinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5721
	 * per proc (excluding public exinfo), and exi_count design
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5722
	 * is sufficient to protect concurrent execution of NFS2/3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5723
	 * ops along with unexport.  This lock will be removed as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5724
	 * part of the NFSv4 phase 2 namespace redesign work.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5725
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5726
	rw_enter(&exported_lock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5727
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5728
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5729
	 * If this is the first compound we've seen, we need to start all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5730
	 * new instances' grace periods.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5731
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5732
	if (rfs4_seen_first_compound == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5733
		rfs4_grace_start_new();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5734
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5735
		 * This must be set after rfs4_grace_start_new(), otherwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5736
		 * another thread could proceed past here before the former
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5737
		 * is finished.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5738
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5739
		rfs4_seen_first_compound = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5740
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5741
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5742
	for (i = 0; i < args->array_len && cs.cont; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5743
		nfs_argop4 *argop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5744
		nfs_resop4 *resop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5745
		uint_t op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5747
		argop = &args->array[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5748
		resop = &resp->array[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5749
		resop->resop = argop->argop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5750
		op = (uint_t)resop->resop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5751
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5752
		if (op < rfsv4disp_cnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5753
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5754
			 * Count the individual ops here; NULL and COMPOUND
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5755
			 * are counted in common_dispatch()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5756
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5757
			rfsproccnt_v4_ptr[op].value.ui64++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5759
			NFS4_DEBUG(rfs4_debug > 1,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5760
			    (CE_NOTE, "Executing %s", rfs4_op_string[op]));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5761
			(*rfsv4disptab[op].dis_proc)(argop, resop, req, &cs);
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5762
			NFS4_DEBUG(rfs4_debug > 1, (CE_NOTE, "%s returned %d",
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5763
			    rfs4_op_string[op], *cs.statusp));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5764
			if (*cs.statusp != NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5765
				cs.cont = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5766
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5767
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5768
			 * This is effectively dead code since XDR code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5769
			 * will have already returned BADXDR if op doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5770
			 * decode to legal value.  This only done for a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5771
			 * day when XDR code doesn't verify v4 opcodes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5772
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5773
			op = OP_ILLEGAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5774
			rfsproccnt_v4_ptr[OP_ILLEGAL_IDX].value.ui64++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5776
			rfs4_op_illegal(argop, resop, req, &cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5777
			cs.cont = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5778
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5780
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5781
		 * If not at last op, and if we are to stop, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5782
		 * compact the results array.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5783
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5784
		if ((i + 1) < args->array_len && !cs.cont) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5785
			nfs_resop4 *new_res = kmem_alloc(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5786
			    (i+1) * sizeof (nfs_resop4), KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5787
			bcopy(resp->array,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5788
			    new_res, (i+1) * sizeof (nfs_resop4));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5789
			kmem_free(resp->array,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5790
			    args->array_len * sizeof (nfs_resop4));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5791
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5792
			resp->array_len =  i + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5793
			resp->array = new_res;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5794
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5795
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5797
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5798
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5799
	DTRACE_NFSV4_2(compound__done, struct compound_state *, &cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5800
	    COMPOUND4res *, resp);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  5801
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5802
	if (cs.vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5803
		VN_RELE(cs.vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5804
	if (cs.saved_vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5805
		VN_RELE(cs.saved_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5806
	if (cs.saved_fh.nfs_fh4_val)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5807
		kmem_free(cs.saved_fh.nfs_fh4_val, NFS4_FHSIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5809
	if (cs.basecr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5810
		crfree(cs.basecr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5811
	if (cs.cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5812
		crfree(cs.cr);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5813
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5814
	 * done with this compound request, free the label
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5815
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5816
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5817
	if (req->rq_label != NULL) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5818
		kmem_free(req->rq_label, sizeof (bslabel_t));
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5819
		req->rq_label = NULL;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  5820
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5821
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5823
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5824
 * XXX because of what appears to be duplicate calls to rfs4_compound_free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5825
 * XXX zero out the tag and array values. Need to investigate why the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5826
 * XXX calls occur, but at least prevent the panic for now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5827
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5828
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5829
rfs4_compound_free(COMPOUND4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5830
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5831
	uint_t i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5833
	if (resp->tag.utf8string_val) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5834
		UTF8STRING_FREE(resp->tag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5835
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5837
	for (i = 0; i < resp->array_len; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5838
		nfs_resop4 *resop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5839
		uint_t op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5841
		resop = &resp->array[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5842
		op = (uint_t)resop->resop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5843
		if (op < rfsv4disp_cnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5844
			(*rfsv4disptab[op].dis_resfree)(resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5845
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5846
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5847
	if (resp->array != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5848
		kmem_free(resp->array, resp->array_len * sizeof (nfs_resop4));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5849
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5850
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5851
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5852
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5853
 * Process the value of the compound request rpc flags, as a bit-AND
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5854
 * of the individual per-op flags (idempotent, allowork, publicfh_ok)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5855
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5856
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5857
rfs4_compound_flagproc(COMPOUND4args *args, int *flagp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5858
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5859
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5860
	int flag = RPC_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5861
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5862
	for (i = 0; flag && i < args->array_len; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5863
		uint_t op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5865
		op = (uint_t)args->array[i].argop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5867
		if (op < rfsv4disp_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5868
			flag &= rfsv4disptab[op].dis_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5869
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5870
			flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5871
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5872
	*flagp = flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5873
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5875
nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5876
rfs4_client_sysid(rfs4_client_t *cp, sysid_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5877
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5878
	nfsstat4 e;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5880
	rfs4_dbe_lock(cp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5881
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5882
	if (cp->sysidt != LM_NOSYSID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5883
		*sp = cp->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5884
		e = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5885
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5886
	} else if ((cp->sysidt = lm_alloc_sysidt()) != LM_NOSYSID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5887
		*sp = cp->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5888
		e = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5889
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5890
		NFS4_DEBUG(rfs4_debug, (CE_NOTE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5891
		    "rfs4_client_sysid: allocated 0x%x\n", *sp));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5892
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5893
		e = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5894
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5895
	rfs4_dbe_unlock(cp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5896
	return (e);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5897
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5899
#if defined(DEBUG) && ! defined(lint)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5900
static void lock_print(char *str, int operation, struct flock64 *flk)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5901
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5902
	char *op, *type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5903
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5904
	switch (operation) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5905
	case F_GETLK: op = "F_GETLK";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5906
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5907
	case F_SETLK: op = "F_SETLK";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5908
		break;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5909
	case F_SETLK_NBMAND: op = "F_SETLK_NBMAND";
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5910
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5911
	default: op = "F_UNKNOWN";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5912
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5913
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5914
	switch (flk->l_type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5915
	case F_UNLCK: type = "F_UNLCK";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5916
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5917
	case F_RDLCK: type = "F_RDLCK";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5918
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5919
	case F_WRLCK: type = "F_WRLCK";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5920
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5921
	default: type = "F_UNKNOWN";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5922
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5923
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5925
	ASSERT(flk->l_whence == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5926
	cmn_err(CE_NOTE, "%s:  %s, type = %s, off = %llx len = %llx pid = %d",
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5927
	    str, op, type, (longlong_t)flk->l_start,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  5928
	    flk->l_len ? (longlong_t)flk->l_len : ~0LL, flk->l_pid);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5929
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5931
#define	LOCK_PRINT(d, s, t, f) if (d) lock_print(s, t, f)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5932
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5933
#define	LOCK_PRINT(d, s, t, f)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5934
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5936
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5937
static bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5938
creds_ok(cred_set_t cr_set, struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5939
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5940
	return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5941
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5942
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5943
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5944
 * Look up the pathname using the vp in cs as the directory vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5945
 * cs->vp will be the vnode for the file on success
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5946
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5947
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5948
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5949
rfs4_lookup(component4 *component, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5950
	    struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5951
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5952
	char *nm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5953
	uint32_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5954
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5955
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5956
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5957
		return (NFS4ERR_NOFILEHANDLE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5958
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5959
	if (cs->vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5960
		return (NFS4ERR_NOTDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5961
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5963
	if (!utf8_dir_verify(component))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5964
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5966
	nm = utf8_to_fn(component, &len, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5967
	if (nm == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5968
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5969
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5970
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5971
	if (len > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5972
		kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5973
		return (NFS4ERR_NAMETOOLONG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5974
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5976
	status = do_rfs4_op_lookup(nm, len, req, cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5977
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5978
	kmem_free(nm, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5979
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5980
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5981
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5983
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5984
rfs4_lookupfile(component4 *component, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5985
		struct compound_state *cs, uint32_t access,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5986
		change_info4 *cinfo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5987
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5988
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5989
	vnode_t *dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5990
	vattr_t bva, ava, fva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5991
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5992
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5993
	/* Get "before" change value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5994
	bva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  5995
	error = VOP_GETATTR(dvp, &bva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5996
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5997
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5999
	/* rfs4_lookup may VN_RELE directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6000
	VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6002
	status = rfs4_lookup(component, req, cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6003
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6004
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6005
		return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6006
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6008
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6009
	 * Get "after" change value, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6010
	 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6011
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6012
	ava.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6013
	if (VOP_GETATTR(dvp, &ava, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6014
		ava.va_ctime = bva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6015
		ava.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6016
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6017
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6018
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6019
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6020
	 * Validate the file is a file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6021
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6022
	fva.va_mask = AT_TYPE|AT_MODE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6023
	error = VOP_GETATTR(cs->vp, &fva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6024
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6025
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6027
	if (fva.va_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6028
		if (fva.va_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6029
			return (NFS4ERR_ISDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6030
		if (fva.va_type == VLNK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6031
			return (NFS4ERR_SYMLINK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6032
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6033
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6035
	NFS4_SET_FATTR4_CHANGE(cinfo->before, bva.va_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6036
	NFS4_SET_FATTR4_CHANGE(cinfo->after, ava.va_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6037
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6038
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6039
	 * It is undefined if VOP_LOOKUP will change va_seq, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6040
	 * cinfo.atomic = TRUE only if we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6041
	 * non-zero va_seq's, and they have not changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6042
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6043
	if (bva.va_seq && ava.va_seq && ava.va_seq == bva.va_seq)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6044
		cinfo->atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6045
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6046
		cinfo->atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6048
	/* Check for mandatory locking */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6049
	cs->mandlock = MANDLOCK(cs->vp, fva.va_mode);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6050
	return (check_open_access(access, cs, req));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6051
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6052
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6053
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6054
create_vnode(vnode_t *dvp, char *nm,  vattr_t *vap, createmode4 mode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6055
	    timespec32_t *mtime, cred_t *cr, vnode_t **vpp, bool_t *created)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6056
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6057
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6058
	nfsstat4 status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6059
	vattr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6061
tryagain:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6062
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6063
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6064
	 * The file open mode used is VWRITE.  If the client needs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6065
	 * some other semantic, then it should do the access checking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6066
	 * itself.  It would have been nice to have the file open mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6067
	 * passed as part of the arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6068
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6070
	*created = TRUE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6071
	error = VOP_CREATE(dvp, nm, vap, EXCL, VWRITE, vpp, cr, 0, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6073
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6074
		*created = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6075
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6076
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6077
		 * If we got something other than file already exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6078
		 * then just return this error.  Otherwise, we got
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6079
		 * EEXIST.  If we were doing a GUARDED create, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6080
		 * just return this error.  Otherwise, we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6081
		 * make sure that this wasn't a duplicate of an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6082
		 * exclusive create request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6083
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6084
		 * The assumption is made that a non-exclusive create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6085
		 * request will never return EEXIST.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6086
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6087
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6088
		if (error != EEXIST || mode == GUARDED4) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6089
			status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6090
			return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6091
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6092
		error = VOP_LOOKUP(dvp, nm, vpp, NULL, 0, NULL, cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6093
		    NULL, NULL, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6094
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6095
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6096
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6097
			 * We couldn't find the file that we thought that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6098
			 * we just created.  So, we'll just try creating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6099
			 * it again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6100
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6101
			if (error == ENOENT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6102
				goto tryagain;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6104
			status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6105
			return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6106
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6108
		if (mode == UNCHECKED4) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6109
			/* existing object must be regular file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6110
			if ((*vpp)->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6111
				if ((*vpp)->v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6112
					status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6113
				else if ((*vpp)->v_type == VLNK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6114
					status = NFS4ERR_SYMLINK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6115
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6116
					status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6117
				VN_RELE(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6118
				return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6119
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6121
			return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6122
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6124
		/* Check for duplicate request */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6125
		ASSERT(mtime != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6126
		va.va_mask = AT_MTIME;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6127
		error = VOP_GETATTR(*vpp, &va, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6128
		if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6129
			/* We found the file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6130
			if (va.va_mtime.tv_sec != mtime->tv_sec ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6131
			    va.va_mtime.tv_nsec != mtime->tv_nsec) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6132
				/* but its not our creation */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6133
				VN_RELE(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6134
				return (NFS4ERR_EXIST);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6135
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6136
			*created = TRUE; /* retrans of create == created */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6137
			return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6138
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6139
		VN_RELE(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6140
		return (NFS4ERR_EXIST);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6141
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6143
	return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6144
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6146
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6147
check_open_access(uint32_t access,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6148
		struct compound_state *cs, struct svc_req *req)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6149
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6150
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6151
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6152
	bool_t readonly;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6153
	cred_t *cr = cs->cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6155
	/* For now we don't allow mandatory locking as per V2/V3 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6156
	if (cs->access == CS_ACCESS_DENIED || cs->mandlock) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6157
		return (NFS4ERR_ACCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6158
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6160
	vp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6161
	ASSERT(cr != NULL && vp->v_type == VREG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6163
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6164
	 * If the file system is exported read only and we are trying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6165
	 * to open for write, then return NFS4ERR_ROFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6166
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6168
	readonly = rdonly4(cs->exi, cs->vp, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6170
	if ((access & OPEN4_SHARE_ACCESS_WRITE) && readonly)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6171
		return (NFS4ERR_ROFS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6173
	if (access & OPEN4_SHARE_ACCESS_READ) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6174
		if ((VOP_ACCESS(vp, VREAD, 0, cr, NULL) != 0) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6175
		    (VOP_ACCESS(vp, VEXEC, 0, cr, NULL) != 0)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6176
			return (NFS4ERR_ACCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6177
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6178
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6180
	if (access & OPEN4_SHARE_ACCESS_WRITE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6181
		error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6182
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6183
			return (NFS4ERR_ACCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6184
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6186
	return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6187
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6189
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6190
rfs4_createfile(OPEN4args *args, struct svc_req *req, struct compound_state *cs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6191
		change_info4 *cinfo, bitmap4 *attrset, clientid4 clientid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6192
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6193
	struct nfs4_svgetit_arg sarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6194
	struct nfs4_ntov_table ntov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6196
	bool_t ntov_table_init = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6197
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6198
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6199
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6200
	vattr_t bva, ava, iva, cva, *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6201
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6202
	timespec32_t *mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6203
	char *nm = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6204
	uint_t buflen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6205
	bool_t created;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6206
	bool_t setsize = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6207
	len_t reqsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6208
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6209
	bool_t trunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6210
	caller_context_t ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6211
	component4 *component;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6212
	bslabel_t *clabel;
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6213
	struct sockaddr *ca;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6214
	char *name = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6216
	sarg.sbp = &sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6218
	dvp = cs->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6220
	/* Check if the file system is read only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6221
	if (rdonly4(cs->exi, dvp, req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6222
		return (NFS4ERR_ROFS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6223
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6224
	/* check the label of including directory */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6225
	if (is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6226
		ASSERT(req->rq_label != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6227
		clabel = req->rq_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6228
		DTRACE_PROBE2(tx__rfs4__log__info__opremove__clabel, char *,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6229
		    "got client label from request(1)",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6230
		    struct svc_req *, req);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6231
		if (!blequal(&l_admin_low->tsl_label, clabel)) {
4971
b721af044177 6560317 TX NFS server needs to support NFSv3 clients
jarrett
parents: 3898
diff changeset
  6232
			if (!do_rfs_label_check(clabel, dvp, EQUALITY_CHECK)) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6233
				return (NFS4ERR_ACCESS);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6234
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6235
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6236
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1146
diff changeset
  6237
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6238
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6239
	 * Get the last component of path name in nm. cs will reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6240
	 * the including directory on success.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6241
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6242
	component = &args->open_claim4_u.file;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6243
	if (!utf8_dir_verify(component))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6244
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6245
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6246
	nm = utf8_to_fn(component, &buflen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6248
	if (nm == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6249
		return (NFS4ERR_RESOURCE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6251
	if (buflen > MAXNAMELEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6252
		kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6253
		return (NFS4ERR_NAMETOOLONG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6254
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6256
	bva.va_mask = AT_TYPE|AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6257
	error = VOP_GETATTR(dvp, &bva, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6258
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6259
		kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6260
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6261
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6263
	if (bva.va_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6264
		kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6265
		return (NFS4ERR_NOTDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6266
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6268
	NFS4_SET_FATTR4_CHANGE(cinfo->before, bva.va_ctime)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6270
	switch (args->mode) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6271
	case GUARDED4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6272
		/*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6273
	case UNCHECKED4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6274
		nfs4_ntov_table_init(&ntov);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6275
		ntov_table_init = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6277
		*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6278
		status = do_rfs4_set_attrs(attrset,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6279
		    &args->createhow4_u.createattrs,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6280
		    cs, &sarg, &ntov, NFS4ATTR_SETIT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6282
		if (status == NFS4_OK && (sarg.vap->va_mask & AT_TYPE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6283
		    sarg.vap->va_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6284
			if (sarg.vap->va_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6285
				status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6286
			else if (sarg.vap->va_type == VLNK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6287
				status = NFS4ERR_SYMLINK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6288
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6289
				status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6290
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6292
		if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6293
			kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6294
			nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6295
			*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6296
			return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6297
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6299
		vap = sarg.vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6300
		vap->va_type = VREG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6301
		vap->va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6303
		if ((vap->va_mask & AT_MODE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6304
			vap->va_mask |= AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6305
			vap->va_mode = (mode_t)0600;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6306
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6308
		if (vap->va_mask & AT_SIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6310
			/* Disallow create with a non-zero size */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6312
			if ((reqsize = sarg.vap->va_size) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6313
				kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6314
				nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6315
				*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6316
				return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6317
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6318
			setsize = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6319
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6320
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6322
	case EXCLUSIVE4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6323
		/* prohibit EXCL create of named attributes */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6324
		if (dvp->v_flag & V_XATTRDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6325
			kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6326
			*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6327
			return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6328
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6330
		cva.va_mask = AT_TYPE | AT_MTIME | AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6331
		cva.va_type = VREG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6332
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6333
		 * Ensure no time overflows. Assumes underlying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6334
		 * filesystem supports at least 32 bits.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6335
		 * Truncate nsec to usec resolution to allow valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6336
		 * compares even if the underlying filesystem truncates.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6337
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6338
		mtime = (timespec32_t *)&args->createhow4_u.createverf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6339
		cva.va_mtime.tv_sec = mtime->tv_sec % TIME32_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6340
		cva.va_mtime.tv_nsec = (mtime->tv_nsec / 1000) * 1000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6341
		cva.va_mode = (mode_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6342
		vap = &cva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6343
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6344
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6345
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6346
	/* If necessary, convert to UTF-8 for illbehaved clients */
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6347
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6348
	ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6349
	name = nfscmd_convname(ca, cs->exi, nm, NFSCMD_CONV_INBOUND,
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6350
	    MAXPATHLEN  + 1);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6351
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6352
	if (name == NULL) {
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6353
		kmem_free(nm, buflen);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6354
		return (NFS4ERR_SERVERFAULT);
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6355
	}
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6356
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6357
	status = create_vnode(dvp, name, vap, args->mode, mtime,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6358
	    cs->cr, &vp, &created);
7961
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6359
	if (nm != name)
4b5e3051f38b 6751647 TRANS2_FIND_NEXT continuation by filename restarts search at beginning of directory
natalie li - Sun Microsystems - Irvine United States <Natalie.Li@Sun.COM>
parents: 7757
diff changeset
  6360
		kmem_free(name, MAXPATHLEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6361
	kmem_free(nm, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6363
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6364
		if (ntov_table_init)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6365
			nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6366
		*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6367
		return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6368
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6370
	trunc = (setsize && !created);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6372
	if (args->mode != EXCLUSIVE4) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6373
		bitmap4 createmask = args->createhow4_u.createattrs.attrmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6375
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6376
		 * True verification that object was created with correct
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6377
		 * attrs is impossible.  The attrs could have been changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6378
		 * immediately after object creation.  If attributes did
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6379
		 * not verify, the only recourse for the server is to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6380
		 * destroy the object.  Maybe if some attrs (like gid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6381
		 * are set incorrectly, the object should be destroyed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6382
		 * however, seems bad as a default policy.  Do we really
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6383
		 * want to destroy an object over one of the times not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6384
		 * verifying correctly?  For these reasons, the server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6385
		 * currently sets bits in attrset for createattrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6386
		 * that were set; however, no verification is done.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6387
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6388
		 * vmask_to_nmask accounts for vattr bits set on create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6389
		 *	[do_rfs4_set_attrs() only sets resp bits for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6390
		 *	 non-vattr/vfs bits.]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6391
		 * Mask off any bits we set by default so as not to return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6392
		 * more attrset bits than were requested in createattrs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6393
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6394
		if (created) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6395
			nfs4_vmask_to_nmask(sarg.vap->va_mask, attrset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6396
			*attrset &= createmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6397
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6398
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6399
			 * We did not create the vnode (we tried but it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6400
			 * already existed).  In this case, the only createattr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6401
			 * that the spec allows the server to set is size,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6402
			 * and even then, it can only be set if it is 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6403
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6404
			*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6405
			if (trunc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6406
				*attrset = FATTR4_SIZE_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6407
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6408
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6409
	if (ntov_table_init)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6410
		nfs4_ntov_table_free(&ntov, &sarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6412
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6413
	 * Get the initial "after" sequence number, if it fails,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6414
	 * set to zero, time to before.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6415
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6416
	iva.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6417
	if (VOP_GETATTR(dvp, &iva, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6418
		iva.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6419
		iva.va_ctime = bva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6420
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6422
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6423
	 * create_vnode attempts to create the file exclusive,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6424
	 * if it already exists the VOP_CREATE will fail and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6425
	 * may not increase va_seq. It is atomic if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6426
	 * we haven't changed the directory, but if it has changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6427
	 * we don't know what changed it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6428
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6429
	if (!created) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6430
		if (bva.va_seq && iva.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6431
		    bva.va_seq == iva.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6432
			cinfo->atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6433
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6434
			cinfo->atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6435
		NFS4_SET_FATTR4_CHANGE(cinfo->after, iva.va_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6436
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6437
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6438
		 * The entry was created, we need to sync the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6439
		 * directory metadata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6440
		 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6441
		(void) VOP_FSYNC(dvp, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6443
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6444
		 * Get "after" change value, if it fails, simply return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6445
		 * before value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6446
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6447
		ava.va_mask = AT_CTIME|AT_SEQ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6448
		if (VOP_GETATTR(dvp, &ava, 0, cs->cr, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6449
			ava.va_ctime = bva.va_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6450
			ava.va_seq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6451
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6453
		NFS4_SET_FATTR4_CHANGE(cinfo->after, ava.va_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6455
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6456
		 * The cinfo->atomic = TRUE only if we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6457
		 * non-zero va_seq's, and it has incremented by exactly one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6458
		 * during the create_vnode and it didn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6459
		 * change during the VOP_FSYNC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6460
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6461
		if (bva.va_seq && iva.va_seq && ava.va_seq &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6462
		    iva.va_seq == (bva.va_seq + 1) && iva.va_seq == ava.va_seq)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6463
			cinfo->atomic = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6464
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6465
			cinfo->atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6466
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6467
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6468
	/* Check for mandatory locking and that the size gets set. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6469
	cva.va_mask = AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6470
	if (setsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6471
		cva.va_mask |= AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6473
	/* Assume the worst */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6474
	cs->mandlock = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6475
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6476
	if (VOP_GETATTR(vp, &cva, 0, cs->cr, NULL) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6477
		cs->mandlock = MANDLOCK(cs->vp, cva.va_mode);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6479
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6480
		 * Truncate the file if necessary; this would be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6481
		 * the case for create over an existing file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6482
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6484
		if (trunc) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6485
			int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6486
			rfs4_file_t *fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6487
			bool_t create = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6489
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6490
			 * We are writing over an existing file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6491
			 * Check to see if we need to recall a delegation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6492
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6493
			rfs4_hold_deleg_policy();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6494
			if ((fp = rfs4_findfile(vp, NULL, &create)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6495
				if (rfs4_check_delegated_byfp(FWRITE, fp,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6496
				    (reqsize == 0), FALSE, FALSE, &clientid)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6497
					rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6498
					rfs4_rele_deleg_policy();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6499
					VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6500
					*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6501
					return (NFS4ERR_DELAY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6502
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6503
				rfs4_file_rele(fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6504
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6505
			rfs4_rele_deleg_policy();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6506
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6507
			if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6508
				in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6509
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6510
				ASSERT(reqsize == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6511
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6512
				nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6513
				if (nbl_conflict(vp, NBL_WRITE, 0,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6514
				    cva.va_size, 0, NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6515
					in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6516
					nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6517
					VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6518
					*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6519
					return (NFS4ERR_ACCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6520
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6521
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6522
			ct.cc_sysid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6523
			ct.cc_pid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6524
			ct.cc_caller_id = nfs4_srv_caller_id;
5798
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  6525
			ct.cc_flags = CC_DONTBLOCK;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6527
			cva.va_mask = AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6528
			cva.va_size = reqsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6529
			(void) VOP_SETATTR(vp, &cva, 0, cs->cr, &ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6530
			if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6531
				nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6532
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6533
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6535
	error = makefh4(&cs->fh, vp, cs->exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6537
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6538
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6539
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6540
	(void) VOP_FSYNC(vp, FNODSYNC, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6542
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6543
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6544
		*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6545
		return (puterrno4(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6546
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6548
	/* if parent dir is attrdir, set namedattr fh flag */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6549
	if (dvp->v_flag & V_XATTRDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6550
		set_fh4_flag(&cs->fh, FH4_NAMEDATTR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6551
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6552
	if (cs->vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6553
		VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6555
	cs->vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6557
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6558
	 * if we did not create the file, we will need to check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6559
	 * the access bits on the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6560
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6562
	if (!created) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6563
		if (setsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6564
			args->share_access |= OPEN4_SHARE_ACCESS_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6565
		status = check_open_access(args->share_access, cs, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6566
		if (status != NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6567
			*attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6568
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6569
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6570
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6571
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6572
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6573
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6574
rfs4_do_open(struct compound_state *cs, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6575
		rfs4_openowner_t *oo, delegreq_t deleg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6576
		uint32_t access, uint32_t deny,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6577
		OPEN4res *resp, int deleg_cur)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6578
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6579
	/* XXX Currently not using req  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6580
	rfs4_state_t *state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6581
	rfs4_file_t *file;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6582
	bool_t screate = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6583
	bool_t fcreate = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6584
	uint32_t amodes;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6585
	uint32_t dmodes;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6586
	rfs4_deleg_state_t *dsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6587
	struct shrlock shr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6588
	struct shr_locowner shr_loco;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6589
	sysid_t sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6590
	nfsstat4 status;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6591
	caller_context_t ct;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6592
	int fflags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6593
	int recall = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6594
	int err;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6595
	int cmd;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6597
	/* get the file struct and hold a lock on it during initial open */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6598
	file = rfs4_findfile_withlock(cs->vp, &cs->fh, &fcreate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6599
	if (file == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6600
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6601
		    (CE_NOTE, "rfs4_do_open: can't find file"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6602
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6603
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6604
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6605
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6606
	state = rfs4_findstate_by_owner_file(oo, file, &screate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6607
	if (state == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6608
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6609
		    (CE_NOTE, "rfs4_do_open: can't find state"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6610
		resp->status = NFS4ERR_RESOURCE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6611
		/* No need to keep any reference */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6612
		rfs4_file_rele_withunlock(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6613
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6614
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6615
2038
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6616
	/* try to get the sysid before continuing */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6617
	if ((status = rfs4_client_sysid(oo->client, &sysid)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6618
		resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6619
		rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6620
		/* Not a fully formed open; "close" it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6621
		if (screate == TRUE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6622
			rfs4_state_close(state, FALSE, FALSE, cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6623
		rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6624
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6625
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6626
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6627
	/* Calculate the fflags for this OPEN. */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6628
	if (access & OPEN4_SHARE_ACCESS_READ)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6629
		fflags |= FREAD;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6630
	if (access & OPEN4_SHARE_ACCESS_WRITE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6631
		fflags |= FWRITE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6632
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6633
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6634
	 * Calculate the new deny and access mode that this open is adding to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6635
	 * the file for this open owner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6636
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6637
	dmodes = (deny & ~state->share_deny);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6638
	amodes = (access & ~state->share_access);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6640
	/*
2038
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6641
	 * Check to see the client has already sent an open for this
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6642
	 * open owner on this file with the same share/deny modes.
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6643
	 * If so, we don't need to check for a conflict and we don't
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6644
	 * need to add another shrlock.  If not, then we need to
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6645
	 * check for conflicts in deny and access before checking for
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6646
	 * conflicts in delegation.  We don't want to recall a
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6647
	 * delegation based on an open that will eventually fail based
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6648
	 * on shares modes.
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6649
	 */
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6650
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6651
	if (dmodes || amodes) {
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6652
		shr.s_access = (short)access;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6653
		shr.s_deny = (short)deny;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6654
		shr.s_pid = rfs4_dbe_getid(oo->dbe);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6655
		shr.s_sysid = sysid;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6656
		shr_loco.sl_pid = shr.s_pid;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6657
		shr_loco.sl_id = shr.s_sysid;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6658
		shr.s_owner = (caddr_t)&shr_loco;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6659
		shr.s_own_len = sizeof (shr_loco);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6660
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6661
		cmd = nbl_need_check(cs->vp) ? F_SHARE_NBMAND : F_SHARE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6662
		if ((err = vop_shrlock(cs->vp, cmd, &shr, fflags)) != 0) {
2038
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6663
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6664
			resp->status = err == EAGAIN ?
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6665
			    NFS4ERR_SHARE_DENIED : puterrno4(err);
2038
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6666
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6667
			rfs4_file_rele(file);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6668
			/* Not a fully formed open; "close" it */
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6669
			if (screate == TRUE)
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6670
				rfs4_state_close(state, FALSE, FALSE, cs->cr);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6671
			rfs4_state_rele(state);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6672
			return;
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6673
		}
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6674
	}
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6675
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6676
	rfs4_dbe_lock(state->dbe);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6677
	rfs4_dbe_lock(file->dbe);
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6678
9b30a0ab3306 6413702 NFS Server is leaking SHRLOCK state.
jwahlig
parents: 2035
diff changeset
  6679
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6680
	 * Check to see if this file is delegated and if so, if a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6681
	 * recall needs to be done.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6682
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6683
	if (rfs4_check_recall(state, access)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6684
		rfs4_dbe_unlock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6685
		rfs4_dbe_unlock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6686
		rfs4_recall_deleg(file, FALSE, state->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6687
		delay(NFS4_DELEGATION_CONFLICT_DELAY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6688
		rfs4_dbe_lock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6689
		rfs4_dbe_lock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6690
		/* Let's see if the delegation was returned */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6691
		if (rfs4_check_recall(state, access)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6692
			rfs4_dbe_unlock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6693
			rfs4_dbe_unlock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6694
			rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6695
			rfs4_update_lease(state->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6696
			(void) vop_shrlock(cs->vp, F_UNSHARE, &shr, fflags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6697
			/* Not a fully formed open; "close" it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6698
			if (screate == TRUE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6699
				rfs4_state_close(state, FALSE, FALSE, cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6700
			rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6701
			resp->status = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6702
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6703
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6704
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6705
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6706
	 * the share check passed and any delegation conflict has been
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6707
	 * taken care of, now call vop_open.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6708
	 * if this is the first open then call vop_open with fflags.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6709
	 * if not, call vn_open_upgrade with just the upgrade flags.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6710
	 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6711
	 * if the file has been opened already, it will have the current
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6712
	 * access mode in the state struct.  if it has no share access, then
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6713
	 * this is a new open.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6714
	 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6715
	 * However, if this is open with CLAIM_DLEGATE_CUR, then don't
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6716
	 * call VOP_OPEN(), just do the open upgrade.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6717
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6718
	if (((state->share_access & OPEN4_SHARE_ACCESS_BOTH) == 0) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6719
	    !deleg_cur) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6720
		ct.cc_sysid = sysid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6721
		ct.cc_pid = shr.s_pid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6722
		ct.cc_caller_id = nfs4_srv_caller_id;
5798
6cee32ee4514 6647287 setattr hangs in monitor of read delegated file
jwahlig
parents: 5674
diff changeset
  6723
		ct.cc_flags = CC_DONTBLOCK;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6724
		err = VOP_OPEN(&cs->vp, fflags, cs->cr, &ct);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6725
		if (err) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6726
			rfs4_dbe_unlock(file->dbe);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6727
			rfs4_dbe_unlock(state->dbe);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6728
			rfs4_file_rele(file);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6729
			(void) vop_shrlock(cs->vp, F_UNSHARE, &shr, fflags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6730
			/* Not a fully formed open; "close" it */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6731
			if (screate == TRUE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6732
				rfs4_state_close(state, FALSE, FALSE, cs->cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6733
			rfs4_state_rele(state);
6634
d6cbc114c158 6699816 NFS4.0 server doesn't check for EAGAIN from VOP_OPEN
jwahlig
parents: 6402
diff changeset
  6734
			/* check if a monitor detected a delegation conflict */
d6cbc114c158 6699816 NFS4.0 server doesn't check for EAGAIN from VOP_OPEN
jwahlig
parents: 6402
diff changeset
  6735
			if (err == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK))
d6cbc114c158 6699816 NFS4.0 server doesn't check for EAGAIN from VOP_OPEN
jwahlig
parents: 6402
diff changeset
  6736
				resp->status = NFS4ERR_DELAY;
d6cbc114c158 6699816 NFS4.0 server doesn't check for EAGAIN from VOP_OPEN
jwahlig
parents: 6402
diff changeset
  6737
			else
d6cbc114c158 6699816 NFS4.0 server doesn't check for EAGAIN from VOP_OPEN
jwahlig
parents: 6402
diff changeset
  6738
				resp->status = NFS4ERR_SERVERFAULT;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6739
			return;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6740
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6741
	} else { /* open upgrade */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6742
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6743
		 * calculate the fflags for the new mode that is being added
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6744
		 * by this upgrade.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6745
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6746
		fflags = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6747
		if (amodes & OPEN4_SHARE_ACCESS_READ)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6748
			fflags |= FREAD;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6749
		if (amodes & OPEN4_SHARE_ACCESS_WRITE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6750
			fflags |= FWRITE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6751
		vn_open_upgrade(cs->vp, fflags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6752
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6754
	if (dmodes & OPEN4_SHARE_DENY_READ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6755
		file->deny_read++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6756
	if (dmodes & OPEN4_SHARE_DENY_WRITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6757
		file->deny_write++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6758
	file->share_deny |= deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6759
	state->share_deny |= deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6760
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6761
	if (amodes & OPEN4_SHARE_ACCESS_READ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6762
		file->access_read++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6763
	if (amodes & OPEN4_SHARE_ACCESS_WRITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6764
		file->access_write++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6765
	file->share_access |= access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6766
	state->share_access |= access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6768
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6769
	 * Check for delegation here. if the deleg argument is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6770
	 * DELEG_ANY, then this is a reclaim from a client and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6771
	 * we must honor the delegation requested. If necessary we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6772
	 * set the recall flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6773
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6775
	dsp = rfs4_grant_delegation(deleg, state, &recall);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6777
	cs->deleg = (file->dinfo->dtype == OPEN_DELEGATE_WRITE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6779
	next_stateid(&state->stateid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6780
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6781
	resp->stateid = state->stateid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6782
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6783
	rfs4_dbe_unlock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6784
	rfs4_dbe_unlock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6786
	if (dsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6787
		rfs4_set_deleg_response(dsp, &resp->delegation, NULL, recall);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6788
		rfs4_deleg_state_rele(dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6789
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6791
	rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6792
	rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6794
	resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6795
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6797
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6798
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6799
rfs4_do_opennull(struct compound_state *cs, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6800
		OPEN4args *args, rfs4_openowner_t *oo, OPEN4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6801
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6802
	change_info4 *cinfo = &resp->cinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6803
	bitmap4 *attrset = &resp->attrset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6805
	if (args->opentype == OPEN4_NOCREATE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6806
		resp->status = rfs4_lookupfile(&args->open_claim4_u.file,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6807
		    req, cs, args->share_access, cinfo);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6808
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6809
		/* inhibit delegation grants during exclusive create */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6811
		if (args->mode == EXCLUSIVE4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6812
			rfs4_disable_delegation();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6813
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6814
		resp->status = rfs4_createfile(args, req, cs, cinfo, attrset,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6815
		    oo->client->clientid);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6816
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6818
	if (resp->status == NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6820
		/* cs->vp cs->fh now reference the desired file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6822
		rfs4_do_open(cs, req, oo, DELEG_ANY, args->share_access,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6823
		    args->share_deny, resp, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6825
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6826
		 * If rfs4_createfile set attrset, we must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6827
		 * clear this attrset before the response is copied.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6828
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6829
		if (resp->status != NFS4_OK && resp->attrset) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6830
			resp->attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6831
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6832
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6833
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6834
		*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6836
	if (args->mode == EXCLUSIVE4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6837
		rfs4_enable_delegation();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6838
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6840
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6841
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6842
rfs4_do_openprev(struct compound_state *cs, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6843
		OPEN4args *args, rfs4_openowner_t *oo, OPEN4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6844
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6845
	change_info4 *cinfo = &resp->cinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6846
	vattr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6847
	vtype_t v_type = cs->vp->v_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6848
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6850
	/* Verify that we have a regular file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6851
	if (v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6852
		if (v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6853
			resp->status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6854
		else if (v_type == VLNK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6855
			resp->status = NFS4ERR_SYMLINK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6856
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6857
			resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6858
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6859
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6861
	va.va_mask = AT_MODE|AT_UID;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6862
	error = VOP_GETATTR(cs->vp, &va, 0, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6863
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6864
		resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6865
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6866
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6868
	cs->mandlock = MANDLOCK(cs->vp, va.va_mode);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6870
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6871
	 * Check if we have access to the file, Note the the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6872
	 * could have originally been open UNCHECKED or GUARDED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6873
	 * with mode bits that will now fail, but there is nothing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6874
	 * we can really do about that except in the case that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6875
	 * owner of the file is the one requesting the open.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6876
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6877
	if (crgetuid(cs->cr) != va.va_uid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6878
		resp->status = check_open_access(args->share_access, cs, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6879
		if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6880
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6881
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6882
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6884
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6885
	 * cinfo on a CLAIM_PREVIOUS is undefined, initialize to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6886
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6887
	cinfo->before = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6888
	cinfo->after = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6889
	cinfo->atomic = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6890
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6891
	rfs4_do_open(cs, req, oo,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6892
	    NFS4_DELEG4TYPE2REQTYPE(args->open_claim4_u.delegate_type),
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6893
	    args->share_access, args->share_deny, resp, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6894
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6895
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6896
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6897
rfs4_do_opendelcur(struct compound_state *cs, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6898
		OPEN4args *args, rfs4_openowner_t *oo, OPEN4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6899
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6900
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6901
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6902
	stateid4 stateid =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6903
	    args->open_claim4_u.delegate_cur_info.delegate_stateid;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6904
	rfs4_deleg_state_t *dsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6905
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6906
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6907
	 * Find the state info from the stateid and confirm that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6908
	 * file is delegated.  If the state openowner is the same as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6909
	 * the supplied openowner we're done. If not, get the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6910
	 * info from the found state info. Use that file info to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6911
	 * create the state for this lock owner. Note solaris doen't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6912
	 * really need the pathname to find the file. We may want to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6913
	 * lookup the pathname and make sure that the vp exist and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6914
	 * matches the vp in the file structure. However it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6915
	 * possible that the pathname nolonger exists (local process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6916
	 * unlinks the file), so this may not be that useful.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6917
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6918
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6919
	status = rfs4_get_deleg_state(&stateid, &dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6920
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6921
		resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6922
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6923
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6925
	ASSERT(dsp->finfo->dinfo->dtype != OPEN_DELEGATE_NONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6926
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6927
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6928
	 * New lock owner, create state. Since this was probably called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6929
	 * in response to a CB_RECALL we set deleg to DELEG_NONE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6930
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6932
	ASSERT(cs->vp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6933
	VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6934
	VN_HOLD(dsp->finfo->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6935
	cs->vp = dsp->finfo->vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6937
	if (error = makefh4(&cs->fh, cs->vp, cs->exi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6938
		rfs4_deleg_state_rele(dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6939
		*cs->statusp = resp->status = puterrno4(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6940
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6941
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6942
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6943
	/* Mark progress for delegation returns */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6944
	dsp->finfo->dinfo->time_lastwrite = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6945
	rfs4_deleg_state_rele(dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6946
	rfs4_do_open(cs, req, oo, DELEG_NONE,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  6947
	    args->share_access, args->share_deny, resp, 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6948
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6950
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6951
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6952
rfs4_do_opendelprev(struct compound_state *cs, struct svc_req *req,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6953
			OPEN4args *args, rfs4_openowner_t *oo, OPEN4res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6954
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6955
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6956
	 * Lookup the pathname, it must already exist since this file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6957
	 * was delegated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6958
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6959
	 * Find the file and state info for this vp and open owner pair.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6960
	 *	check that they are in fact delegated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6961
	 *	check that the state access and deny modes are the same.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6962
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6963
	 * Return the delgation possibly seting the recall flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6964
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6965
	rfs4_file_t *file;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6966
	rfs4_state_t *state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6967
	bool_t create = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6968
	bool_t dcreate = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6969
	rfs4_deleg_state_t *dsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6970
	nfsace4 *ace;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6972
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6973
	/* Note we ignore oflags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6974
	resp->status = rfs4_lookupfile(&args->open_claim4_u.file_delegate_prev,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6975
	    req, cs, args->share_access, &resp->cinfo);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6976
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6977
	if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6978
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6979
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6980
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6981
	/* get the file struct and hold a lock on it during initial open */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6982
	file = rfs4_findfile_withlock(cs->vp, NULL, &create);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6983
	if (file == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6984
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6985
		    (CE_NOTE, "rfs4_do_opendelprev: can't find file"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6986
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6987
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6988
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6990
	state = rfs4_findstate_by_owner_file(oo, file, &create);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6991
	if (state == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6992
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  6993
		    (CE_NOTE, "rfs4_do_opendelprev: can't find state"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6994
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6995
		rfs4_file_rele_withunlock(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6996
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6997
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6999
	rfs4_dbe_lock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7000
	rfs4_dbe_lock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7001
	if (args->share_access != state->share_access ||
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7002
	    args->share_deny != state->share_deny ||
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7003
	    state->finfo->dinfo->dtype == OPEN_DELEGATE_NONE) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7004
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7005
		    (CE_NOTE, "rfs4_do_opendelprev: state mixup"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7006
		rfs4_dbe_unlock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7007
		rfs4_dbe_unlock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7008
		rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7009
		rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7010
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7011
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7013
	rfs4_dbe_unlock(file->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7014
	rfs4_dbe_unlock(state->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7015
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7016
	dsp = rfs4_finddeleg(state, &dcreate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7017
	if (dsp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7018
		rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7019
		rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7020
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7021
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7022
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7023
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7024
	next_stateid(&state->stateid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7026
	resp->stateid = state->stateid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7027
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7028
	resp->delegation.delegation_type = dsp->dtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7029
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7030
	if (dsp->dtype == OPEN_DELEGATE_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7031
		open_read_delegation4 *rv =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7032
		    &resp->delegation.open_delegation4_u.read;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7033
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7034
		rv->stateid = dsp->delegid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7035
		rv->recall = FALSE; /* no policy in place to set to TRUE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7036
		ace = &rv->permissions;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7037
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7038
		open_write_delegation4 *rv =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7039
		    &resp->delegation.open_delegation4_u.write;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7040
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7041
		rv->stateid = dsp->delegid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7042
		rv->recall = FALSE;  /* no policy in place to set to TRUE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7043
		ace = &rv->permissions;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7044
		rv->space_limit.limitby = NFS_LIMIT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7045
		rv->space_limit.nfs_space_limit4_u.filesize = UINT64_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7046
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7048
	/* XXX For now */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7049
	ace->type = ACE4_ACCESS_ALLOWED_ACE_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7050
	ace->flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7051
	ace->access_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7052
	ace->who.utf8string_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7053
	ace->who.utf8string_val = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7055
	rfs4_deleg_state_rele(dsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7056
	rfs4_state_rele(state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7057
	rfs4_file_rele(file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7058
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7060
typedef enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7061
	NFS4_CHKSEQ_OKAY = 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7062
	NFS4_CHKSEQ_REPLAY = 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7063
	NFS4_CHKSEQ_BAD = 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7064
} rfs4_chkseq_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7065
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7066
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7067
 * Generic function for sequence number checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7068
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7069
static rfs4_chkseq_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7070
rfs4_check_seqid(seqid4 seqid, nfs_resop4 *lastop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7071
		seqid4 rqst_seq, nfs_resop4 *resop, bool_t copyres)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7072
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7073
	/* Same sequence ids and matching operations? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7074
	if (seqid == rqst_seq && resop->resop == lastop->resop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7075
		if (copyres == TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7076
			rfs4_free_reply(resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7077
			rfs4_copy_reply(resop, lastop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7078
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7079
		NFS4_DEBUG(rfs4_debug, (CE_NOTE,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7080
		    "Replayed SEQID %d\n", seqid));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7081
		return (NFS4_CHKSEQ_REPLAY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7082
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7084
	/* If the incoming sequence is not the next expected then it is bad */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7085
	if (rqst_seq != seqid + 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7086
		if (rqst_seq == seqid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7087
			NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7088
			    (CE_NOTE, "BAD SEQID: Replayed sequence id "
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7089
			    "but last op was %d current op is %d\n",
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7090
			    lastop->resop, resop->resop));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7091
			return (NFS4_CHKSEQ_BAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7092
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7093
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7094
		    (CE_NOTE, "BAD SEQID: got %u expecting %u\n",
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7095
		    rqst_seq, seqid));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7096
		return (NFS4_CHKSEQ_BAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7097
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7098
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7099
	/* Everything okay -- next expected */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7100
	return (NFS4_CHKSEQ_OKAY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7101
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7102
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7104
static rfs4_chkseq_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7105
rfs4_check_open_seqid(seqid4 seqid, rfs4_openowner_t *op, nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7106
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7107
	rfs4_chkseq_t rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7109
	rfs4_dbe_lock(op->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7110
	rc = rfs4_check_seqid(op->open_seqid, op->reply, seqid, resop, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7111
	rfs4_dbe_unlock(op->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7113
	if (rc == NFS4_CHKSEQ_OKAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7114
		rfs4_update_lease(op->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7116
	return (rc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7117
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7119
static rfs4_chkseq_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7120
rfs4_check_olo_seqid(seqid4 olo_seqid, rfs4_openowner_t *op,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7121
	nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7122
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7123
	rfs4_chkseq_t rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7125
	rfs4_dbe_lock(op->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7126
	rc = rfs4_check_seqid(op->open_seqid, op->reply,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7127
	    olo_seqid, resop, FALSE);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7128
	rfs4_dbe_unlock(op->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7130
	return (rc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7131
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7133
static rfs4_chkseq_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7134
rfs4_check_lock_seqid(seqid4 seqid, rfs4_lo_state_t *lp, nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7135
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7136
	rfs4_chkseq_t rc = NFS4_CHKSEQ_OKAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7138
	rfs4_dbe_lock(lp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7139
	if (!lp->skip_seqid_check)
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7140
		rc = rfs4_check_seqid(lp->seqid, lp->reply, seqid, resop, TRUE);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7141
	rfs4_dbe_unlock(lp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7143
	return (rc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7144
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7146
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7147
rfs4_op_open(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7148
	    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7149
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7150
	OPEN4args *args = &argop->nfs_argop4_u.opopen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7151
	OPEN4res *resp = &resop->nfs_resop4_u.opopen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7152
	open_owner4 *owner = &args->owner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7153
	open_claim_type4 claim = args->claim;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7154
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7155
	rfs4_openowner_t *oo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7156
	bool_t create;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7157
	bool_t replay = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7158
	int can_reclaim;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7159
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7160
	DTRACE_NFSV4_2(op__open__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7161
	    OPEN4args *, args);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7163
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7164
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7165
		goto end;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7166
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7168
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7169
	 * Need to check clientid and lease expiration first based on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7170
	 * error ordering and incrementing sequence id.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7171
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7172
	cp = rfs4_findclient_by_id(owner->clientid, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7173
	if (cp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7174
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7175
		    rfs4_check_clientid(&owner->clientid, 0);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7176
		goto end;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7177
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7179
	if (rfs4_lease_expired(cp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7180
		rfs4_client_close(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7181
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7182
		goto end;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7183
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7184
	can_reclaim = cp->can_reclaim;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7186
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7187
	 * Find the open_owner for use from this point forward.  Take
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7188
	 * care in updating the sequence id based on the type of error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7189
	 * being returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7190
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7191
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7192
	create = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7193
	oo = rfs4_findopenowner(owner, &create, args->seqid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7194
	if (oo == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7195
		*cs->statusp = resp->status = NFS4ERR_STALE_CLIENTID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7196
		rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7197
		goto end;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7198
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7200
	/* Hold off access to the sequence space while the open is done */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7201
	rfs4_sw_enter(&oo->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7203
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7204
	 * If the open_owner existed before at the server, then check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7205
	 * the sequence id.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7206
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7207
	if (!create && !oo->postpone_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7208
		switch (rfs4_check_open_seqid(args->seqid, oo, resop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7209
		case NFS4_CHKSEQ_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7210
			if ((args->seqid > oo->open_seqid) &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7211
			    oo->need_confirm) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7212
				rfs4_free_opens(oo, TRUE, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7213
				rfs4_sw_exit(&oo->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7214
				rfs4_openowner_rele(oo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7215
				goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7216
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7217
			resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7218
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7219
		case NFS4_CHKSEQ_REPLAY: /* replay of previous request */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7220
			replay = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7221
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7222
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7223
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7224
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7225
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7226
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7227
		 * Sequence was ok and open owner exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7228
		 * check to see if we have yet to see an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7229
		 * open_confirm.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7230
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7231
		if (oo->need_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7232
			rfs4_free_opens(oo, TRUE, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7233
			rfs4_sw_exit(&oo->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7234
			rfs4_openowner_rele(oo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7235
			goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7236
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7237
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7238
	/* Grace only applies to regular-type OPENs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7239
	if (rfs4_clnt_in_grace(cp) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7240
	    (claim == CLAIM_NULL || claim == CLAIM_DELEGATE_CUR)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7241
		*cs->statusp = resp->status = NFS4ERR_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7242
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7243
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7245
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7246
	 * If previous state at the server existed then can_reclaim
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7247
	 * will be set. If not reply NFS4ERR_NO_GRACE to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7248
	 * client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7249
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7250
	if (rfs4_clnt_in_grace(cp) && claim == CLAIM_PREVIOUS && !can_reclaim) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7251
		*cs->statusp = resp->status = NFS4ERR_NO_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7252
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7253
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7254
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7256
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7257
	 * Reject the open if the client has missed the grace period
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7258
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7259
	if (!rfs4_clnt_in_grace(cp) && claim == CLAIM_PREVIOUS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7260
		*cs->statusp = resp->status = NFS4ERR_NO_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7261
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7262
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7264
	/* Couple of up-front bookkeeping items */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7265
	if (oo->need_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7266
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7267
		 * If this is a reclaim OPEN then we should not ask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7268
		 * for a confirmation of the open_owner per the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7269
		 * protocol specification.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7270
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7271
		if (claim == CLAIM_PREVIOUS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7272
			oo->need_confirm = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7273
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7274
			resp->rflags |= OPEN4_RESULT_CONFIRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7275
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7276
	resp->rflags |= OPEN4_RESULT_LOCKTYPE_POSIX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7278
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7279
	 * If there is an unshared filesystem mounted on this vnode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7280
	 * do not allow to open/create in this directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7281
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7282
	if (vn_ismntpt(cs->vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7283
		*cs->statusp = resp->status = NFS4ERR_ACCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7284
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7285
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7287
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7288
	 * access must READ, WRITE, or BOTH.  No access is invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7289
	 * deny can be READ, WRITE, BOTH, or NONE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7290
	 * bits not defined for access/deny are invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7291
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7292
	if (! (args->share_access & OPEN4_SHARE_ACCESS_BOTH) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7293
	    (args->share_access & ~OPEN4_SHARE_ACCESS_BOTH) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7294
	    (args->share_deny & ~OPEN4_SHARE_DENY_BOTH)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7295
		*cs->statusp = resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7296
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7297
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7300
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7301
	 * make sure attrset is zero before response is built.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7302
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7303
	resp->attrset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7305
	switch (claim) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7306
	case CLAIM_NULL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7307
		rfs4_do_opennull(cs, req, args, oo, resp);
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7308
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7309
	case CLAIM_PREVIOUS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7310
		rfs4_do_openprev(cs, req, args, oo, resp);
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7311
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7312
	case CLAIM_DELEGATE_CUR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7313
		rfs4_do_opendelcur(cs, req, args, oo, resp);
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7314
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7315
	case CLAIM_DELEGATE_PREV:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7316
		rfs4_do_opendelprev(cs, req, args, oo, resp);
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7317
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7318
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7319
		resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7320
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7321
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7323
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7324
	rfs4_client_rele(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7326
	/* Catch sequence id handling here to make it a little easier */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7327
	switch (resp->status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7328
	case NFS4ERR_BADXDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7329
	case NFS4ERR_BAD_SEQID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7330
	case NFS4ERR_BAD_STATEID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7331
	case NFS4ERR_NOFILEHANDLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7332
	case NFS4ERR_RESOURCE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7333
	case NFS4ERR_STALE_CLIENTID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7334
	case NFS4ERR_STALE_STATEID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7335
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7336
		 * The protocol states that if any of these errors are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7337
		 * being returned, the sequence id should not be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7338
		 * incremented.  Any other return requires an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7339
		 * increment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7340
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7341
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7342
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7343
		/* Always update the lease in this case */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7344
		rfs4_update_lease(oo->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7346
		/* Regular response - copy the result */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7347
		if (!replay)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7348
			rfs4_update_open_resp(oo, resop, &cs->fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7350
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7351
		 * REPLAY case: Only if the previous response was OK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7352
		 * do we copy the filehandle.  If not OK, no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7353
		 * filehandle to copy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7354
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7355
		if (replay == TRUE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7356
		    resp->status == NFS4_OK &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7357
		    oo->reply_fh.nfs_fh4_val) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7358
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7359
			 * If this is a replay, we must restore the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7360
			 * current filehandle/vp to that of what was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7361
			 * returned originally.  Try our best to do
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7362
			 * it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7363
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7364
			nfs_fh4_fmt_t *fh_fmtp =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7365
			    (nfs_fh4_fmt_t *)oo->reply_fh.nfs_fh4_val;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7366
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7367
			cs->exi = checkexport4(&fh_fmtp->fh4_fsid,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7368
			    (fid_t *)&fh_fmtp->fh4_xlen, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7370
			if (cs->exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7371
				resp->status = NFS4ERR_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7372
				goto finish;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7373
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7375
			VN_RELE(cs->vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7377
			cs->vp = nfs4_fhtovp(&oo->reply_fh, cs->exi,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7378
			    &resp->status);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7380
			if (cs->vp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7381
				goto finish;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7383
			nfs_fh4_copy(&oo->reply_fh, &cs->fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7384
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7386
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7387
		 * If this was a replay, no need to update the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7388
		 * sequence id. If the open_owner was not created on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7389
		 * this pass, then update.  The first use of an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7390
		 * open_owner will not bump the sequence id.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7391
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7392
		if (replay == FALSE && !create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7393
			rfs4_update_open_sequence(oo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7394
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7395
		 * If the client is receiving an error and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7396
		 * open_owner needs to be confirmed, there is no way
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7397
		 * to notify the client of this fact ignoring the fact
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7398
		 * that the server has no method of returning a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7399
		 * stateid to confirm.  Therefore, the server needs to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7400
		 * mark this open_owner in a way as to avoid the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7401
		 * sequence id checking the next time the client uses
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7402
		 * this open_owner.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7403
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7404
		if (resp->status != NFS4_OK && oo->need_confirm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7405
			oo->postpone_confirm = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7406
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7407
		 * If OK response then clear the postpone flag and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7408
		 * reset the sequence id to keep in sync with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7409
		 * client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7410
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7411
		if (resp->status == NFS4_OK && oo->postpone_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7412
			oo->postpone_confirm = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7413
			oo->open_seqid = args->seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7414
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7415
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7416
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7418
finish:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7419
	*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7420
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7421
	rfs4_sw_exit(&oo->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7422
	rfs4_openowner_rele(oo);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7423
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7424
end:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7425
	DTRACE_NFSV4_2(op__open__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7426
	    OPEN4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7427
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7429
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7430
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7431
rfs4_op_open_confirm(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7432
		    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7433
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7434
	OPEN_CONFIRM4args *args = &argop->nfs_argop4_u.opopen_confirm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7435
	OPEN_CONFIRM4res *resp = &resop->nfs_resop4_u.opopen_confirm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7436
	rfs4_state_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7437
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7438
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7439
	DTRACE_NFSV4_2(op__open__confirm__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7440
	    OPEN_CONFIRM4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7441
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7442
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7443
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7444
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7445
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7447
	status = rfs4_get_state(&args->open_stateid, &sp, RFS4_DBS_VALID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7448
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7449
		*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7450
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7451
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7453
	/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7454
	if (cs->vp != sp->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7455
		rfs4_state_rele(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7456
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7457
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7458
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7460
	/* hold off other access to open_owner while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7461
	rfs4_sw_enter(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7462
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7463
	switch (rfs4_check_stateid_seqid(sp, &args->open_stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7464
	case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7465
		if (rfs4_check_open_seqid(args->seqid, sp->owner,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7466
		    resop) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7467
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7468
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7469
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7470
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7471
		 * If it is the appropriate stateid and determined to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7472
		 * be "OKAY" then this means that the stateid does not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7473
		 * need to be confirmed and the client is in error for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7474
		 * sending an OPEN_CONFIRM.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7475
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7476
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7477
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7478
	case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7479
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7480
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7481
	case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7482
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7483
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7484
	case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7485
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7486
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7487
	case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7488
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7489
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7490
	case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7491
		switch (rfs4_check_open_seqid(args->seqid, sp->owner, resop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7492
		case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7493
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7494
			 * This is replayed stateid; if seqid matches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7495
			 * next expected, then client is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7496
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7497
			/* fall through */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7498
		case NFS4_CHKSEQ_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7499
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7500
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7501
		case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7502
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7503
			 * Note this case is the duplicate case so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7504
			 * resp->status is already set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7505
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7506
			*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7507
			rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7508
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7509
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7510
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7511
	case NFS4_CHECK_STATEID_UNCONFIRMED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7512
		if (rfs4_check_open_seqid(args->seqid, sp->owner,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7513
		    resop) != NFS4_CHKSEQ_OKAY) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7514
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7515
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7516
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7517
		*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7519
		next_stateid(&sp->stateid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7520
		resp->open_stateid = sp->stateid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7521
		sp->owner->need_confirm = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7522
		rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7523
		rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7524
		rfs4_update_open_resp(sp->owner, resop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7525
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7526
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7527
		ASSERT(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7528
		*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7529
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7530
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7531
	rfs4_sw_exit(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7532
	rfs4_state_rele(sp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7533
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7534
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7535
	DTRACE_NFSV4_2(op__open__confirm__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7536
	    OPEN_CONFIRM4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7537
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7538
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7539
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7540
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7541
rfs4_op_open_downgrade(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7542
		    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7543
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7544
	OPEN_DOWNGRADE4args *args = &argop->nfs_argop4_u.opopen_downgrade;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7545
	OPEN_DOWNGRADE4res *resp = &resop->nfs_resop4_u.opopen_downgrade;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7546
	uint32_t access = args->share_access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7547
	uint32_t deny = args->share_deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7548
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7549
	rfs4_state_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7550
	rfs4_file_t *fp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7551
	int fflags = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7552
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7553
	DTRACE_NFSV4_2(op__open__downgrade__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7554
	    OPEN_DOWNGRADE4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7555
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7556
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7557
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7558
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7559
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7561
	status = rfs4_get_state(&args->open_stateid, &sp, RFS4_DBS_VALID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7562
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7563
		*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7564
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7565
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7567
	/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7568
	if (cs->vp != sp->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7569
		rfs4_state_rele(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7570
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7571
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7572
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7574
	/* hold off other access to open_owner while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7575
	rfs4_sw_enter(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7577
	switch (rfs4_check_stateid_seqid(sp, &args->open_stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7578
	case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7579
		if (rfs4_check_open_seqid(args->seqid, sp->owner,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7580
		    resop) != NFS4_CHKSEQ_OKAY) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7581
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7582
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7583
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7584
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7585
	case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7586
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7587
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7588
	case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7589
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7590
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7591
	case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7592
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7593
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7594
	case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7595
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7596
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7597
	case NFS4_CHECK_STATEID_UNCONFIRMED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7598
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7599
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7600
	case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7601
		/* Check the sequence id for the open owner */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7602
		switch (rfs4_check_open_seqid(args->seqid, sp->owner, resop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7603
		case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7604
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7605
			 * This is replayed stateid; if seqid matches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7606
			 * next expected, then client is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7607
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7608
			/* fall through */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7609
		case NFS4_CHKSEQ_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7610
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7611
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7612
		case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7613
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7614
			 * Note this case is the duplicate case so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7615
			 * resp->status is already set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7616
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7617
			*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7618
			rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7619
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7620
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7621
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7622
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7623
		ASSERT(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7624
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7625
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7627
	rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7628
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7629
	 * Check that the new access modes and deny modes are valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7630
	 * Check that no invalid bits are set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7631
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7632
	if ((access & ~(OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WRITE)) ||
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7633
	    (deny & ~(OPEN4_SHARE_DENY_READ | OPEN4_SHARE_DENY_WRITE))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7634
		*cs->statusp = resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7635
		rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7636
		rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7637
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7638
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7640
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7641
	 * The new modes must be a subset of the current modes and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7642
	 * the access must specify at least one mode. To test that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7643
	 * the new mode is a subset of the current modes we bitwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7644
	 * AND them together and check that the result equals the new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7645
	 * mode. For example:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7646
	 * New mode, access == R and current mode, sp->share_access  == RW
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7647
	 * access & sp->share_access == R == access, so the new access mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7648
	 * is valid. Consider access == RW, sp->share_access = R
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7649
	 * access & sp->share_access == R != access, so the new access mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7650
	 * is invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7651
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7652
	if ((access & sp->share_access) != access ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7653
	    (deny & sp->share_deny) != deny ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7654
	    (access &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7655
	    (OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WRITE)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7656
		*cs->statusp = resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7657
		rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7658
		rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7659
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7660
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7662
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7663
	 * Release any share locks associated with this stateID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7664
	 * Strictly speaking, this violates the spec because the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7665
	 * spec effectively requires that open downgrade be atomic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7666
	 * At present, fs_shrlock does not have this capability.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7667
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7668
	rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7669
	rfs4_unshare(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7670
	rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7671
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7672
	fp = sp->finfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7673
	rfs4_dbe_lock(fp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7675
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7676
	 * If the current mode has deny read and the new mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7677
	 * does not, decrement the number of deny read mode bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7678
	 * and if it goes to zero turn off the deny read bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7679
	 * on the file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7680
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7681
	if ((sp->share_deny & OPEN4_SHARE_DENY_READ) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7682
	    (deny & OPEN4_SHARE_DENY_READ) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7683
		fp->deny_read--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7684
		if (fp->deny_read == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7685
			fp->share_deny &= ~OPEN4_SHARE_DENY_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7686
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7688
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7689
	 * If the current mode has deny write and the new mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7690
	 * does not, decrement the number of deny write mode bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7691
	 * and if it goes to zero turn off the deny write bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7692
	 * on the file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7693
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7694
	if ((sp->share_deny & OPEN4_SHARE_DENY_WRITE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7695
	    (deny & OPEN4_SHARE_DENY_WRITE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7696
		fp->deny_write--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7697
		if (fp->deny_write == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7698
			fp->share_deny &= ~OPEN4_SHARE_DENY_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7699
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7701
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7702
	 * If the current mode has access read and the new mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7703
	 * does not, decrement the number of access read mode bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7704
	 * and if it goes to zero turn off the access read bit
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7705
	 * on the file.  set fflags to FREAD for the call to
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7706
	 * vn_open_downgrade().
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7707
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7708
	if ((sp->share_access & OPEN4_SHARE_ACCESS_READ) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7709
	    (access & OPEN4_SHARE_ACCESS_READ) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7710
		fp->access_read--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7711
		if (fp->access_read == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7712
			fp->share_access &= ~OPEN4_SHARE_ACCESS_READ;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7713
		fflags |= FREAD;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7714
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7716
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7717
	 * If the current mode has access write and the new mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7718
	 * does not, decrement the number of access write mode bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7719
	 * and if it goes to zero turn off the access write bit
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7720
	 * on the file.  set fflags to FWRITE for the call to
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7721
	 * vn_open_downgrade().
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7722
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7723
	if ((sp->share_access & OPEN4_SHARE_ACCESS_WRITE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7724
	    (access & OPEN4_SHARE_ACCESS_WRITE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7725
		fp->access_write--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7726
		if (fp->access_write == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7727
			fp->share_deny &= ~OPEN4_SHARE_ACCESS_WRITE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7728
		fflags |= FWRITE;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7729
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7731
	/* Set the new access and deny modes */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7732
	sp->share_access = access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7733
	sp->share_deny = deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7734
	/* Check that the file is still accessible */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7735
	ASSERT(fp->share_access);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7737
	rfs4_dbe_unlock(fp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7739
	rfs4_dbe_unlock(sp->dbe);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7740
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7741
	if ((status = rfs4_share(sp)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7742
		*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7743
		rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7744
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7745
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7746
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7747
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7748
	 * we successfully downgraded the share lock, now we need to downgrade
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7749
	 * the open.  it is possible that the downgrade was only for a deny
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7750
	 * mode and we have nothing else to do.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7751
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7752
	if ((fflags & (FREAD|FWRITE)) != 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7753
		vn_open_downgrade(cs->vp, fflags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  7754
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7755
	rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7756
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7757
	/* Update the stateid */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7758
	next_stateid(&sp->stateid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7759
	resp->open_stateid = sp->stateid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7760
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7761
	rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7762
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7763
	*cs->statusp = resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7764
	/* Update the lease */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7765
	rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7766
	/* And the sequence */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7767
	rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7768
	rfs4_update_open_resp(sp->owner, resop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7770
end:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7771
	rfs4_sw_exit(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7772
	rfs4_state_rele(sp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7773
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7774
	DTRACE_NFSV4_2(op__open__downgrade__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7775
	    OPEN_DOWNGRADE4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7776
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7778
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7779
 * The logic behind this function is detailed in the NFSv4 RFC in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7780
 * SETCLIENTID operation description under IMPLEMENTATION.  Refer to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7781
 * that section for explicit guidance to server behavior for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7782
 * SETCLIENTID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7783
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7784
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7785
rfs4_op_setclientid(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7786
		    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7787
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7788
	SETCLIENTID4args *args = &argop->nfs_argop4_u.opsetclientid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7789
	SETCLIENTID4res *res = &resop->nfs_resop4_u.opsetclientid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7790
	rfs4_client_t *cp, *newcp, *cp_confirmed, *cp_unconfirmed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7791
	bool_t create = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7792
	char *addr, *netid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7793
	int len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7794
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7795
	DTRACE_NFSV4_2(op__setclientid__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7796
	    SETCLIENTID4args *, args);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7797
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7798
	newcp = cp_confirmed = cp_unconfirmed = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7800
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7801
	 * In search of an EXISTING client matching the incoming
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7802
	 * request to establish a new client identifier at the server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7803
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7804
	create = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7805
	cp = rfs4_findclient(&args->client, &create, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7807
	/* Should never happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7808
	ASSERT(cp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7810
	if (cp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7811
		*cs->statusp = res->status = NFS4ERR_SERVERFAULT;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7812
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7813
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7815
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7816
	 * Easiest case. Client identifier is newly created and is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7817
	 * unconfirmed.  Also note that for this case, no other
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7818
	 * entries exist for the client identifier.  Nothing else to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7819
	 * check.  Just setup the response and respond.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7820
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7821
	if (create) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7822
		*cs->statusp = res->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7823
		res->SETCLIENTID4res_u.resok4.clientid = cp->clientid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7824
		res->SETCLIENTID4res_u.resok4.setclientid_confirm =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7825
		    cp->confirm_verf;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7826
		/* Setup callback information; CB_NULL confirmation later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7827
		rfs4_client_setcb(cp, &args->callback, args->callback_ident);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7829
		rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7830
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7831
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7833
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7834
	 * An existing, confirmed client may exist but it may not have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7835
	 * been active for at least one lease period.  If so, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7836
	 * "close" the client and create a new client identifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7837
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7838
	if (rfs4_lease_expired(cp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7839
		rfs4_client_close(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7840
		goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7841
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7843
	if (cp->need_confirm == TRUE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7844
		cp_unconfirmed = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7845
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7846
		cp_confirmed = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7848
	cp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7850
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7851
	 * We have a confirmed client, now check for an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7852
	 * unconfimred entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7853
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7854
	if (cp_confirmed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7855
		/* If creds don't match then client identifier is inuse */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7856
		if (!creds_ok(cp_confirmed->cr_set, req, cs)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7857
			rfs4_cbinfo_t *cbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7858
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7859
			 * Some one else has established this client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7860
			 * id. Try and say * who they are. We will use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7861
			 * the call back address supplied by * the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7862
			 * first client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7863
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7864
			*cs->statusp = res->status = NFS4ERR_CLID_INUSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7866
			addr = netid = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7868
			cbp = &cp_confirmed->cbinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7869
			if (cbp->cb_callback.cb_location.r_addr &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7870
			    cbp->cb_callback.cb_location.r_netid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7871
				cb_client4 *cbcp = &cbp->cb_callback;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7872
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7873
				len = strlen(cbcp->cb_location.r_addr)+1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7874
				addr = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7875
				bcopy(cbcp->cb_location.r_addr, addr, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7876
				len = strlen(cbcp->cb_location.r_netid)+1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7877
				netid = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7878
				bcopy(cbcp->cb_location.r_netid, netid, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7879
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7880
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7881
			res->SETCLIENTID4res_u.client_using.r_addr = addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7882
			res->SETCLIENTID4res_u.client_using.r_netid = netid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7884
			rfs4_client_rele(cp_confirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7885
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7887
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7888
		 * Confirmed, creds match, and verifier matches; must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7889
		 * be an update of the callback info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7890
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7891
		if (cp_confirmed->nfs_client.verifier ==
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7892
		    args->client.verifier) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7893
			/* Setup callback information */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7894
			rfs4_client_setcb(cp_confirmed, &args->callback,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7895
			    args->callback_ident);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7897
			/* everything okay -- move ahead */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7898
			*cs->statusp = res->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7899
			res->SETCLIENTID4res_u.resok4.clientid =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7900
			    cp_confirmed->clientid;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7901
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7902
			/* update the confirm_verifier and return it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7903
			rfs4_client_scv_next(cp_confirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7904
			res->SETCLIENTID4res_u.resok4.setclientid_confirm =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7905
			    cp_confirmed->confirm_verf;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7906
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7907
			rfs4_client_rele(cp_confirmed);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7908
			goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7909
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7911
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7912
		 * Creds match but the verifier doesn't.  Must search
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7913
		 * for an unconfirmed client that would be replaced by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7914
		 * this request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7915
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7916
		create = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7917
		cp_unconfirmed = rfs4_findclient(&args->client, &create,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7918
		    cp_confirmed);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7919
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7921
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7922
	 * At this point, we have taken care of the brand new client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7923
	 * struct, INUSE case, update of an existing, and confirmed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7924
	 * client struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7925
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7926
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7927
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7928
	 * check to see if things have changed while we originally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7929
	 * picked up the client struct.  If they have, then return and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7930
	 * retry the processing of this SETCLIENTID request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7931
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7932
	if (cp_unconfirmed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7933
		rfs4_dbe_lock(cp_unconfirmed->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7934
		if (!cp_unconfirmed->need_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7935
			rfs4_dbe_unlock(cp_unconfirmed->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7936
			rfs4_client_rele(cp_unconfirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7937
			if (cp_confirmed)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7938
				rfs4_client_rele(cp_confirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7939
			goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7940
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7941
		/* do away with the old unconfirmed one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7942
		rfs4_dbe_invalidate(cp_unconfirmed->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7943
		rfs4_dbe_unlock(cp_unconfirmed->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7944
		rfs4_client_rele(cp_unconfirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7945
		cp_unconfirmed = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7946
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7947
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7948
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7949
	 * This search will temporarily hide the confirmed client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7950
	 * struct while a new client struct is created as the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7951
	 * unconfirmed one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7952
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7953
	create = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7954
	newcp = rfs4_findclient(&args->client, &create, cp_confirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7955
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7956
	ASSERT(newcp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7958
	if (newcp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7959
		*cs->statusp = res->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7960
		rfs4_client_rele(cp_confirmed);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7961
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7962
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7964
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7965
	 * If one was not created, then a similar request must be in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7966
	 * process so release and start over with this one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7967
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7968
	if (create != TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7969
		rfs4_client_rele(newcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7970
		if (cp_confirmed)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7971
			rfs4_client_rele(cp_confirmed);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7972
		goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7973
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7974
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7975
	*cs->statusp = res->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7976
	res->SETCLIENTID4res_u.resok4.clientid = newcp->clientid;
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7977
	res->SETCLIENTID4res_u.resok4.setclientid_confirm = newcp->confirm_verf;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7978
	/* Setup callback information; CB_NULL confirmation later */
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7979
	rfs4_client_setcb(newcp, &args->callback, args->callback_ident);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7980
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7981
	newcp->cp_confirmed = cp_confirmed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7983
	rfs4_client_rele(newcp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7984
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7985
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7986
	DTRACE_NFSV4_2(op__setclientid__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  7987
	    SETCLIENTID4res *, res);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7988
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7990
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7991
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7992
rfs4_op_setclientid_confirm(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7993
			    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7994
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7995
	SETCLIENTID_CONFIRM4args *args =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7996
	    &argop->nfs_argop4_u.opsetclientid_confirm;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7997
	SETCLIENTID_CONFIRM4res *res =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  7998
	    &resop->nfs_resop4_u.opsetclientid_confirm;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  7999
	rfs4_client_t *cp, *cptoclose = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8000
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8001
	DTRACE_NFSV4_2(op__setclientid__confirm__start,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8002
	    struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8003
	    SETCLIENTID_CONFIRM4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8004
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8005
	*cs->statusp = res->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8007
	cp = rfs4_findclient_by_id(args->clientid, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8009
	if (cp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8010
		*cs->statusp = res->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8011
		    rfs4_check_clientid(&args->clientid, 1);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8012
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8013
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8014
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8015
	if (!creds_ok(cp, req, cs)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8016
		*cs->statusp = res->status = NFS4ERR_CLID_INUSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8017
		rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8018
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8019
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8021
	/* If the verifier doesn't match, the record doesn't match */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8022
	if (cp->confirm_verf != args->setclientid_confirm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8023
		*cs->statusp = res->status = NFS4ERR_STALE_CLIENTID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8024
		rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8025
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8026
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8027
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8028
	rfs4_dbe_lock(cp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8029
	cp->need_confirm = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8030
	if (cp->cp_confirmed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8031
		cptoclose = cp->cp_confirmed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8032
		cptoclose->ss_remove = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8033
		cp->cp_confirmed = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8034
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8036
	/*
2035
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8037
	 * Update the client's associated server instance, if it's changed
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8038
	 * since the client was created.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8039
	 */
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8040
	if (rfs4_servinst(cp) != rfs4_cur_servinst)
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8041
		rfs4_servinst_assign(cp, rfs4_cur_servinst);
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8042
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8043
	/*
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8044
	 * Record clientid in stable storage.
a29bc457bcb9 PSARC/2006/313 NFSv4: nfsd "-s" distributed stable storage
calum
parents: 1676
diff changeset
  8045
	 * Must be done after server instance has been assigned.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8046
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8047
	rfs4_ss_clid(cp, req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8049
	rfs4_dbe_unlock(cp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8050
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8051
	if (cptoclose)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8052
		/* don't need to rele, client_close does it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8053
		rfs4_client_close(cptoclose);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8055
	/* If needed, initiate CB_NULL call for callback path */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8056
	rfs4_deleg_cb_check(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8057
	rfs4_update_lease(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8059
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8060
	 * Check to see if client can perform reclaims
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8061
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8062
	rfs4_ss_chkclid(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8064
	rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8065
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8066
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8067
	DTRACE_NFSV4_2(op__setclientid__confirm__done,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8068
	    struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8069
	    SETCLIENTID_CONFIRM4 *, res);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8070
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8073
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8074
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8075
rfs4_op_close(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8076
	    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8077
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8078
	CLOSE4args *args = &argop->nfs_argop4_u.opclose;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8079
	CLOSE4res *resp = &resop->nfs_resop4_u.opclose;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8080
	rfs4_state_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8081
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8082
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8083
	DTRACE_NFSV4_2(op__close__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8084
	    CLOSE4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8085
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8086
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8087
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8088
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8089
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8091
	status = rfs4_get_state(&args->open_stateid, &sp, RFS4_DBS_INVALID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8092
	if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8093
		*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8094
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8095
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8097
	/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8098
	if (cs->vp != sp->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8099
		rfs4_state_rele(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8100
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8101
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8102
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8104
	/* hold off other access to open_owner while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8105
	rfs4_sw_enter(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8107
	switch (rfs4_check_stateid_seqid(sp, &args->open_stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8108
	case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8109
		if (rfs4_check_open_seqid(args->seqid, sp->owner,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8110
		    resop) != NFS4_CHKSEQ_OKAY) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8111
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8112
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8113
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8114
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8115
	case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8116
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8117
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8118
	case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8119
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8120
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8121
	case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8122
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8123
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8124
	case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8125
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8126
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8127
	case NFS4_CHECK_STATEID_UNCONFIRMED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8128
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8129
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8130
	case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8131
		/* Check the sequence id for the open owner */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8132
		switch (rfs4_check_open_seqid(args->seqid, sp->owner, resop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8133
		case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8134
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8135
			 * This is replayed stateid; if seqid matches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8136
			 * next expected, then client is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8137
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8138
			/* FALL THROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8139
		case NFS4_CHKSEQ_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8140
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8141
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8142
		case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8143
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8144
			 * Note this case is the duplicate case so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8145
			 * resp->status is already set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8146
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8147
			*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8148
			rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8149
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8150
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8151
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8152
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8153
		ASSERT(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8154
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8155
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8157
	rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8159
	/* Update the stateid. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8160
	next_stateid(&sp->stateid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8161
	resp->open_stateid = sp->stateid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8163
	rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8165
	rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8166
	rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8167
	rfs4_update_open_resp(sp->owner, resop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8169
	rfs4_state_close(sp, FALSE, FALSE, cs->cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8171
	*cs->statusp = resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8173
end:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8174
	rfs4_sw_exit(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8175
	rfs4_state_rele(sp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8176
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8177
	DTRACE_NFSV4_2(op__close__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8178
	    CLOSE4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8179
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8181
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8182
 * Manage the counts on the file struct and close all file locks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8183
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8184
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8185
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8186
rfs4_release_share_lock_state(rfs4_state_t *sp, cred_t *cr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8187
	bool_t close_of_client)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8188
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8189
	rfs4_file_t *fp = sp->finfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8190
	rfs4_lo_state_t *lsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8191
	struct shrlock shr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8192
	struct shr_locowner shr_loco;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8193
	int fflags, s_access, s_deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8195
	fflags = s_access = s_deny = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8196
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8197
	 * Decrement the count for each access and deny bit that this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8198
	 * state has contributed to the file. If the file counts go to zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8199
	 * clear the appropriate bit in the appropriate mask.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8200
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8202
	if (sp->share_access & OPEN4_SHARE_ACCESS_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8203
		fp->access_read--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8204
		fflags |= FREAD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8205
		s_access |= F_RDACC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8206
		if (fp->access_read == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8207
			fp->share_access &= ~OPEN4_SHARE_ACCESS_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8208
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8209
	if (sp->share_access & OPEN4_SHARE_ACCESS_WRITE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8210
		fp->access_write--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8211
		fflags |= FWRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8212
		s_access |= F_WRACC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8213
		if (fp->access_write == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8214
			fp->share_access &= ~OPEN4_SHARE_ACCESS_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8215
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8216
	if (sp->share_deny & OPEN4_SHARE_DENY_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8217
		fp->deny_read--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8218
		s_deny |= F_RDDNY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8219
		if (fp->deny_read == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8220
			fp->share_deny &= ~OPEN4_SHARE_DENY_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8221
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8222
	if (sp->share_deny & OPEN4_SHARE_DENY_WRITE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8223
		fp->deny_write--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8224
		s_deny |= F_WRDNY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8225
		if (fp->deny_write == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8226
			fp->share_deny &= ~OPEN4_SHARE_DENY_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8227
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8228
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8229
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8230
	 * If this call is part of the larger closing down of client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8231
	 * state then it is just easier to release all locks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8232
	 * associated with this client instead of going through each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8233
	 * individual file and cleaning locks there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8234
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8235
	if (close_of_client) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8236
		if (sp->owner->client->unlksys_completed == FALSE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8237
		    sp->lockownerlist.next->lsp != NULL &&
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8238
		    sp->owner->client->sysidt != LM_NOSYSID) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8239
			/* Is the PxFS kernel module loaded? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8240
			if (lm_remove_file_locks != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8241
				int new_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8243
				/* Encode the cluster nodeid in new sysid */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8244
				new_sysid = sp->owner->client->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8245
				lm_set_nlmid_flk(&new_sysid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8247
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8248
				 * This PxFS routine removes file locks for a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8249
				 * client over all nodes of a cluster.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8250
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8251
				NFS4_DEBUG(rfs4_debug, (CE_NOTE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8252
				    "lm_remove_file_locks(sysid=0x%x)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8253
				    new_sysid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8254
				(*lm_remove_file_locks)(new_sysid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8255
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8256
				struct flock64 flk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8258
				/* Release all locks for this client */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8259
				flk.l_type = F_UNLKSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8260
				flk.l_whence = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8261
				flk.l_start = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8262
				flk.l_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8263
				flk.l_sysid = sp->owner->client->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8264
				flk.l_pid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8265
				(void) VOP_FRLOCK(sp->finfo->vp, F_SETLK, &flk,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8266
				    F_REMOTELOCK | FREAD | FWRITE,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8267
				    (u_offset_t)0, NULL, CRED(), NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8268
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8270
			sp->owner->client->unlksys_completed = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8271
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8272
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8274
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8275
	 * Release all locks on this file by this lock owner or at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8276
	 * least mark the locks as having been released
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8277
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8278
	for (lsp = sp->lockownerlist.next->lsp; lsp != NULL;
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8279
	    lsp = lsp->lockownerlist.next->lsp) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8281
		lsp->locks_cleaned = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8283
		/* Was this already taken care of above? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8284
		if (!close_of_client &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8285
		    sp->owner->client->sysidt != LM_NOSYSID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8286
			(void) cleanlocks(sp->finfo->vp, lsp->locker->pid,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8287
			    lsp->locker->client->sysidt);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8288
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8290
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8291
	 * Release any shrlocks associated with this open state ID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8292
	 * This must be done before the rfs4_state gets marked closed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8293
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8294
	if (sp->owner->client->sysidt != LM_NOSYSID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8295
		shr.s_access = s_access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8296
		shr.s_deny = s_deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8297
		shr.s_pid = rfs4_dbe_getid(sp->owner->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8298
		shr.s_sysid = sp->owner->client->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8299
		shr_loco.sl_pid = shr.s_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8300
		shr_loco.sl_id = shr.s_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8301
		shr.s_owner = (caddr_t)&shr_loco;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8302
		shr.s_own_len = sizeof (shr_loco);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8303
		(void) vop_shrlock(sp->finfo->vp, F_UNSHARE, &shr, fflags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8304
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8305
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8306
	(void) VOP_CLOSE(fp->vp, fflags, 1, (offset_t)0, cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8307
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8309
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8310
 * lock_denied: Fill in a LOCK4deneid structure given an flock64 structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8311
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8312
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8313
lock_denied(LOCK4denied *dp, struct flock64 *flk)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8314
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8315
	rfs4_lockowner_t *lo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8316
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8317
	uint32_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8319
	lo = rfs4_findlockowner_by_pid(flk->l_pid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8320
	if (lo != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8321
		cp = lo->client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8322
		if (rfs4_lease_expired(cp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8323
			rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8324
			rfs4_dbe_hold(cp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8325
			rfs4_client_close(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8326
			return (NFS4ERR_EXPIRED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8327
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8328
		dp->owner.clientid = lo->owner.clientid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8329
		len = lo->owner.owner_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8330
		dp->owner.owner_val = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8331
		bcopy(lo->owner.owner_val, dp->owner.owner_val, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8332
		dp->owner.owner_len = len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8333
		rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8334
		goto finish;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8335
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8337
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8338
	 * Its not a NFS4 lock. We take advantage that the upper 32 bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8339
	 * of the client id contain the boot time for a NFS4 lock. So we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8340
	 * fabricate and identity by setting clientid to the sysid, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8341
	 * the lock owner to the pid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8342
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8343
	dp->owner.clientid = flk->l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8344
	len = sizeof (pid_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8345
	dp->owner.owner_len = len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8346
	dp->owner.owner_val = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8347
	bcopy(&flk->l_pid, dp->owner.owner_val, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8348
finish:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8349
	dp->offset = flk->l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8350
	dp->length = flk->l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8352
	if (flk->l_type == F_RDLCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8353
		dp->locktype = READ_LT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8354
	else if (flk->l_type == F_WRLCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8355
		dp->locktype = WRITE_LT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8356
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8357
		return (NFS4ERR_INVAL);	/* no mapping from POSIX ltype to v4 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8359
	return (NFS4_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8360
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8362
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8363
setlock(vnode_t *vp, struct flock64 *flock, int flag, cred_t *cred)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8364
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8365
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8366
	struct flock64 flk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8367
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8368
	clock_t delaytime;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8369
	int cmd;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8370
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8371
	cmd = nbl_need_check(vp) ? F_SETLK_NBMAND : F_SETLK;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8372
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8373
	delaytime = MSEC_TO_TICK_ROUNDUP(rfs4_lock_delay);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8375
	for (i = 0; i < rfs4_maxlock_tries; i++) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8376
		LOCK_PRINT(rfs4_debug, "setlock", cmd, flock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8377
		error = VOP_FRLOCK(vp, cmd,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8378
		    flock, flag, (u_offset_t)0, NULL, cred, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8380
		if (error != EAGAIN && error != EACCES)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8381
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8383
		if (i < rfs4_maxlock_tries - 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8384
			delay(delaytime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8385
			delaytime *= 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8386
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8387
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8389
	if (error == EAGAIN || error == EACCES) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8390
		/* Get the owner of the lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8391
		flk = *flock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8392
		LOCK_PRINT(rfs4_debug, "setlock", F_GETLK, &flk);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8393
		if (VOP_FRLOCK(vp, F_GETLK, &flk, flag,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  8394
		    (u_offset_t)0, NULL, cred, NULL) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8395
			if (flk.l_type == F_UNLCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8396
				/* No longer locked, retry */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8397
				goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8398
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8399
			*flock = flk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8400
			LOCK_PRINT(rfs4_debug, "setlock(blocking lock)",
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8401
			    F_GETLK, &flk);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8402
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8403
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8405
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8406
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8408
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8409
static nfsstat4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8410
rfs4_do_lock(rfs4_lo_state_t *lp, nfs_lock_type4 locktype,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8411
	    seqid4 seqid, offset4 offset,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8412
	    length4 length, cred_t *cred, nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8413
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8414
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8415
	rfs4_lockowner_t *lo = lp->locker;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8416
	rfs4_state_t *sp = lp->state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8417
	struct flock64 flock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8418
	int16_t ltype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8419
	int flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8420
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8421
	sysid_t sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8422
	LOCK4res *lres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8424
	if (rfs4_lease_expired(lo->client)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8425
		return (NFS4ERR_EXPIRED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8426
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8428
	if ((status = rfs4_client_sysid(lo->client, &sysid)) != NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8429
		return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8431
	/* Check for zero length. To lock to end of file use all ones for V4 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8432
	if (length == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8433
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8434
	else if (length == (length4)(~0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8435
		length = 0;		/* Posix to end of file  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8437
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8438
	rfs4_dbe_lock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8441
	if (resop->resop != OP_LOCKU) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8442
		switch (locktype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8443
		case READ_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8444
		case READW_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8445
			if ((sp->share_access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8446
			    & OPEN4_SHARE_ACCESS_READ) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8447
				rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8449
				return (NFS4ERR_OPENMODE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8450
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8451
			ltype = F_RDLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8452
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8453
		case WRITE_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8454
		case WRITEW_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8455
			if ((sp->share_access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8456
			    & OPEN4_SHARE_ACCESS_WRITE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8457
				rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8459
				return (NFS4ERR_OPENMODE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8460
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8461
			ltype = F_WRLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8462
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8463
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8464
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8465
		ltype = F_UNLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8467
	flock.l_type = ltype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8468
	flock.l_whence = 0;		/* SEEK_SET */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8469
	flock.l_start = offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8470
	flock.l_len = length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8471
	flock.l_sysid = sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8472
	flock.l_pid = lp->locker->pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8474
	/* Note that length4 is uint64_t but l_len and l_start are off64_t */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8475
	if (flock.l_len < 0 || flock.l_start < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8476
		rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8477
		return (NFS4ERR_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8478
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8479
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8480
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8481
	 * N.B. FREAD has the same value as OPEN4_SHARE_ACCESS_READ and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8482
	 * FWRITE has the same value as OPEN4_SHARE_ACCESS_WRITE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8483
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8484
	flag = (int)sp->share_access | F_REMOTELOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8486
	error = setlock(sp->finfo->vp, &flock, flag, cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8487
	if (error == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8488
		rfs4_dbe_lock(lp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8489
		next_stateid(&lp->lockid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8490
		rfs4_dbe_unlock(lp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8491
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8493
	rfs4_dbe_unlock(sp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8495
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8496
	 * N.B. We map error values to nfsv4 errors. This is differrent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8497
	 * than puterrno4 routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8498
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8499
	switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8500
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8501
		status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8502
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8503
	case EAGAIN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8504
	case EACCES:		/* Old value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8505
		/* Can only get here if op is OP_LOCK */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8506
		ASSERT(resop->resop == OP_LOCK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8507
		lres = &resop->nfs_resop4_u.oplock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8508
		status = NFS4ERR_DENIED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8509
		if (lock_denied(&lres->LOCK4res_u.denied, &flock)
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8510
		    == NFS4ERR_EXPIRED)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8511
			goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8512
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8513
	case ENOLCK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8514
		status = NFS4ERR_DELAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8515
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8516
	case EOVERFLOW:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8517
		status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8518
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8519
	case EINVAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8520
		status = NFS4ERR_NOTSUPP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8521
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8522
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8523
		status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8524
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8525
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8527
	return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8528
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8530
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8531
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8532
rfs4_op_lock(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8533
	    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8534
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8535
	LOCK4args *args = &argop->nfs_argop4_u.oplock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8536
	LOCK4res *resp = &resop->nfs_resop4_u.oplock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8537
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8538
	stateid4 *stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8539
	rfs4_lockowner_t *lo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8540
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8541
	rfs4_state_t *sp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8542
	rfs4_lo_state_t *lsp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8543
	bool_t ls_sw_held = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8544
	bool_t create = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8545
	bool_t lcreate = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8546
	bool_t dup_lock = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8547
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8548
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8549
	DTRACE_NFSV4_2(op__lock__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8550
	    LOCK4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8551
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8552
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8553
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8554
		DTRACE_NFSV4_2(op__lock__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8555
		    cs, LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8556
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8557
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8559
	if (args->locker.new_lock_owner) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8560
		/* Create a new lockowner for this instance */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8561
		open_to_lock_owner4 *olo = &args->locker.locker4_u.open_owner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8563
		NFS4_DEBUG(rfs4_debug, (CE_NOTE, "Creating new lock owner"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8564
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8565
		stateid = &olo->open_stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8566
		status = rfs4_get_state(stateid, &sp, RFS4_DBS_VALID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8567
		if (status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8568
			NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8569
			    (CE_NOTE, "Get state failed in lock %d", status));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8570
			*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8571
			DTRACE_NFSV4_2(op__lock__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8572
			    cs, LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8573
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8574
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8575
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8576
		/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8577
		if (cs->vp != sp->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8578
			rfs4_state_rele(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8579
			*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8580
			DTRACE_NFSV4_2(op__lock__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8581
			    cs, LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8582
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8583
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8585
		/* hold off other access to open_owner while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8586
		rfs4_sw_enter(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8588
		switch (rc = rfs4_check_stateid_seqid(sp, stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8589
		case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8590
			*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8591
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8592
		case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8593
			*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8594
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8595
		case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8596
			*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8597
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8598
		case NFS4_CHECK_STATEID_UNCONFIRMED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8599
			*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8600
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8601
		case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8602
			*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8603
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8604
		case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8605
		case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8606
			switch (rfs4_check_olo_seqid(olo->open_seqid,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8607
			    sp->owner, resop)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8608
			case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8609
				if (rc == NFS4_CHECK_STATEID_OKAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8610
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8611
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8612
				 * This is replayed stateid; if seqid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8613
				 * matches next expected, then client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8614
				 * is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8615
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8616
				/* FALLTHROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8617
			case NFS4_CHKSEQ_BAD:
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8618
				*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8619
				goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8620
			case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8621
				/* This is a duplicate LOCK request */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8622
				dup_lock = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8624
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8625
				 * For a duplicate we do not want to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8626
				 * create a new lockowner as it should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8627
				 * already exist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8628
				 * Turn off the lockowner create flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8629
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8630
				lcreate = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8631
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8632
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8633
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8635
		lo = rfs4_findlockowner(&olo->lock_owner, &lcreate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8636
		if (lo == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8637
			NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8638
			    (CE_NOTE, "rfs4_op_lock: no lock owner"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8639
			*cs->statusp = resp->status = NFS4ERR_RESOURCE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8640
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8641
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8643
		lsp = rfs4_findlo_state_by_owner(lo, sp, &create);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8644
		if (lsp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8645
			rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8646
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8647
			 * Only update theh open_seqid if this is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8648
			 * a duplicate request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8649
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8650
			if (dup_lock == FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8651
				rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8652
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8654
			NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8655
			    (CE_NOTE, "rfs4_op_lock: no state"));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8656
			*cs->statusp = resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8657
			rfs4_update_open_resp(sp->owner, resop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8658
			rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8659
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8660
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8662
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8663
		 * This is the new_lock_owner branch and the client is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8664
		 * supposed to be associating a new lock_owner with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8665
		 * the open file at this point.  If we find that a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8666
		 * lock_owner/state association already exists and a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8667
		 * successful LOCK request was returned to the client,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8668
		 * an error is returned to the client since this is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8669
		 * not appropriate.  The client should be using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8670
		 * existing lock_owner branch.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8671
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8672
		if (dup_lock == FALSE && create == FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8673
			if (lsp->lock_completed == TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8674
				*cs->statusp =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8675
				    resp->status = NFS4ERR_BAD_SEQID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8676
				rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8677
				goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8678
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8679
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8681
		rfs4_update_lease(sp->owner->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8683
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8684
		 * Only update theh open_seqid if this is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8685
		 * a duplicate request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8686
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8687
		if (dup_lock == FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8688
			rfs4_update_open_sequence(sp->owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8689
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8691
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8692
		 * If this is a duplicate lock request, just copy the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8693
		 * previously saved reply and return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8694
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8695
		if (dup_lock == TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8696
			/* verify that lock_seqid's match */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8697
			if (lsp->seqid != olo->lock_seqid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8698
				NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8699
				    (CE_NOTE, "rfs4_op_lock: Dup-Lock seqid bad"
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8700
				    "lsp->seqid=%d old->seqid=%d",
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8701
				    lsp->seqid, olo->lock_seqid));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8702
				*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8703
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8704
				rfs4_copy_reply(resop, lsp->reply);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8705
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8706
				 * Make sure to copy the just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8707
				 * retrieved reply status into the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8708
				 * overall compound status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8709
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8710
				*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8711
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8712
			rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8713
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8714
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8716
		rfs4_dbe_lock(lsp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8717
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8718
		/* Make sure to update the lock sequence id */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8719
		lsp->seqid = olo->lock_seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8721
		NFS4_DEBUG(rfs4_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8722
		    (CE_NOTE, "Lock seqid established as %d", lsp->seqid));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8724
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8725
		 * This is used to signify the newly created lockowner
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8726
		 * stateid and its sequence number.  The checks for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8727
		 * sequence number and increment don't occur on the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8728
		 * very first lock request for a lockowner.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8729
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8730
		lsp->skip_seqid_check = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8732
		/* hold off other access to lsp while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8733
		rfs4_sw_enter(&lsp->ls_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8734
		ls_sw_held = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8736
		rfs4_dbe_unlock(lsp->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8738
		rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8739
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8740
		stateid = &args->locker.locker4_u.lock_owner.lock_stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8741
		/* get lsp and hold the lock on the underlying file struct */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8742
		if ((status = rfs4_get_lo_state(stateid, &lsp, TRUE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8743
		    != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8744
			*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8745
			DTRACE_NFSV4_2(op__lock__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8746
			    cs, LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8747
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8748
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8749
		create = FALSE;	/* We didn't create lsp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8751
		/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8752
		if (cs->vp != lsp->state->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8753
			rfs4_lo_state_rele(lsp, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8754
			*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8755
			DTRACE_NFSV4_2(op__lock__done, struct compound_state *,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8756
			    cs, LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8757
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8758
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8760
		/* hold off other access to lsp while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8761
		rfs4_sw_enter(&lsp->ls_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8762
		ls_sw_held = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8764
		switch (rfs4_check_lo_stateid_seqid(lsp, stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8765
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8766
		 * The stateid looks like it was okay (expected to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8767
		 * the next one)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8768
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8769
		case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8770
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8771
			 * The sequence id is now checked.  Determine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8772
			 * if this is a replay or if it is in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8773
			 * expected (next) sequence.  In the case of a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8774
			 * replay, there are two replay conditions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8775
			 * that may occur.  The first is the normal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8776
			 * condition where a LOCK is done with a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8777
			 * NFS4_OK response and the stateid is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8778
			 * updated.  That case is handled below when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8779
			 * the stateid is identified as a REPLAY.  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8780
			 * second is the case where an error is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8781
			 * returned, like NFS4ERR_DENIED, and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8782
			 * sequence number is updated but the stateid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8783
			 * is not updated.  This second case is dealt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8784
			 * with here.  So it may seem odd that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8785
			 * stateid is okay but the sequence id is a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8786
			 * replay but it is okay.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8787
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8788
			switch (rfs4_check_lock_seqid(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8789
			    args->locker.locker4_u.lock_owner.lock_seqid,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8790
			    lsp, resop)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8791
			case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8792
				if (resp->status != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8793
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8794
					 * Here is our replay and need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8795
					 * to verify that the last
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8796
					 * response was an error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8797
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8798
					*cs->statusp = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8799
					goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8800
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8801
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8802
				 * This is done since the sequence id
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8803
				 * looked like a replay but it didn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8804
				 * pass our check so a BAD_SEQID is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8805
				 * returned as a result.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8806
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8807
				/*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8808
			case NFS4_CHKSEQ_BAD:
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8809
				*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8810
				goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8811
			case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8812
				/* Everything looks okay move ahead */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8813
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8814
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8815
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8816
		case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8817
			*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8818
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8819
		case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8820
			*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8821
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8822
		case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8823
			*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8824
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8825
		case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8826
			*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8827
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8828
		case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8829
			switch (rfs4_check_lock_seqid(
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8830
			    args->locker.locker4_u.lock_owner.lock_seqid,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8831
			    lsp, resop)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8832
			case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8833
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8834
				 * This is a replayed stateid; if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8835
				 * seqid matches the next expected,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8836
				 * then client is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8837
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8838
			case NFS4_CHKSEQ_BAD:
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8839
				*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8840
				goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8841
			case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8842
				rfs4_update_lease(lsp->locker->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8843
				*cs->statusp = status = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8844
				goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8845
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8846
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8847
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8848
			ASSERT(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8849
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8850
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8851
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8852
		rfs4_update_lock_sequence(lsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8853
		rfs4_update_lease(lsp->locker->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8854
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8856
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8857
	 * NFS4 only allows locking on regular files, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8858
	 * verify type of object.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8859
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8860
	if (cs->vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8861
		if (cs->vp->v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8862
			status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8863
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8864
			status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8865
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8866
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8868
	cp = lsp->state->owner->client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8870
	if (rfs4_clnt_in_grace(cp) && !args->reclaim) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8871
		status = NFS4ERR_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8872
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8873
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8875
	if (rfs4_clnt_in_grace(cp) && args->reclaim && !cp->can_reclaim) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8876
		status = NFS4ERR_NO_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8877
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8878
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8880
	if (!rfs4_clnt_in_grace(cp) && args->reclaim) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8881
		status = NFS4ERR_NO_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8882
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8883
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8885
	if (lsp->state->finfo->dinfo->dtype == OPEN_DELEGATE_WRITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8886
		cs->deleg = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8888
	status = rfs4_do_lock(lsp, args->locktype,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8889
	    args->locker.locker4_u.lock_owner.lock_seqid,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  8890
	    args->offset, args->length, cs->cr, resop);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8892
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8893
	lsp->skip_seqid_check = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8894
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8895
	*cs->statusp = resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8897
	if (status == NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8898
		resp->LOCK4res_u.lock_stateid = lsp->lockid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8899
		lsp->lock_completed = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8900
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8901
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8902
	 * Only update the "OPEN" response here if this was a new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8903
	 * lock_owner
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8904
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8905
	if (sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8906
		rfs4_update_open_resp(sp->owner, resop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8908
	rfs4_update_lock_resp(lsp, resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8910
end:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8911
	if (lsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8912
		if (ls_sw_held)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8913
			rfs4_sw_exit(&lsp->ls_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8914
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8915
		 * If an sp obtained, then the lsp does not represent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8916
		 * a lock on the file struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8917
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8918
		if (sp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8919
			rfs4_lo_state_rele(lsp, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8920
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8921
			rfs4_lo_state_rele(lsp, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8922
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8923
	if (sp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8924
		rfs4_sw_exit(&sp->owner->oo_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8925
		rfs4_state_rele(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8926
	}
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8927
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8928
	DTRACE_NFSV4_2(op__lock__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8929
	    LOCK4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8930
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8932
/* free function for LOCK/LOCKT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8933
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8934
lock_denied_free(nfs_resop4 *resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8935
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8936
	LOCK4denied *dp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8937
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8938
	switch (resop->resop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8939
	case OP_LOCK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8940
		if (resop->nfs_resop4_u.oplock.status == NFS4ERR_DENIED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8941
			dp = &resop->nfs_resop4_u.oplock.LOCK4res_u.denied;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8942
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8943
	case OP_LOCKT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8944
		if (resop->nfs_resop4_u.oplockt.status == NFS4ERR_DENIED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8945
			dp = &resop->nfs_resop4_u.oplockt.denied;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8946
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8947
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8948
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8949
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8950
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8951
	if (dp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8952
		kmem_free(dp->owner.owner_val, dp->owner.owner_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8953
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8954
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8955
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8956
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8957
rfs4_op_locku(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8958
	    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8959
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8960
	LOCKU4args *args = &argop->nfs_argop4_u.oplocku;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8961
	LOCKU4res *resp = &resop->nfs_resop4_u.oplocku;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8962
	nfsstat4 status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8963
	stateid4 *stateid = &args->lock_stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8964
	rfs4_lo_state_t *lsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8965
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8966
	DTRACE_NFSV4_2(op__locku__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8967
	    LOCKU4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8968
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8969
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8970
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8971
		DTRACE_NFSV4_2(op__locku__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8972
		    LOCKU4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8973
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8974
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8976
	if ((status = rfs4_get_lo_state(stateid, &lsp, TRUE)) != NFS4_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8977
		*cs->statusp = resp->status = status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8978
		DTRACE_NFSV4_2(op__locku__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8979
		    LOCKU4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8980
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8981
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8983
	/* Ensure specified filehandle matches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8984
	if (cs->vp != lsp->state->finfo->vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8985
		rfs4_lo_state_rele(lsp, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8986
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8987
		DTRACE_NFSV4_2(op__locku__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  8988
		    LOCKU4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8989
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8990
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8991
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8992
	/* hold off other access to lsp while we tinker */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8993
	rfs4_sw_enter(&lsp->ls_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8995
	switch (rfs4_check_lo_stateid_seqid(lsp, stateid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8996
	case NFS4_CHECK_STATEID_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8997
		if (rfs4_check_lock_seqid(args->seqid, lsp, resop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8998
		    != NFS4_CHKSEQ_OKAY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  8999
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9000
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9001
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9002
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9003
	case NFS4_CHECK_STATEID_OLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9004
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9005
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9006
	case NFS4_CHECK_STATEID_BAD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9007
		*cs->statusp = resp->status = NFS4ERR_BAD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9008
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9009
	case NFS4_CHECK_STATEID_EXPIRED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9010
		*cs->statusp = resp->status = NFS4ERR_EXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9011
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9012
	case NFS4_CHECK_STATEID_CLOSED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9013
		*cs->statusp = resp->status = NFS4ERR_OLD_STATEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9014
		goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9015
	case NFS4_CHECK_STATEID_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9016
		switch (rfs4_check_lock_seqid(args->seqid, lsp, resop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9017
		case NFS4_CHKSEQ_OKAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9018
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9019
				 * This is a replayed stateid; if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9020
				 * seqid matches the next expected,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9021
				 * then client is using wrong seqid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9022
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9023
		case NFS4_CHKSEQ_BAD:
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9024
			*cs->statusp = resp->status = NFS4ERR_BAD_SEQID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9025
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9026
		case NFS4_CHKSEQ_REPLAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9027
			rfs4_update_lease(lsp->locker->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9028
			*cs->statusp = status = resp->status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9029
			goto end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9030
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9031
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9032
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9033
		ASSERT(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9034
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9035
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9036
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9037
	rfs4_update_lock_sequence(lsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9038
	rfs4_update_lease(lsp->locker->client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9039
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9040
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9041
	 * NFS4 only allows locking on regular files, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9042
	 * verify type of object.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9043
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9044
	if (cs->vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9045
		if (cs->vp->v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9046
			status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9047
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9048
			status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9049
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9050
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9052
	if (rfs4_clnt_in_grace(lsp->state->owner->client)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9053
		status = NFS4ERR_GRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9054
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9055
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9056
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9057
	status = rfs4_do_lock(lsp, args->locktype,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9058
	    args->seqid, args->offset, args->length, cs->cr, resop);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9060
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9061
	*cs->statusp = resp->status = status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9062
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9063
	if (status == NFS4_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9064
		resp->lock_stateid = lsp->lockid.stateid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9065
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9066
	rfs4_update_lock_resp(lsp, resop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9067
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9068
end:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9069
	rfs4_sw_exit(&lsp->ls_sw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9070
	rfs4_lo_state_rele(lsp, TRUE);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9071
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9072
	DTRACE_NFSV4_2(op__locku__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9073
	    LOCKU4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9074
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9075
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9076
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9077
 * LOCKT is a best effort routine, the client can not be guaranteed that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9078
 * the status return is still in effect by the time the reply is received.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9079
 * They are numerous race conditions in this routine, but we are not required
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9080
 * and can not be accurate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9081
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9082
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9083
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9084
rfs4_op_lockt(nfs_argop4 *argop, nfs_resop4 *resop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9085
	    struct svc_req *req, struct compound_state *cs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9086
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9087
	LOCKT4args *args = &argop->nfs_argop4_u.oplockt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9088
	LOCKT4res *resp = &resop->nfs_resop4_u.oplockt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9089
	rfs4_lockowner_t *lo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9090
	rfs4_client_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9091
	bool_t create = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9092
	struct flock64 flk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9093
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9094
	int flag = FREAD | FWRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9095
	int ltype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9096
	length4 posix_length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9097
	sysid_t sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9098
	pid_t pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9099
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9100
	DTRACE_NFSV4_2(op__lockt__start, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9101
	    LOCKT4args *, args);
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9102
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9103
	if (cs->vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9104
		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9105
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9106
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9108
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9109
	 * NFS4 only allows locking on regular files, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9110
	 * verify type of object.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9111
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9112
	if (cs->vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9113
		if (cs->vp->v_type == VDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9114
			*cs->statusp = resp->status = NFS4ERR_ISDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9115
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9116
			*cs->statusp = resp->status =  NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9117
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9118
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9120
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9121
	 * Check out the clientid to ensure the server knows about it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9122
	 * so that we correctly inform the client of a server reboot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9123
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9124
	if ((cp = rfs4_findclient_by_id(args->owner.clientid, FALSE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9125
	    == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9126
		*cs->statusp = resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9127
		    rfs4_check_clientid(&args->owner.clientid, 0);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9128
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9129
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9130
	if (rfs4_lease_expired(cp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9131
		rfs4_client_close(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9132
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9133
		 * Protocol doesn't allow returning NFS4ERR_STALE as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9134
		 * other operations do on this check so STALE_CLIENTID
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9135
		 * is returned instead
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9136
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9137
		*cs->statusp = resp->status = NFS4ERR_STALE_CLIENTID;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9138
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9139
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9140
6364
54b943168f88 6655612 rfs4_op_lockt needs to release client table reference
vv149972
parents: 5798
diff changeset
  9141
	if (rfs4_clnt_in_grace(cp) && !(cp->can_reclaim)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9142
		*cs->statusp = resp->status = NFS4ERR_GRACE;
6364
54b943168f88 6655612 rfs4_op_lockt needs to release client table reference
vv149972
parents: 5798
diff changeset
  9143
		rfs4_client_rele(cp);
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9144
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9146
	rfs4_client_rele(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9148
	resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9150
	switch (args->locktype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9151
	case READ_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9152
	case READW_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9153
		ltype = F_RDLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9154
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9155
	case WRITE_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9156
	case WRITEW_LT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9157
		ltype = F_WRLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9158
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9159
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9160
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9161
	posix_length = args->length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9162
	/* Check for zero length. To lock to end of file use all ones for V4 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9163
	if (posix_length == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9164
		*cs->statusp = resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9165
		goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9166
	} else if (posix_length == (length4)(~0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9167
		posix_length = 0;	/* Posix to end of file  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9168
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9170
	/* Find or create a lockowner */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9171
	lo = rfs4_findlockowner(&args->owner, &create);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9173
	if (lo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9174
		pid = lo->pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9175
		if ((resp->status =
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9176
		    rfs4_client_sysid(lo->client, &sysid)) != NFS4_OK)
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9177
			goto err;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9178
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9179
		pid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9180
		sysid = lockt_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9181
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9182
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9183
	flk.l_type = ltype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9184
	flk.l_whence = 0;		/* SEEK_SET */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9185
	flk.l_start = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9186
	flk.l_len = posix_length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9187
	flk.l_sysid = sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9188
	flk.l_pid = pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9189
	flag |= F_REMOTELOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9191
	LOCK_PRINT(rfs4_debug, "rfs4_op_lockt", F_GETLK, &flk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9193
	/* Note that length4 is uint64_t but l_len and l_start are off64_t */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9194
	if (flk.l_len < 0 || flk.l_start < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9195
		resp->status = NFS4ERR_INVAL;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9196
		goto err;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9198
	error = VOP_FRLOCK(cs->vp, F_GETLK, &flk, flag, (u_offset_t)0,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9199
	    NULL, cs->cr, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9201
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9202
	 * N.B. We map error values to nfsv4 errors. This is differrent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9203
	 * than puterrno4 routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9204
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9205
	switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9206
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9207
		if (flk.l_type == F_UNLCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9208
			resp->status = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9209
		else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9210
			if (lock_denied(&resp->denied, &flk) == NFS4ERR_EXPIRED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9211
				goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9212
			resp->status = NFS4ERR_DENIED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9213
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9214
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9215
	case EOVERFLOW:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9216
		resp->status = NFS4ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9217
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9218
	case EINVAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9219
		resp->status = NFS4ERR_NOTSUPP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9220
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9221
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9222
		cmn_err(CE_WARN, "rfs4_op_lockt: unexpected errno (%d)",
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9223
		    error);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9224
		resp->status = NFS4ERR_SERVERFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9225
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9226
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9227
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9228
err:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9229
	if (lo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9230
		rfs4_lockowner_rele(lo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9231
	*cs->statusp = resp->status;
5647
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9232
out:
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9233
	DTRACE_NFSV4_2(op__lockt__done, struct compound_state *, cs,
738702b10756 PSARC/2007/663 DTrace NFS v4 Provider
samf
parents: 5599
diff changeset
  9234
	    LOCKT4res *, resp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9235
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9237
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9238
vop_shrlock(vnode_t *vp, int cmd, struct shrlock *sp, int fflags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9239
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9240
	int err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9242
	if (cmd == F_UNSHARE && sp->s_deny == 0 && sp->s_access == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9243
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9244
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9245
	err = VOP_SHRLOCK(vp, cmd, sp, fflags, CRED(), NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9247
	NFS4_DEBUG(rfs4_shrlock_debug,
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9248
	    (CE_NOTE, "rfs4_shrlock %s vp=%p acc=%d dny=%d sysid=%d "
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9249
	    "pid=%d err=%d\n", cmd == F_UNSHARE ? "UNSHR" : "SHARE",
5050
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9250
	    (void *) vp, sp->s_access, sp->s_deny, sp->s_sysid, sp->s_pid,
e67c98912955 PSARC 2007/456 Vnode Specific Data
jwahlig
parents: 4971
diff changeset
  9251
	    err));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9253
	return (err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9254
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9256
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9257
rfs4_shrlock(rfs4_state_t *sp, int cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9258
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9259
	struct shrlock shr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9260
	struct shr_locowner shr_loco;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9261
	int fflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9263
	fflags = shr.s_access = shr.s_deny = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9265
	if (sp->share_access & OPEN4_SHARE_ACCESS_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9266
		fflags |= FREAD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9267
		shr.s_access |= F_RDACC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9268
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9269
	if (sp->share_access & OPEN4_SHARE_ACCESS_WRITE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9270
		fflags |= FWRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9271
		shr.s_access |= F_WRACC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9272
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9273
	if (sp->share_deny & OPEN4_SHARE_DENY_READ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9274
		shr.s_deny |= F_RDDNY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9275
	if (sp->share_deny & OPEN4_SHARE_DENY_WRITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9276
		shr.s_deny |= F_WRDNY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9278
	shr.s_pid = rfs4_dbe_getid(sp->owner->dbe);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9279
	shr.s_sysid = sp->owner->client->sysidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9280
	shr_loco.sl_pid = shr.s_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9281
	shr_loco.sl_id = shr.s_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9282
	shr.s_owner = (caddr_t)&shr_loco;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9283
	shr.s_own_len = sizeof (shr_loco);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9284
	return (vop_shrlock(sp->finfo->vp, cmd, &shr, fflags));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9285
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9287
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9288
rfs4_share(rfs4_state_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9289
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9290
	int cmd;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9291
	cmd = nbl_need_check(sp->finfo->vp) ? F_SHARE_NBMAND : F_SHARE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5050
diff changeset
  9292
	return (rfs4_shrlock(sp, cmd));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9293
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9294
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9295
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9296
rfs4_unshare(rfs4_state_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9297
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9298
	(void) rfs4_shrlock(sp, F_UNSHARE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  9299
}
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9300
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9301
static int
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  9302
rdma_setup_read_data4(READ4args *args, READ4res *rok)
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9303
{
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9304
	struct clist	*wcl;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9305
	count4		count = rok->data_len;
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  9306
	int		wlist_len;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9307
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9308
	wcl = args->wlist;
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  9309
	if (rdma_setup_read_chunks(wcl, count, &wlist_len) == FALSE) {
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9310
		return (FALSE);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9311
	}
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9312
	wcl = args->wlist;
9348
7155ecb17858 6760947 NFS/RDMA port should be changed to IANA assigned 20049
Siddheshwar Mahesh <Siddheshwar.Mahesh@Sun.COM>
parents: 8869
diff changeset
  9313
	rok->wlist_len = wlist_len;
7387
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9314
	rok->wlist = wcl;
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9315
	return (TRUE);
0b3a92e31fd8 PSARC 2007/347 NFS/RDMA - Transport Version Update
Robert Gordon <Robert.Gordon@Sun.COM>
parents: 7067
diff changeset
  9316
}