usr/src/uts/common/fs/nfs/nfs3_srv.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 1610 3436e82414c8
child 4971 b721af044177
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
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
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
     5
 * Common Development and Distribution License (the "License").
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
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
/*
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
    22
 * Copyright 2006 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
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/* All Rights Reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#pragma ident	"%Z%%M%	%I%	%E% SMI"
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>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/dirent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/systeminfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/flock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/nbmlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <rpc/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <rpc/auth.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <rpc/svc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <nfs/nfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <nfs/export.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/strsubr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * These are the interface routines for the server side of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 * Network File System.  See the NFS version 3 protocol specification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * for a description of this interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
int rfs3_do_pre_op_attr = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
int rfs3_do_post_op_attr = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
int rfs3_do_post_op_fh3 = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
static writeverf3 write3verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
static int	sattr3_to_vattr(sattr3 *, struct vattr *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
static int	vattr_to_fattr3(struct vattr *, fattr3 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
static int	vattr_to_wcc_attr(struct vattr *, wcc_attr *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
static void	vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
static void	vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	vp = nfs3_fhtovp(&args->object, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
		goto out;
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
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
	error = rfs4_delegated_getattr(vp, &va, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
		/* overflow error if time or size is out of range */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
		error = vattr_to_fattr3(&va, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
		resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   117
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
rfs3_getattr_getfh(GETATTR3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   121
	return (&args->object);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
rfs3_setattr(SETATTR3args *args, SETATTR3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	struct vattr *bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
	struct vattr *avap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	int flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	struct flock64 bf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
	vp = nfs3_fhtovp(&args->object, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	error = sattr3_to_vattr(&args->new_attributes, &ava);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	 * We need to specially handle size changes because of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	 * possible conflicting NBMAND locks. Get into critical
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	 * region before VOP_GETATTR, so the size attribute is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	 * valid when checking conflicts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	 * Also, check to see if the v4 side of the server has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	 * delegated this file.  If so, then we return JUKEBOX to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	 * allow the client to retrasmit its request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	if (vp->v_type == VREG && (ava.va_mask & AT_SIZE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
		if (rfs4_check_delegated(FWRITE, vp, TRUE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
			resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
		if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
			nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
			in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	error = rfs4_delegated_getattr(vp, &bva, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	if (rfs3_do_pre_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		bvap = &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	bvap = &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	if (rdonly(exi, req) || vn_is_readonly(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	if (args->guard.check &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	    (args->guard.obj_ctime.seconds != bva.va_ctime.tv_sec ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	    args->guard.obj_ctime.nseconds != bva.va_ctime.tv_nsec)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
		resp->status = NFS3ERR_NOT_SYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	if (args->new_attributes.mtime.set_it == SET_TO_CLIENT_TIME)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		flag = ATTR_UTIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	 * If the filesystem is exported with nosuid, then mask off
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	 * the setuid and setgid bits.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	if ((ava.va_mask & AT_MODE) && vp->v_type == VREG &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	    (exi->exi_export.ex_flags & EX_NOSUID))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
		ava.va_mode &= ~(VSUID | VSGID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	 * We need to specially handle size changes because it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	 * possible for the client to create a file with modes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	 * which indicate read-only, but with the file opened for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	 * writing.  If the client then tries to set the size of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	 * the file, then the normal access checking done in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	 * VOP_SETATTR would prevent the client from doing so,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	 * although it should be legal for it to do so.  To get
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	 * around this, we do the access checking for ourselves
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	 * and then use VOP_SPACE which doesn't do the access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	 * checking which VOP_SETATTR does. VOP_SPACE can only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	 * operate on VREG files, let VOP_SETATTR handle the other
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	 * extremely rare cases.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	 * Also the client should not be allowed to change the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	 * size of the file if there is a conflicting non-blocking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	 * mandatory lock in the region the change.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	if (vp->v_type == VREG && (ava.va_mask & AT_SIZE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		if (in_crit) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
			u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
			ssize_t length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
			if (ava.va_size < bva.va_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
				offset = ava.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
				length = bva.va_size - ava.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
				offset = bva.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
				length = ava.va_size - bva.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
			if (nbl_conflict(vp, NBL_WRITE, offset, length, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
				error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
		if (crgetuid(cr) == bva.va_uid && ava.va_size != bva.va_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
			ava.va_mask &= ~AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
			bf.l_type = F_WRLCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
			bf.l_whence = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
			bf.l_start = (off64_t)ava.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
			bf.l_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
			bf.l_sysid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
			bf.l_pid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
			error = VOP_SPACE(vp, F_FREESP, &bf, FWRITE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
			    (offset_t)ava.va_size, cr, NULL);
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
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	if (!error && ava.va_mask)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
		error = VOP_SETATTR(vp, &ava, flag, cr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		avap = rfs4_delegated_getattr(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	avap = rfs4_delegated_getattr(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
#endif
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
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	vattr_to_wcc_data(bvap, avap, &resp->resok.obj_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	if (vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	vattr_to_wcc_data(bvap, avap, &resp->resfail.obj_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   307
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
rfs3_setattr_getfh(SETATTR3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   311
	return (&args->object);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	struct vattr *dvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	struct vattr dva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	nfs_fh3 *fhp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	struct sec_ol sec = {0, 0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	bool_t publicfh_flag = FALSE, auth_weak = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	dvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	 * Allow lookups from the root - the default
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	 * location of the public filehandle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		dvp = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	} else {
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   340
		dvp = nfs3_fhtovp(&args->what.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
		if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
			error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
		dva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		dvap = VOP_GETATTR(dvp, &dva, 0, cr) ? NULL : &dva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	dva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	dvap = VOP_GETATTR(dvp, &dva, 0, cr) ? NULL : &dva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	if (args->what.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	if (args->what.name == NULL || *(args->what.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   367
	fhp = &args->what.dir;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	if (strcmp(args->what.name, "..") == 0 &&
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   369
	    EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		resp->status = NFS3ERR_NOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	 * If the public filehandle is used then allow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
	 * a multi-component lookup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	 */
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   378
	if (PUBLIC_FH3(&args->what.dir)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		publicfh_flag = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		error = rfs_publicfh_mclookup(args->what.name, dvp, cr, &vp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
					&exi, &sec);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		if (error && exi != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
			exi_rele(exi);  /* See the comment below */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		error = VOP_LOOKUP(dvp, args->what.name, &vp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
				NULL, 0, NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		dva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		dvap = VOP_GETATTR(dvp, &dva, 0, cr) ? NULL : &dva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		dvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	dva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	dvap = VOP_GETATTR(dvp, &dva, 0, cr) ? NULL : &dva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	if (sec.sec_flags & SEC_QUERY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
		error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		error = makefh3(&resp->resok.object, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
		if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
			auth_weak = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
	 * If publicfh_flag is true then we have called rfs_publicfh_mclookup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	 * and have obtained a new exportinfo in exi which needs to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
	 * released. Note the the original exportinfo pointed to by exi
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
	 * will be released by the caller, common_dispatch.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	if (publicfh_flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
		exi_rele(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
		vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	 * If it's public fh, no 0x81, and client's flavor is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	 * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	 * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	if (auth_weak)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
		resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   467
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
rfs3_lookup_getfh(LOOKUP3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   471
	return (&args->what.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
rfs3_access(ACCESS3args *args, ACCESS3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	int checkwriteperm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	vp = nfs3_fhtovp(&args->object, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	 * If the file system is exported read only, it is not appropriate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	 * to check write permissions for regular files and directories.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	 * Special files are interpreted by the client, so the underlying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	 * permissions are sent back to the client for interpretation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
	if (rdonly(exi, req) && (vp->v_type == VREG || vp->v_type == VDIR))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
		checkwriteperm = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		checkwriteperm = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	 * We need the mode so that we can correctly determine access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	 * permissions relative to a mandatory lock file.  Access to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	 * mandatory lock files is denied on the server, so it might
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	 * as well be reflected to the server during the open.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	va.va_mask = AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	error = VOP_GETATTR(vp, &va, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	if (rfs3_do_post_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	resp->resok.access = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	if (args->access & ACCESS3_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
		error = VOP_ACCESS(vp, VREAD, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
		} else if (!MANDLOCK(vp, va.va_mode))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
			resp->resok.access |= ACCESS3_READ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
	if ((args->access & ACCESS3_LOOKUP) && vp->v_type == VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
		error = VOP_ACCESS(vp, VEXEC, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
			resp->resok.access |= ACCESS3_LOOKUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
	if (checkwriteperm &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	    (args->access & (ACCESS3_MODIFY|ACCESS3_EXTEND))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		error = VOP_ACCESS(vp, VWRITE, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		} else if (!MANDLOCK(vp, va.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
			resp->resok.access |=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
			    (args->access & (ACCESS3_MODIFY|ACCESS3_EXTEND));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
	if (checkwriteperm &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	    (args->access & ACCESS3_DELETE) && vp->v_type == VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		error = VOP_ACCESS(vp, VWRITE, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
			resp->resok.access |= ACCESS3_DELETE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	if (args->access & ACCESS3_EXECUTE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		error = VOP_ACCESS(vp, VEXEC, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		} else if (!MANDLOCK(vp, va.va_mode))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
			resp->resok.access |= ACCESS3_EXECUTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
	vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   597
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
rfs3_access_getfh(ACCESS3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   601
	return (&args->object);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
rfs3_readlink(READLINK3args *args, READLINK3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	char *data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	vp = nfs3_fhtovp(&args->symlink, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
		goto out;
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
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
	error = VOP_GETATTR(vp, &va, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	if (rfs3_do_post_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
		vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
	vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
	if (vp->v_type != VLNK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
	if (MANDLOCK(vp, va.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	data = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	iov.iov_base = data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	iov.iov_len = MAXPATHLEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	uio.uio_loffset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	uio.uio_resid = MAXPATHLEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	error = VOP_READLINK(vp, &uio, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
#if 0 /* notyet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	 * Don't do this.  It causes local disk writes when just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	 * reading the file and the overhead is deemed larger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	 * than the benefit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		kmem_free(data, MAXPATHLEN + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	vattr_to_post_op_attr(vap, &resp->resok.symlink_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	resp->resok.data = data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	*(data + MAXPATHLEN - uio.uio_resid) = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
	vattr_to_post_op_attr(vap, &resp->resfail.symlink_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   708
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
rfs3_readlink_getfh(READLINK3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   712
	return (&args->symlink);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
rfs3_readlink_free(READLINK3res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	if (resp->status == NFS3_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		kmem_free(resp->resok.data, MAXPATHLEN + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
rfs3_read(READ3args *args, READ3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
	mblk_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	int alloc_err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
	int need_rwunlock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	vp = nfs3_fhtovp(&args->file, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	 * Check to see if the v4 side of the server has delegated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
	 * this file.  If so, then we return JUKEBOX to allow the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
	 * client to retrasmit its request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
	if (rfs4_check_delegated(FREAD, vp, FALSE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	 * Enter the critical region before calling VOP_RWLOCK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	 * to avoid a deadlock with write requests.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
		nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
		in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
		if (nbl_conflict(vp, NBL_READ, args->offset, args->count, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
			error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
		}
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
	(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	need_rwunlock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	error = VOP_GETATTR(vp, &va, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	if (rfs3_do_post_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
		vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
	vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	if (crgetuid(cr) != va.va_uid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
		error = VOP_ACCESS(vp, VREAD, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
			if (curthread->t_flag & T_WOULDBLOCK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
			error = VOP_ACCESS(vp, VEXEC, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
			if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	if (MANDLOCK(vp, va.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	offset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	if (offset >= va.va_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
		VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
		vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		resp->resok.count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
		resp->resok.eof = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
		resp->resok.data.data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		resp->resok.data.data_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
		resp->resok.data.mp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	if (args->count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
		VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
		resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
		vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		resp->resok.count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
		resp->resok.eof = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
		resp->resok.data.data_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
		resp->resok.data.data_val = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
		resp->resok.data.mp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	 * do not allocate memory more the max. allowed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	 * transfer size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	if (args->count > rfs3_tsize(req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
		args->count = rfs3_tsize(req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	 * mp will contain the data to be sent out in the read reply.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	 * This will be freed after the reply has been sent out (by the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	 * driver).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	 * Let's roundup the data to a BYTES_PER_XDR_UNIT multiple, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	 * that the call to xdrmblk_putmblk() never fails.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG, &alloc_err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	ASSERT(mp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	ASSERT(alloc_err == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	iov.iov_base = (caddr_t)mp->b_datap->db_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	iov.iov_len = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	uio.uio_loffset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	uio.uio_resid = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	error = VOP_READ(vp, &uio, 0, cr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
		freeb(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	error = VOP_GETATTR(vp, &va, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
			vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
			vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		vap = &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
#if 0 /* notyet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	 * Don't do this.  It causes local disk writes when just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	 * reading the file and the overhead is deemed larger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	 * than the benefit.
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
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
		nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
	vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	resp->resok.count = args->count - uio.uio_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	if (!error && offset + resp->resok.count == va.va_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
		resp->resok.eof = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		resp->resok.eof = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
	resp->resok.data.data_len = resp->resok.count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	resp->resok.data.data_val = (char *)mp->b_datap->db_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
	resp->resok.data.mp = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	resp->resok.size = (uint_t)args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	if (vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
		if (need_rwunlock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
			VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
	vattr_to_post_op_attr(vap, &resp->resfail.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
rfs3_read_free(READ3res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	mblk_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	if (resp->status == NFS3_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
		mp = resp->resok.data.mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
		if (mp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
			freeb(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   957
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
rfs3_read_getfh(READ3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
   961
	return (&args->file);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
#define	MAX_IOVECS	12
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
static int rfs3_write_hits = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
static int rfs3_write_misses = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
rfs3_write(WRITE3args *args, WRITE3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	struct vattr *bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	struct vattr *avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	u_offset_t rlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	struct iovec iov[MAX_IOVECS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	mblk_t *m;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	struct iovec *iovp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	int iovcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	int ioflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	cred_t *savecred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
	int rwlock_ret = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	vp = nfs3_fhtovp(&args->file, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	 * Check to see if the v4 side of the server has delegated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	 * this file.  If so, then we return JUKEBOX to allow the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	 * client to retrasmit its request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	if (rfs4_check_delegated(FWRITE, vp, FALSE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	 * We have to enter the critical region before calling VOP_RWLOCK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	 * to avoid a deadlock with ufs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
		nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
		in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
		if (nbl_conflict(vp, NBL_WRITE, args->offset, args->count, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
			error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
	rwlock_ret = VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	error = VOP_GETATTR(vp, &bva, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	bvap = &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	if (!rfs3_do_pre_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
		bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
	avap = bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
	if (args->count != args->data.data_len) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
	if (crgetuid(cr) != bva.va_uid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
	    (error = VOP_ACCESS(vp, VWRITE, 0, cr)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
	if (MANDLOCK(vp, bva.va_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
	if (args->count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
		VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
		resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
		vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
		resp->resok.count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
		resp->resok.committed = args->stable;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
		resp->resok.verf = write3verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	if (args->mblk != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		iovcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		for (m = args->mblk; m != NULL; m = m->b_cont)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
			iovcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
		if (iovcnt <= MAX_IOVECS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
			rfs3_write_hits++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
			iovp = iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
			rfs3_write_misses++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
			iovp = kmem_alloc(sizeof (*iovp) * iovcnt, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
		mblk_to_iov(args->mblk, iovcnt, iovp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
		iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
		iovp = iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
		iovp->iov_base = args->data.data_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
		iovp->iov_len = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
	uio.uio_iov = iovp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	uio.uio_iovcnt = iovcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
	uio.uio_extflg = UIO_COPY_DEFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	uio.uio_loffset = args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
	uio.uio_resid = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	uio.uio_llimit = curproc->p_fsz_ctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
	rlimit = uio.uio_llimit - args->offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
	if (rlimit < (u_offset_t)uio.uio_resid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
		uio.uio_resid = (int)rlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
	if (args->stable == UNSTABLE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
		ioflag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	else if (args->stable == FILE_SYNC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
		ioflag = FSYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	else if (args->stable == DATA_SYNC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
		ioflag = FDSYNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
		if (iovp != iov)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
			kmem_free(iovp, sizeof (*iovp) * iovcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	 * We're changing creds because VM may fault and we need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	 * the cred of the current thread to be used if quota
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
	 * checking is enabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
	savecred = curthread->t_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	curthread->t_cred = cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
	error = VOP_WRITE(vp, &uio, ioflag, cr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	curthread->t_cred = savecred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	if (iovp != iov)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		kmem_free(iovp, sizeof (*iovp) * iovcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
	avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	if (!rfs3_do_post_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	VN_RELE(vp);
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
	 * If we were unable to get the V_WRITELOCK_TRUE, then we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
	 * may not have accurate after attrs, so check if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
	 * we have both attributes, they have a non-zero va_seq, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	 * va_seq has changed by exactly one,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	 * if not, turn off the before attr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	if (rwlock_ret != V_WRITELOCK_TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		if (bvap == NULL || avap == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
				bvap->va_seq == 0 || avap->va_seq == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
				avap->va_seq != (bvap->va_seq + 1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
			bvap = NULL;
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
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	resp->resok.count = args->count - uio.uio_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
	resp->resok.committed = args->stable;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	resp->resok.verf = write3verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	if (vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
		if (rwlock_ret != -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
			VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
			nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1191
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
rfs3_write_getfh(WRITE3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1195
	return (&args->file);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
rfs3_create(CREATE3args *args, CREATE3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	int in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	vnode_t *tvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	struct vattr *dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	struct vattr dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	struct vattr *davap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	struct vattr dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	enum vcexcl excl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
	nfstime3 *mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
	len_t reqsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	bool_t trunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1221
	dvp = nfs3_fhtovp(&args->where.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
		dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
		dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
		dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
	dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
	dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
	davap = dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	if (args->where.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	if (args->where.name == NULL || *(args->where.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
	if (args->how.mode == EXCLUSIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
		va.va_mask = AT_TYPE | AT_MODE | AT_MTIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
		va.va_type = VREG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
		va.va_mode = (mode_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
		 * Ensure no time overflows and that types match
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		mtime = (nfstime3 *)&args->how.createhow3_u.verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
		va.va_mtime.tv_sec = mtime->seconds % INT32_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
		va.va_mtime.tv_nsec = mtime->nseconds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
		excl = EXCL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
		error = sattr3_to_vattr(&args->how.createhow3_u.obj_attributes,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
		    &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
		va.va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
		va.va_type = VREG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
		if (args->how.mode == GUARDED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
			excl = EXCL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
		else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
			excl = NONEXCL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
			 * During creation of file in non-exclusive mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
			 * if size of file is being set then make sure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
			 * that if the file already exists that no conflicting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
			 * non-blocking mandatory locks exists in the region
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
			 * being modified. If there are conflicting locks fail
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
			 * the operation with EACCES.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
			if (va.va_mask & AT_SIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
				struct vattr tva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
				 * Does file already exist?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
				error = VOP_LOOKUP(dvp, args->where.name, &tvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
						NULL, 0, NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
				 * Check to see if the file has been delegated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
				 * to a v4 client.  If so, then begin recall of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
				 * the delegation and return JUKEBOX to allow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
				 * the client to retrasmit its request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
				trunc = va.va_size == 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
				if (!error &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
				    rfs4_check_delegated(FWRITE, tvp, trunc)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
					resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
					goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
				 * Check for NBMAND lock conflicts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
				if (!error && nbl_need_check(tvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
					u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
					ssize_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
					nbl_start_crit(tvp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
					in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
					tva.va_mask = AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
					error = VOP_GETATTR(tvp, &tva, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
					 * Can't check for conflicts, so return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
					 * error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
					if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
						goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
					offset = tva.va_size < va.va_size ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
						tva.va_size : va.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
					len = tva.va_size < va.va_size ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
						va.va_size - tva.va_size :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
						tva.va_size - va.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
					if (nbl_conflict(tvp, NBL_WRITE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
							offset, len, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
						error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
						goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
				} else if (tvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
					VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
					tvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
		if (va.va_mask & AT_SIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
			reqsize = va.va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
	 * Must specify the mode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
	if (!(va.va_mask & AT_MODE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	 * If the filesystem is exported with nosuid, then mask off
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
	 * the setuid and setgid bits.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	if (va.va_type == VREG && (exi->exi_export.ex_flags & EX_NOSUID))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
		va.va_mode &= ~(VSUID | VSGID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
tryagain:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	 * The file open mode used is VWRITE.  If the client needs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	 * some other semantic, then it should do the access checking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
	 * itself.  It would have been nice to have the file open mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
	 * passed as part of the arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	error = VOP_CREATE(dvp, args->where.name, &va, excl, VWRITE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	    &vp, cr, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
		dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
		davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
		davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
		 * If we got something other than file already exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
		 * then just return this error.  Otherwise, we got
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
		 * EEXIST.  If we were doing a GUARDED create, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
		 * just return this error.  Otherwise, we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
		 * make sure that this wasn't a duplicate of an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
		 * exclusive create request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
		 * The assumption is made that a non-exclusive create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
		 * request will never return EEXIST.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
		if (error != EEXIST || args->how.mode == GUARDED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
		 * Lookup the file so that we can get a vnode for it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
		error = VOP_LOOKUP(dvp, args->where.name, &vp, NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
		    NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
			 * We couldn't find the file that we thought that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
			 * we just created.  So, we'll just try creating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
			 * it again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
			if (error == ENOENT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
				goto tryagain;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
		 * If the file is delegated to a v4 client, go ahead
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
		 * and initiate recall, this create is a hint that a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
		 * conflicting v3 open has occurred.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
		if (rfs4_check_delegated(FWRITE, vp, FALSE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
			resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
		mtime = (nfstime3 *)&args->how.createhow3_u.verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
		/* % with INT32_MAX to prevent overflows */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
		if (args->how.mode == EXCLUSIVE && (vap == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
		    vap->va_mtime.tv_sec !=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
		    (mtime->seconds % INT32_MAX) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
		    vap->va_mtime.tv_nsec != mtime->nseconds)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
			error = EEXIST;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
		if ((args->how.mode == UNCHECKED ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
		    args->how.mode == GUARDED) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
		    args->how.createhow3_u.obj_attributes.size.set_it &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
		    va.va_size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
			trunc = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
			trunc = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
		if (rfs4_check_delegated(FWRITE, vp, trunc)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
			resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
		 * We need to check to make sure that the file got
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
		 * created to the indicated size.  If not, we do a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
		 * setattr to try to change the size, but we don't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		 * try too hard.  This shouldn't a problem as most
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		 * clients will only specifiy a size of zero which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
		 * local file systems handle.  However, even if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
		 * the client does specify a non-zero size, it can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
		 * still recover by checking the size of the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
		 * after it has created it and then issue a setattr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
		 * request of its own to set the size of the file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
		if (vap != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
		    (args->how.mode == UNCHECKED ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
		    args->how.mode == GUARDED) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
		    args->how.createhow3_u.obj_attributes.size.set_it &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
		    vap->va_size != reqsize) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
			va.va_mask = AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
			va.va_size = reqsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
			(void) VOP_SETATTR(vp, &va, 0, cr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
			va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
			vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	if (!rfs3_do_post_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	if (!rfs3_do_post_op_fh3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	error = makefh3(&resp->resok.obj.handle, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
		resp->resok.obj.handle_follows = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
	(void) VOP_FSYNC(dvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
	if (tvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
			nbl_end_crit(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
		VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	if (tvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
		if (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
			nbl_end_crit(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
		VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1537
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
rfs3_create_getfh(CREATE3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1541
	return (&args->where.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
rfs3_mkdir(MKDIR3args *args, MKDIR3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
	vnode_t *vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	struct vattr *dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	struct vattr dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	struct vattr *davap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	struct vattr dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
	dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
	davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1561
	dvp = nfs3_fhtovp(&args->where.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
		dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
		dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
		dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
	dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	davap = dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	if (args->where.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
	if (args->where.name == NULL || *(args->where.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	error = sattr3_to_vattr(&args->attributes, &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
	if (!(va.va_mask & AT_MODE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
	va.va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	va.va_type = VDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	error = VOP_MKDIR(dvp, args->where.name, &va, &vp, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
		dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
		davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
		davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
	davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
	(void) VOP_FSYNC(dvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	if (!rfs3_do_post_op_fh3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	error = makefh3(&resp->resok.obj.handle, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
		resp->resok.obj.handle_follows = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	(void) VOP_FSYNC(vp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
	vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
	vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1678
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
rfs3_mkdir_getfh(MKDIR3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1682
	return (&args->where.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
rfs3_symlink(SYMLINK3args *args, SYMLINK3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
	struct vattr *dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
	struct vattr dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
	struct vattr *davap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
	struct vattr dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
	dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
	davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1702
	dvp = nfs3_fhtovp(&args->where.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
		dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
		dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
		dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
	dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
	dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	davap = dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
	if (args->where.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
	if (args->where.name == NULL || *(args->where.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
		goto out1;
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
	error = sattr3_to_vattr(&args->symlink.symlink_attributes, &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
	if (!(va.va_mask & AT_MODE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	if (args->symlink.symlink_data == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
	va.va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
	va.va_type = VLNK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
	error = VOP_SYMLINK(dvp, args->where.name, &va,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
	    args->symlink.symlink_data, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
		dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
		davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
		davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
	dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	error = VOP_LOOKUP(dvp, args->where.name, &vp, NULL, 0, NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
	(void) VOP_FSYNC(dvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
		vattr_to_post_op_attr(NULL, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
		vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
	if (!rfs3_do_post_op_fh3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	error = makefh3(&resp->resok.obj.handle, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
		resp->resok.obj.handle_follows = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
	(void) VOP_FSYNC(vp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1834
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
rfs3_symlink_getfh(SYMLINK3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1838
	return (&args->where.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
rfs3_mknod(MKNOD3args *args, MKNOD3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
	struct vattr *dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	struct vattr dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	struct vattr *davap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	struct vattr dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	int mode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
	enum vcexcl excl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
	dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
	davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  1860
	dvp = nfs3_fhtovp(&args->where.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
		dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
		dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
		dbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	dbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	dbvap = VOP_GETATTR(dvp, &dbva, 0, cr) ? NULL : &dbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	davap = dbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
	if (args->where.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
	if (args->where.name == NULL || *(args->where.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
	switch (args->what.type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	case NF3CHR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
	case NF3BLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
		error = sattr3_to_vattr(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
		    &args->what.mknoddata3_u.device.dev_attributes, &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
		if (secpolicy_sys_devices(cr) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
			resp->status = NFS3ERR_PERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
		if (args->what.type == NF3CHR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
			va.va_type = VCHR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
			va.va_type = VBLK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
		va.va_rdev = makedevice(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
		    args->what.mknoddata3_u.device.spec.specdata1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
		    args->what.mknoddata3_u.device.spec.specdata2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
		va.va_mask |= AT_TYPE | AT_RDEV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	case NF3SOCK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
		error = sattr3_to_vattr(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
		    &args->what.mknoddata3_u.pipe_attributes, &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
		va.va_type = VSOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
		va.va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	case NF3FIFO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
		error = sattr3_to_vattr(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
		    &args->what.mknoddata3_u.pipe_attributes, &va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
		va.va_type = VFIFO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
		va.va_mask |= AT_TYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
		resp->status = NFS3ERR_BADTYPE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
	 * Must specify the mode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	if (!(va.va_mask & AT_MODE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	excl = EXCL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
	mode = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
	error = VOP_CREATE(dvp, args->where.name, &va, excl, mode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	    &vp, cr, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
		dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
		davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
		davap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	dava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	davap = VOP_GETATTR(dvp, &dava, 0, cr) ? NULL : &dava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
	(void) VOP_FSYNC(dvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
	if (!rfs3_do_post_op_fh3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
	error = makefh3(&resp->resok.obj.handle, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
		resp->resok.obj.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
		resp->resok.obj.handle_follows = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
	vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2020
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
rfs3_mknod_getfh(MKNOD3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2024
	return (&args->where.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
rfs3_remove(REMOVE3args *args, REMOVE3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
	struct vattr *bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
	struct vattr *avap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	vnode_t *targvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2042
	vp = nfs3_fhtovp(&args->object.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
		bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
		bvap = VOP_GETATTR(vp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
		bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
	bvap = VOP_GETATTR(vp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
	avap = bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
	if (vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
		resp->status = NFS3ERR_NOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
	if (args->object.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
	if (args->object.name == NULL || *(args->object.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
	 * Check for a conflict with a non-blocking mandatory share
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
	 * reservation and V4 delegations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
	error = VOP_LOOKUP(vp, args->object.name, &targvp, NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
			NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
	if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	if (!nbl_need_check(targvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
		error = VOP_REMOVE(vp, args->object.name, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
		nbl_start_crit(targvp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
		if (nbl_conflict(targvp, NBL_REMOVE, 0, 0, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
			error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
			error = VOP_REMOVE(vp, args->object.name, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
		nbl_end_crit(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
	VN_RELE(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	targvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
		ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
		avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
	avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	(void) VOP_FSYNC(vp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
	vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
	vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2145
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
rfs3_remove_getfh(REMOVE3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2149
	return (&args->object.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
rfs3_rmdir(RMDIR3args *args, RMDIR3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
	struct vattr *bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
	struct vattr *avap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2166
	vp = nfs3_fhtovp(&args->object.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
		bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
		bvap = VOP_GETATTR(vp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
		bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
	bvap = VOP_GETATTR(vp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
	avap = bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
	if (vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
		resp->status = NFS3ERR_NOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
	if (args->object.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
	if (args->object.name == NULL || *(args->object.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
	error = VOP_RMDIR(vp, args->object.name, rootdir, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
		ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
		avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
	avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
	(void) VOP_FSYNC(vp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
		 * System V defines rmdir to return EEXIST, not ENOTEMPTY,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
		 * if the directory is not empty.  A System V NFS server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
		 * needs to map NFS3ERR_EXIST to NFS3ERR_NOTEMPTY to transmit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
		 * over the wire.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
		if (error == EEXIST)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
			error = ENOTEMPTY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
		goto out;
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
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
	vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2252
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
rfs3_rmdir_getfh(RMDIR3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2256
	return (&args->object.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
rfs3_rename(RENAME3args *args, RENAME3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
	vnode_t *fvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	vnode_t *tvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
	vnode_t *targvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
	struct vattr *fbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
	struct vattr fbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
	struct vattr *favap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
	struct vattr fava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
	struct vattr *tbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
	struct vattr tbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
	struct vattr *tavap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
	struct vattr tava;
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2275
	nfs_fh3 *fh3;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
	struct exportinfo *to_exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
	vnode_t *srcvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
	fbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
	favap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
	tbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
	tavap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
	tvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2285
	fvp = nfs3_fhtovp(&args->from.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
	if (fvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
		fbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
		fbvap = VOP_GETATTR(fvp, &fbva, 0, cr) ? NULL : &fbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
		fbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
	fbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
	fbvap = VOP_GETATTR(fvp, &fbva, 0, cr) ? NULL : &fbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
	favap = fbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2303
	fh3 = &args->to.dir;
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2304
	to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
	if (to_exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
	exi_rele(to_exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
	if (to_exi != exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
		resp->status = NFS3ERR_XDEV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2316
	tvp = nfs3_fhtovp(&args->to.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
	if (tvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
		tbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
		tbvap = VOP_GETATTR(tvp, &tbva, 0, cr) ? NULL : &tbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
		tbvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
	tbva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
	tbvap = VOP_GETATTR(tvp, &tbva, 0, cr) ? NULL : &tbva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
	tavap = tbvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	if (fvp->v_type != VDIR || tvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
		resp->status = NFS3ERR_NOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
	if (args->from.name == nfs3nametoolong ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	    args->to.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
	if (args->from.name == NULL || *(args->from.name) == '\0' ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
	    args->to.name == NULL || *(args->to.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
	 * Check for a conflict with a non-blocking mandatory share
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
	 * reservation or V4 delegations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
	error = VOP_LOOKUP(fvp, args->from.name, &srcvp, NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
			NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	 * If we rename a delegated file we should recall the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
	 * delegation, since future opens should fail or would
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
	 * refer to a new file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
	if (rfs4_check_delegated(FWRITE, srcvp, FALSE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
	 * Check for renaming over a delegated file.  Check rfs4_deleg_policy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
	 * first to avoid VOP_LOOKUP if possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
	if (rfs4_deleg_policy != SRV_NEVER_DELEGATE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
	    VOP_LOOKUP(tvp, args->to.name, &targvp, NULL, 0, NULL, cr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
		if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
			VN_RELE(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
			resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
		VN_RELE(targvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
	if (!nbl_need_check(srcvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
		error = VOP_RENAME(fvp, args->from.name, tvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
				    args->to.name, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
		nbl_start_crit(srcvp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
		if (nbl_conflict(srcvp, NBL_RENAME, 0, 0, 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
			error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
			error = VOP_RENAME(fvp, args->from.name, tvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
				    args->to.name, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
		nbl_end_crit(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
	}
1146
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2402
	if (error == 0) {
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2403
		char *tmp;
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2404
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2405
		/* fix the path name for the renamed file */
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2406
		mutex_enter(&srcvp->v_lock);
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2407
		tmp = srcvp->v_path;
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2408
		srcvp->v_path = NULL;
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2409
		mutex_exit(&srcvp->v_lock);
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2410
		vn_setpath(rootdir, tvp, srcvp, args->to.name,
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2411
				strlen(args->to.name));
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2412
		if (tmp != NULL)
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2413
			kmem_free(tmp, strlen(tmp) + 1);
c3555cdf52c2 6331154 v_path contains old name after file is renamed
jwahlig
parents: 254
diff changeset
  2414
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
	VN_RELE(srcvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
	srcvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
		fava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
		favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
		tava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
		tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
		favap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		tavap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
	fava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
	favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
	tava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
	tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
#endif
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
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	(void) VOP_FSYNC(fvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	(void) VOP_FSYNC(tvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
	VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	VN_RELE(fvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	vattr_to_wcc_data(fbvap, favap, &resp->resok.fromdir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	vattr_to_wcc_data(tbvap, tavap, &resp->resok.todir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	if (fvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		VN_RELE(fvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
	if (tvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
	vattr_to_wcc_data(fbvap, favap, &resp->resfail.fromdir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
	vattr_to_wcc_data(tbvap, tavap, &resp->resfail.todir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2467
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
rfs3_rename_getfh(RENAME3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2471
	return (&args->from.dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
rfs3_link(LINK3args *args, LINK3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
	struct vattr *bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
	struct vattr *avap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
	nfs_fh3	*fh3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
	struct exportinfo *to_exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
	bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
	dvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
	vp = nfs3_fhtovp(&args->file, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2512
	fh3 = &args->link.dir;
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2513
	to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
	if (to_exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	exi_rele(to_exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
	if (to_exi != exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		resp->status = NFS3ERR_XDEV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2525
	dvp = nfs3_fhtovp(&args->link.dir, exi);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
	if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
		bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
		bvap = VOP_GETATTR(dvp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
		bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
	bvap = VOP_GETATTR(dvp, &bva, 0, cr) ? NULL : &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
	if (dvp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
		resp->status = NFS3ERR_NOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
		goto out1;
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
	if (args->link.name == nfs3nametoolong) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
		resp->status = NFS3ERR_NAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	if (args->link.name == NULL || *(args->link.name) == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
		resp->status = NFS3ERR_ACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
	error = VOP_LINK(dvp, vp, args->link.name, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
		ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
		avap = VOP_GETATTR(dvp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	avap = VOP_GETATTR(dvp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
	 * Force modified data and metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
	(void) VOP_FSYNC(dvp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
	VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
	vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
	vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	vattr_to_post_op_attr(vap, &resp->resfail.file_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	vattr_to_wcc_data(bvap, avap, &resp->resfail.linkdir_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2613
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
rfs3_link_getfh(LINK3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2617
	return (&args->file);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
 * This macro defines the size of a response which contains attribute
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
 * information and one directory entry (whose length is specified by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
 * the macro parameter).  If the incoming request is larger than this,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
 * then we are guaranteed to be able to return at one directory entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
 * if one exists.  Therefore, we do not need to check for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
 * NFS3ERR_TOOSMALL if the requested size is larger then this.  If it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
 * is not, then we need to check to make sure that this error does not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
 * need to be returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
 * NFS3_READDIR_MIN_COUNT is comprised of following :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
 * status - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
 * attr. flag - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
 * cookie verifier - 2 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
 * attributes  - NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
 * boolean - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
 * file id - 2 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
 * direcotory name length - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
 * cookie - 2 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
 * end of list - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
 * end of file - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
 * Name length of directory to the nearest byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
#define	NFS3_READDIR_MIN_COUNT(length)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
	((1 + 1 + 2 + NFS3_SIZEOF_FATTR3 + 1 + 2 + 1 + 2 + 1 + 1) * \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
		BYTES_PER_XDR_UNIT + roundup((length), BYTES_PER_XDR_UNIT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
rfs3_readdir(READDIR3args *args, READDIR3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
	char *data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
	int iseof;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
	int bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	int namlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
	uint_t count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
	vp = nfs3_fhtovp(&args->dir, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
	(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
	if (vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
		resp->status = NFS3ERR_NOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
		goto out1;
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
	error = VOP_ACCESS(vp, VREAD, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
	 * Now don't allow arbitrary count to alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
	 * allow the maximum not to exceed rfs3_tsize()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
	if (args->count > rfs3_tsize(req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
		args->count = rfs3_tsize(req);
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
	 * Make sure that there is room to read at least one entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
	 * if any are available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
	if (args->count < DIRENT64_RECLEN(MAXNAMELEN))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
		count = DIRENT64_RECLEN(MAXNAMELEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
		count = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
	data = kmem_alloc(count, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
	iov.iov_base = data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
	iov.iov_len = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
	uio.uio_loffset = (offset_t)args->cookie;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
	uio.uio_resid = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
	error = VOP_READDIR(vp, &uio, cr, &iseof);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
		kmem_free(data, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
	 * If the count was not large enough to be able to guarantee
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
	 * to be able to return at least one entry, then need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
	 * check to see if NFS3ERR_TOOSMALL should be returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
	if (args->count < NFS3_READDIR_MIN_COUNT(MAXNAMELEN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
		 * bufsize is used to keep track of the size of the response.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
		 * It is primed with:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
		 *	1 for the status +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
		 *	1 for the dir_attributes.attributes boolean +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
		 *	2 for the cookie verifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
		 * all times BYTES_PER_XDR_UNIT to convert from XDR units
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
		 * to bytes.  If there are directory attributes to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
		 * returned, then:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
		 *	NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
		 * time BYTES_PER_XDR_UNIT is added to account for them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
		bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
		if (vap != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
			bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
		 * An entry is composed of:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
		 *	1 for the true/false list indicator +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
		 *	2 for the fileid +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
		 *	1 for the length of the name +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
		 *	2 for the cookie +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
		 * all times BYTES_PER_XDR_UNIT to convert from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
		 * XDR units to bytes, plus the length of the name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
		 * rounded up to the nearest BYTES_PER_XDR_UNIT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
		if (count != uio.uio_resid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
			namlen = strlen(((struct dirent64 *)data)->d_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
			bufsize += (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
				    roundup(namlen, BYTES_PER_XDR_UNIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
		 * We need to check to see if the number of bytes left
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
		 * to go into the buffer will actually fit into the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
		 * buffer.  This is calculated as the size of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
		 * entry plus:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
		 *	1 for the true/false list indicator +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
		 *	1 for the eof indicator
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
		 * times BYTES_PER_XDR_UNIT to convert from from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
		 * XDR units to bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
		bufsize += (1 + 1) * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
		if (bufsize > args->count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
			kmem_free(data, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
			resp->status = NFS3ERR_TOOSMALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
	VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
#if 0 /* notyet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
	 * Don't do this.  It causes local disk writes when just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
	 * reading the file and the overhead is deemed larger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
	 * than the benefit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2809
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2811
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
	vattr_to_post_op_attr(vap, &resp->resok.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
	resp->resok.cookieverf = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
	resp->resok.reply.entries = (entry3 *)data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	resp->resok.reply.eof = iseof;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
	resp->resok.size = count - uio.uio_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
	resp->resok.count = args->count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
	resp->resok.freecount = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
	if (vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
		VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
	vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2835
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
rfs3_readdir_getfh(READDIR3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2839
	return (&args->dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
rfs3_readdir_free(READDIR3res *resp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
	if (resp->status == NFS3_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
		kmem_free(resp->resok.reply.entries, resp->resok.freecount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
#ifdef nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
#undef nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
#define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
 * This macro computes the size of a response which contains
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
 * one directory entry including the attributes as well as file handle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
 * If the incoming request is larger than this, then we are guaranteed to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
 * able to return at least one more directory entry if one exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
 * NFS3_READDIRPLUS_ENTRY is made up of the following:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
 * boolean - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
 * file id - 2 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
 * directory name length - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
 * cookie - 2 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
 * attribute flag - 1 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
 * attributes - NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
 * status byte for file handle - 1 *  BYTES_PER_XDR_UNIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
 * length of a file handle - 1 * BYTES_PER_XDR_UNIT
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2871
 * Maxmum length of a file handle (NFS3_MAXFHSIZE)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
 * name length of the entry to the nearest bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2874
#define	NFS3_READDIRPLUS_ENTRY(namelen)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
	((1 + 2 + 1 + 2 + 1 + NFS3_SIZEOF_FATTR3 + 1 + 1) * \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
		BYTES_PER_XDR_UNIT + \
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  2877
	NFS3_MAXFHSIZE + roundup(namelen, BYTES_PER_XDR_UNIT))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
static int rfs3_readdir_unit = MAXBSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
rfs3_readdirplus(READDIRPLUS3args *args, READDIRPLUS3res *resp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
	struct exportinfo *exi, struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
	struct iovec iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
	struct uio uio;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
	char *data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
	int iseof;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
	struct dirent64 *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
	vnode_t *nvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
	struct vattr *nvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
	struct vattr nva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
	entryplus3_info *infop = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
	int size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
	int nents = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
	int bufsize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
	int entrysize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
	int tofit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
	int rd_unit = rfs3_readdir_unit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
	int prev_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	int space_left;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
	uint_t *namlen = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
	vp = nfs3_fhtovp(&args->dir, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2913
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2914
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
	(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
	if (rfs3_do_pre_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2928
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
	if (vp->v_type != VDIR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
		error = ENOTDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2933
		goto out;
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
	error = VOP_ACCESS(vp, VREAD, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
	 * Don't allow arbitrary counts for allocation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
	if (args->maxcount > rfs3_tsize(req))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
		args->maxcount = rfs3_tsize(req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2946
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
	 * Make sure that there is room to read at least one entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
	 * if any are available
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
	args->dircount = MIN(args->dircount, args->maxcount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
	if (args->dircount < DIRENT64_RECLEN(MAXNAMELEN))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
		args->dircount = DIRENT64_RECLEN(MAXNAMELEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
	 * This allocation relies on a minimum directory entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
	 * being roughly 24 bytes.  Therefore, the namlen array
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
	 * will have enough space based on the maximum number of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
	 * entries to read.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
	namlen = kmem_alloc(args->dircount, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2963
	space_left = args->dircount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2964
	data = kmem_alloc(args->dircount, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2965
	dp = (struct dirent64 *)data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
	uio.uio_iov = &iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
	uio.uio_iovcnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2968
	uio.uio_segflg = UIO_SYSSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
	uio.uio_extflg = UIO_COPY_CACHED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
	uio.uio_loffset = (offset_t)args->cookie;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
	 * bufsize is used to keep track of the size of the response as we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
	 * get post op attributes and filehandles for each entry.  This is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
	 * an optimization as the server may have read more entries than will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
	 * fit in the buffer specified by maxcount.  We stop calculating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
	 * post op attributes and filehandles once we have exceeded maxcount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
	 * This will minimize the effect of truncation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
	 * It is primed with:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
	 *	1 for the status +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
	 *	1 for the dir_attributes.attributes boolean +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
	 *	2 for the cookie verifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
	 * all times BYTES_PER_XDR_UNIT to convert from XDR units
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2985
	 * to bytes.  If there are directory attributes to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2986
	 * returned, then:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
	 *	NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2988
	 * time BYTES_PER_XDR_UNIT is added to account for them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2989
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2990
	bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2991
	if (vap != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
		bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
getmoredents:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
	 * Here we make a check so that our read unit is not larger than
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
	 * the space left in the buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
	rd_unit = MIN(rd_unit, space_left);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	iov.iov_base = (char *)dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
	iov.iov_len = rd_unit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
	uio.uio_resid = rd_unit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
	prev_len = rd_unit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
	error = VOP_READDIR(vp, &uio, cr, &iseof);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
		kmem_free(data, args->dircount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
	if (uio.uio_resid == prev_len && !iseof) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
		if (nents == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
			kmem_free(data, args->dircount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
			resp->status = NFS3ERR_TOOSMALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
			goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
		 * We could not get any more entries, so get the attributes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
		 * and filehandle for the entries already obtained.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
		goto good;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
	 * We estimate the size of the response by assuming the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
	 * entry exists and attributes and filehandle are also valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
	for (size = prev_len - uio.uio_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
		size > 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
		size -= dp->d_reclen, dp = nextdp(dp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
		if (dp->d_ino == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
			nents++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
			continue;
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
		namlen[nents] = strlen(dp->d_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
		entrysize = NFS3_READDIRPLUS_ENTRY(namlen[nents]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
		 * We need to check to see if the number of bytes left
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
		 * to go into the buffer will actually fit into the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
		 * buffer.  This is calculated as the size of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
		 * entry plus:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
		 *	1 for the true/false list indicator +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
		 *	1 for the eof indicator
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
		 * times BYTES_PER_XDR_UNIT to convert from XDR units
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
		 * to bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
		 * Also check the dircount limit against the first entry read
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
		tofit = entrysize + (1 + 1) * BYTES_PER_XDR_UNIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
		if (bufsize + tofit > args->maxcount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
			 * We make a check here to see if this was the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
			 * first entry being measured.  If so, then maxcount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
			 * was too small to begin with and so we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
			 * return with NFS3ERR_TOOSMALL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
			if (nents == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
				kmem_free(data, args->dircount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
				resp->status = NFS3ERR_TOOSMALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
				goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
			iseof = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
			goto good;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
		bufsize += entrysize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
		nents++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
	 * If there is enough room to fit at least 1 more entry including
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3077
	 * post op attributes and filehandle in the buffer AND that we haven't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3078
	 * exceeded dircount then go back and get some more.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
	if (!iseof &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
	    (args->maxcount - bufsize) >= NFS3_READDIRPLUS_ENTRY(MAXNAMELEN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
		space_left -= (prev_len - uio.uio_resid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
		if (space_left >= DIRENT64_RECLEN(MAXNAMELEN))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
			goto getmoredents;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		/* else, fall through */
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
good:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
	VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
	infop = kmem_alloc(nents * sizeof (struct entryplus3_info), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
	resp->resok.infop = infop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
	dp = (struct dirent64 *)data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
	for (i = 0; i < nents; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
		if (dp->d_ino == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
			infop[i].attr.attributes = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
			infop[i].fh.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
			dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
		infop[i].namelen = namlen[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
		error = VOP_LOOKUP(vp, dp->d_name, &nvp, NULL, 0, NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
			infop[i].attr.attributes = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
			infop[i].fh.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
			dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
		if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
			nva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
			nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
				NULL : &nva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
			nvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
		nva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
		nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ? NULL : &nva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
		vattr_to_post_op_attr(nvap, &infop[i].attr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3141
		if (!rfs3_do_post_op_fh3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
			infop[i].fh.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
		else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
		error = makefh3(&infop[i].fh.handle, nvp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
		if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
			infop[i].fh.handle_follows = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3148
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
			infop[i].fh.handle_follows = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
		VN_RELE(nvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
		dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
#if 0 /* notyet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
	 * Don't do this.  It causes local disk writes when just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
	 * reading the file and the overhead is deemed larger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
	 * than the benefit.
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
	 * Force modified metadata out to stable storage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
	(void) VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
	kmem_free(namlen, args->dircount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
	vattr_to_post_op_attr(vap, &resp->resok.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
	resp->resok.cookieverf = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
	resp->resok.reply.entries = (entryplus3 *)data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
	resp->resok.reply.eof = iseof;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
	resp->resok.size = nents;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
	resp->resok.count = args->dircount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
	resp->resok.maxcount = args->maxcount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
	if (vp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
		VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
	if (namlen != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
		kmem_free(namlen, args->dircount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
	vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3202
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
rfs3_readdirplus_getfh(READDIRPLUS3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3206
	return (&args->dir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
rfs3_readdirplus_free(READDIRPLUS3res *resp)
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
	if (resp->status == NFS3_OK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
		kmem_free(resp->resok.reply.entries, resp->resok.count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
		kmem_free(resp->resok.infop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
			resp->resok.size * sizeof (struct entryplus3_info));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
rfs3_fsstat(FSSTAT3args *args, FSSTAT3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
	struct statvfs64 sb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
	vp = nfs3_fhtovp(&args->fsroot, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	error = VFS_STATVFS(vp->v_vfsp, &sb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
	if (sb.f_blocks != (fsblkcnt64_t)-1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
		resp->resok.tbytes = (size3)sb.f_frsize * (size3)sb.f_blocks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
		resp->resok.tbytes = (size3)sb.f_blocks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
	if (sb.f_bfree != (fsblkcnt64_t)-1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
		resp->resok.fbytes = (size3)sb.f_frsize * (size3)sb.f_bfree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
		resp->resok.fbytes = (size3)sb.f_bfree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
	if (sb.f_bavail != (fsblkcnt64_t)-1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
		resp->resok.abytes = (size3)sb.f_frsize * (size3)sb.f_bavail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
		resp->resok.abytes = (size3)sb.f_bavail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
	resp->resok.tfiles = (size3)sb.f_files;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	resp->resok.ffiles = (size3)sb.f_ffree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
	resp->resok.afiles = (size3)sb.f_favail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
	resp->resok.invarsec = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
	vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3286
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
rfs3_fsstat_getfh(FSSTAT3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3290
	return (&args->fsroot);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
rfs3_fsinfo(FSINFO3args *args, FSINFO3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
	uint32_t xfer_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
	ulong_t l = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
	vp = nfs3_fhtovp(&args->fsroot, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
		if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
			curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
			resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
			resp->status = NFS3ERR_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
		vattr_to_post_op_attr(NULL, &resp->resfail.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
	xfer_size = rfs3_tsize(req);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
	resp->resok.rtmax = xfer_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
	resp->resok.rtpref = xfer_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
	resp->resok.rtmult = DEV_BSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
	resp->resok.wtmax = xfer_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
	resp->resok.wtpref = xfer_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
	resp->resok.wtmult = DEV_BSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
	resp->resok.dtpref = MAXBSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
	 * Large file spec: want maxfilesize based on limit of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	 * underlying filesystem.  We can guess 2^31-1 if need be.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
	error = VOP_PATHCONF(vp, _PC_FILESIZEBITS, &l, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
	if (!error && l != 0 && l <= 64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
		resp->resok.maxfilesize = (1LL << (l-1)) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
		resp->resok.maxfilesize = MAXOFF32_T;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	resp->resok.time_delta.seconds = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
	resp->resok.time_delta.nseconds = 1000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
	resp->resok.properties = FSF3_LINK | FSF3_SYMLINK |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
	    FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3357
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
rfs3_fsinfo_getfh(FSINFO3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3361
	return (&args->fsroot);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
rfs3_pathconf(PATHCONF3args *args, PATHCONF3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
	struct vattr *vap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
	ulong_t val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
	vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
	vp = nfs3_fhtovp(&args->object, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
		va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
		vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
		vap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
	va.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
	vap = VOP_GETATTR(vp, &va, 0, cr) ? NULL : &va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
	error = VOP_PATHCONF(vp, _PC_LINK_MAX, &val, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
	resp->resok.info.link_max = (uint32)val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
	error = VOP_PATHCONF(vp, _PC_NAME_MAX, &val, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
	resp->resok.info.name_max = (uint32)val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
	error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &val, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
	if (val == 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
		resp->resok.info.no_trunc = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
		resp->resok.info.no_trunc = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
	error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &val, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
	if (val == 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
		resp->resok.info.chown_restricted = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
		resp->resok.info.chown_restricted = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
	vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
	resp->resok.info.case_insensitive = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
	resp->resok.info.case_preserving = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
	vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3439
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
rfs3_pathconf_getfh(PATHCONF3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3443
	return (&args->object);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
rfs3_commit(COMMIT3args *args, COMMIT3res *resp, struct exportinfo *exi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
	struct svc_req *req, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
	struct vattr *bvap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	struct vattr bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
	struct vattr *avap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	struct vattr ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
	bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
	avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
	vp = nfs3_fhtovp(&args->file, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
	if (vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
		error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
	bva.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
	error = VOP_GETATTR(vp, &bva, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
	 * If we can't get the attributes, then we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
	 * right access checking.  So, we'll fail the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
	if (rfs3_do_pre_op_attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
		bvap = &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
		bvap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
	bvap = &bva;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
	if (rdonly(exi, req)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
		resp->status = NFS3ERR_ROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
	if (vp->v_type != VREG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
		resp->status = NFS3ERR_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
		goto out1;
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
	if (crgetuid(cr) != bva.va_uid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
	    (error = VOP_ACCESS(vp, VWRITE, 0, cr)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
	error = VOP_PUTPAGE(vp, args->offset, args->count, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
	if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
		error = VOP_FSYNC(vp, FNODSYNC, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
	if (rfs3_do_post_op_attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
		ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
		avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
		avap = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
	ava.va_mask = AT_ALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
	avap = VOP_GETATTR(vp, &ava, 0, cr) ? NULL : &ava;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
	resp->status = NFS3_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
	vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
	resp->resok.verf = write3verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
	return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
	if (curthread->t_flag & T_WOULDBLOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
		curthread->t_flag &= ~T_WOULDBLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
		resp->status = NFS3ERR_JUKEBOX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
		resp->status = puterrno3(error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
	if (vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
	vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3536
void *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
rfs3_commit_getfh(COMMIT3args *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 1146
diff changeset
  3540
	return (&args->file);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
sattr3_to_vattr(sattr3 *sap, struct vattr *vap)
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
	vap->va_mask = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
	if (sap->mode.set_it) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
		vap->va_mode = (mode_t)sap->mode.mode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
		vap->va_mask |= AT_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
	if (sap->uid.set_it) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
		vap->va_uid = (uid_t)sap->uid.uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
		vap->va_mask |= AT_UID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
	if (sap->gid.set_it) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
		vap->va_gid = (gid_t)sap->gid.gid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
		vap->va_mask |= AT_GID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
	if (sap->size.set_it) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
		if (sap->size.size > (size3)((u_longlong_t)-1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
		vap->va_size = sap->size.size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
		vap->va_mask |= AT_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
	if (sap->atime.set_it == SET_TO_CLIENT_TIME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
#ifndef _LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
		/* check time validity */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
		if (!NFS3_TIME_OK(sap->atime.atime.seconds))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
			return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
		 * nfs protocol defines times as unsigned so don't extend sign,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
		 * unless sysadmin set nfs_allow_preepoch_time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
		NFS_TIME_T_CONVERT(vap->va_atime.tv_sec,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
			sap->atime.atime.seconds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
		vap->va_atime.tv_nsec = (uint32_t)sap->atime.atime.nseconds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
		vap->va_mask |= AT_ATIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
	} else if (sap->atime.set_it == SET_TO_SERVER_TIME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
		gethrestime(&vap->va_atime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
		vap->va_mask |= AT_ATIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
	if (sap->mtime.set_it == SET_TO_CLIENT_TIME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
#ifndef _LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
		/* check time validity */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
		if (!NFS3_TIME_OK(sap->mtime.mtime.seconds))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
			return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
		 * nfs protocol defines times as unsigned so don't extend sign,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
		 * unless sysadmin set nfs_allow_preepoch_time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
		NFS_TIME_T_CONVERT(vap->va_mtime.tv_sec,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
			sap->mtime.mtime.seconds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
		vap->va_mtime.tv_nsec = (uint32_t)sap->mtime.mtime.nseconds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
		vap->va_mask |= AT_MTIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
	} else if (sap->mtime.set_it == SET_TO_SERVER_TIME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
		gethrestime(&vap->va_mtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
		vap->va_mask |= AT_MTIME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
static ftype3 vt_to_nf3[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
	0, NF3REG, NF3DIR, NF3BLK, NF3CHR, NF3LNK, NF3FIFO, 0, 0, NF3SOCK, 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
vattr_to_fattr3(struct vattr *vap, fattr3 *fap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
	ASSERT(vap->va_type >= VNON && vap->va_type <= VBAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
	/* Return error if time or size overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
	if (! (NFS_VAP_TIME_OK(vap) && NFS3_SIZE_OK(vap->va_size))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
		return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
	fap->type = vt_to_nf3[vap->va_type];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
	fap->mode = (mode3)(vap->va_mode & MODEMASK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
	fap->nlink = (uint32)vap->va_nlink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
	if (vap->va_uid == UID_NOBODY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
		fap->uid = (uid3)NFS_UID_NOBODY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
		fap->uid = (uid3)vap->va_uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
	if (vap->va_gid == GID_NOBODY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
		fap->gid = (gid3)NFS_GID_NOBODY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
		fap->gid = (gid3)vap->va_gid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
	fap->size = (size3)vap->va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
	fap->used = (size3)DEV_BSIZE * (size3)vap->va_nblocks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
	fap->rdev.specdata1 = (uint32)getmajor(vap->va_rdev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
	fap->rdev.specdata2 = (uint32)getminor(vap->va_rdev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
	fap->fsid = (uint64)vap->va_fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
	fap->fileid = (fileid3)vap->va_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
	fap->atime.seconds = vap->va_atime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
	fap->atime.nseconds = vap->va_atime.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
	fap->mtime.seconds = vap->va_mtime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
	fap->mtime.nseconds = vap->va_mtime.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
	fap->ctime.seconds = vap->va_ctime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
	fap->ctime.nseconds = vap->va_ctime.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
vattr_to_wcc_attr(struct vattr *vap, wcc_attr *wccap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
	/* Return error if time or size overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
	if (!  (NFS_TIME_T_OK(vap->va_mtime.tv_sec) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
		NFS_TIME_T_OK(vap->va_ctime.tv_sec) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
		NFS3_SIZE_OK(vap->va_size))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
		return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
	wccap->size = (size3)vap->va_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
	wccap->mtime.seconds = vap->va_mtime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
	wccap->mtime.nseconds = vap->va_mtime.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
	wccap->ctime.seconds = vap->va_ctime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
	wccap->ctime.nseconds = vap->va_ctime.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
vattr_to_pre_op_attr(struct vattr *vap, pre_op_attr *poap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
	/* don't return attrs if time overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
	if ((vap != NULL) && !vattr_to_wcc_attr(vap, &poap->attr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
		poap->attributes = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
		poap->attributes = FALSE;
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
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
vattr_to_post_op_attr(struct vattr *vap, post_op_attr *poap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
	/* don't return attrs if time overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
	if ((vap != NULL) && !vattr_to_fattr3(vap, &poap->attr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
		poap->attributes = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
		poap->attributes = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
vattr_to_wcc_data(struct vattr *bvap, struct vattr *avap, wcc_data *wccp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
	vattr_to_pre_op_attr(bvap, &wccp->before);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
	vattr_to_post_op_attr(avap, &wccp->after);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
rfs3_srvrinit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
	struct rfs3_verf_overlay {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
		uint_t id; /* a "unique" identifier */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
		int ts; /* a unique timestamp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
	} *verfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
	timestruc_t now;
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
	 * The following algorithm attempts to find a unique verifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
	 * to be used as the write verifier returned from the server
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
	 * to the client.  It is important that this verifier change
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
	 * whenever the server reboots.  Of secondary importance, it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
	 * is important for the verifier to be unique between two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
	 * different servers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
	 * Thus, an attempt is made to use the system hostid and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
	 * current time in seconds when the nfssrv kernel module is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
	 * loaded.  It is assumed that an NFS server will not be able
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
	 * to boot and then to reboot in less than a second.  If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
	 * hostid has not been set, then the current high resolution
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
	 * time is used.  This will ensure different verifiers each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
	 * time the server reboots and minimize the chances that two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
	 * different servers will have the same verifier.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
#ifndef	lint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
	 * We ASSERT that this constant logic expression is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
	 * always true because in the past, it wasn't.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
	ASSERT(sizeof (*verfp) <= sizeof (write3verf));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
	gethrestime(&now);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
	verfp = (struct rfs3_verf_overlay *)&write3verf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
	verfp->ts = (int)now.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
	verfp->id = (uint_t)nfs_atoi(hw_serial);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
	if (verfp->id == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
		verfp->id = (uint_t)now.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
rfs3_srvrfini(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
	/* Nothing to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
}