annotate usr/src/uts/common/syscall/fcntl.c @ 14022:19e11862653b

3713 Implement accept4() 3714 Implement pipe2() 3715 Implement dup3() 3716 Implement mkostemp() and mkostemps() 3719 so_socketpair syscall should preserve FD_CLOEXEC flag Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Garrett D'Amore <garrett@damore.org>
author Theo Schlossnagle <jesus@omniti.com>
date Thu, 11 Apr 2013 04:50:36 +0000
parents 82cffaae72d5
children c50199ce44c8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
5 * Common Development and Distribution License (the "License").
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
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 */
7088
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
22 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
23 /*
12151
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
24 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
25 * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
26 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
29 /* All Rights Reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
31 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
32 * Portions of this source code were derived from Berkeley 4.3 BSD
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
33 * under license from the Regents of the University of California.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
34 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
35
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
36
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
37 /* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
38
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
39 #include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
40 #include <sys/isa_defs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
41 #include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
42 #include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
43 #include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
44 #include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
45 #include <sys/fcntl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
46 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
47 #include <sys/flock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
48 /* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
49 #include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
50 #include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
51 #include <sys/mode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
52 #include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
53 #include <sys/filio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
54 #include <sys/share.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
55 #include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
56 #include <sys/rctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
57 #include <sys/nbmlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
58
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
59 #include <sys/cmn_err.h>
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
60
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
61 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
62 static int flock_check(vnode_t *, flock64_t *, offset_t, offset_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
63 static int flock_get_start(vnode_t *, flock64_t *, offset_t, u_offset_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
64 static void fd_too_big(proc_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
65
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
66 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
67 * File control.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
68 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
69 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
70 fcntl(int fdes, int cmd, intptr_t arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
71 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
72 int iarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
73 int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
74 int retval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
75 proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
76 file_t *fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
77 vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
78 u_offset_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
79 u_offset_t start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
80 struct vattr vattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
81 int in_crit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
82 int flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
83 struct flock sbf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
84 struct flock64 bf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
85 struct o_flock obf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
86 struct flock64_32 bf64_32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
87 struct fshare fsh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
88 struct shrlock shr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
89 struct shr_locowner shr_own;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
90 offset_t maxoffset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
91 model_t datamodel;
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
92 int fdres;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
94 #if defined(_ILP32) && !defined(lint) && defined(_SYSCALL32)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
95 ASSERT(sizeof (struct flock) == sizeof (struct flock32));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
96 ASSERT(sizeof (struct flock64) == sizeof (struct flock64_32));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
97 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
98 #if defined(_LP64) && !defined(lint) && defined(_SYSCALL32)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
99 ASSERT(sizeof (struct flock) == sizeof (struct flock64_64));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
100 ASSERT(sizeof (struct flock64) == sizeof (struct flock64_64));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
101 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
102
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
103 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
104 * First, for speed, deal with the subset of cases
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
105 * that do not require getf() / releasef().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
106 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
107 switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
108 case F_GETFD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
109 if ((error = f_getfd_error(fdes, &flag)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
110 retval = flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
111 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
113 case F_SETFD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
114 error = f_setfd_error(fdes, (int)arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
115 retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
116 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
118 case F_GETFL:
12801
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
119 if ((error = f_getfl(fdes, &flag)) == 0) {
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
120 retval = (flag & (FMASK | FASYNC));
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
121 if ((flag & (FSEARCH | FEXEC)) == 0)
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
122 retval += FOPEN;
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
123 else
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
124 retval |= (flag & (FSEARCH | FEXEC));
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
125 }
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
126 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
128 case F_GETXFL:
12801
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
129 if ((error = f_getfl(fdes, &flag)) == 0) {
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
130 retval = flag;
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
131 if ((flag & (FSEARCH | FEXEC)) == 0)
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
132 retval += FOPEN;
82cffaae72d5 PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
Roger A. Faulkner <Roger.Faulkner@Oracle.COM>
parents: 12151
diff changeset
133 }
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
134 goto out;
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
135
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
136 case F_BADFD:
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
137 if ((error = f_badfd(fdes, &fdres, (int)arg)) == 0)
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
138 retval = fdres;
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
139 goto out;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
140 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
142 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
143 * Second, for speed, deal with the subset of cases that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
144 * require getf() / releasef() but do not require copyin.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
145 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
146 if ((fp = getf(fdes)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
147 error = EBADF;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
148 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
149 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
150 iarg = (int)arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
152 switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
153 /* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
155 case F_DUPFD:
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
156 case F_DUPFD_CLOEXEC:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
157 p = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
158 if ((uint_t)iarg >= p->p_fno_ctl) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
159 if (iarg >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
160 fd_too_big(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
161 error = EINVAL;
12151
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
162 goto done;
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
163 }
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
164 /*
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
165 * We need to increment the f_count reference counter
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
166 * before allocating a new file descriptor.
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
167 * Doing it other way round opens a window for race condition
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
168 * with closeandsetf() on the target file descriptor which can
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
169 * close the file still referenced by the original
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
170 * file descriptor.
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
171 */
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
172 mutex_enter(&fp->f_tlock);
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
173 fp->f_count++;
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
174 mutex_exit(&fp->f_tlock);
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
175 if ((retval = ufalloc_file(iarg, fp)) == -1) {
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
176 /*
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
177 * New file descriptor can't be allocated.
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
178 * Revert the reference count.
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
179 */
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
180 mutex_enter(&fp->f_tlock);
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
181 fp->f_count--;
a78c082f61ab 6867268 sol10 on T2000: vn_rele: vnode ref count 0
Milan Cermak <Milan.Cermak@Sun.COM>
parents: 11798
diff changeset
182 mutex_exit(&fp->f_tlock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
183 error = EMFILE;
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
184 } else {
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
185 if (cmd == F_DUPFD_CLOEXEC) {
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
186 f_setfd(retval, FD_CLOEXEC);
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
187 }
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
188 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
189 goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
190
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
191 case F_DUP2FD_CLOEXEC:
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
192 if (fdes == iarg) {
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
193 error = EINVAL;
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
194 goto done;
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
195 }
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
196
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
197 /* lint -fallthrough */
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
198
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
199 case F_DUP2FD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
200 p = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
201 if (fdes == iarg) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
202 retval = iarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
203 } else if ((uint_t)iarg >= p->p_fno_ctl) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
204 if (iarg >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
205 fd_too_big(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
206 error = EBADF;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
207 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
208 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
209 * We can't hold our getf(fdes) across the call to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
210 * closeandsetf() because it creates a window for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
211 * deadlock: if one thread is doing dup2(a, b) while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
212 * another is doing dup2(b, a), each one will block
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
213 * waiting for the other to call releasef(). The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
214 * solution is to increment the file reference count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
215 * (which we have to do anyway), then releasef(fdes),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
216 * then closeandsetf(). Incrementing f_count ensures
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
217 * that fp won't disappear after we call releasef().
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
218 * When closeandsetf() fails, we try avoid calling
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
219 * closef() because of all the side effects.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
220 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
221 mutex_enter(&fp->f_tlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
222 fp->f_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
223 mutex_exit(&fp->f_tlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
224 releasef(fdes);
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
225 if ((error = closeandsetf(iarg, fp)) == 0) {
14022
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
226 if (cmd == F_DUP2FD_CLOEXEC) {
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
227 f_setfd(iarg, FD_CLOEXEC);
19e11862653b 3713 Implement accept4()
Theo Schlossnagle <jesus@omniti.com>
parents: 12801
diff changeset
228 }
1846
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
229 retval = iarg;
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
230 } else {
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
231 mutex_enter(&fp->f_tlock);
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
232 if (fp->f_count > 1) {
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
233 fp->f_count--;
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
234 mutex_exit(&fp->f_tlock);
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
235 } else {
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
236 mutex_exit(&fp->f_tlock);
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
237 (void) closef(fp);
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
238 }
376b8b33ed65 PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents: 923
diff changeset
239 }
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
240 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
241 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
242 goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
244 case F_SETFL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
245 vp = fp->f_vnode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
246 flag = fp->f_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
247 if ((iarg & (FNONBLOCK|FNDELAY)) == (FNONBLOCK|FNDELAY))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
248 iarg &= ~FNDELAY;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
249 if ((error = VOP_SETFL(vp, flag, iarg, fp->f_cred, NULL)) ==
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
250 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
251 iarg &= FMASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
252 mutex_enter(&fp->f_tlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
253 fp->f_flag &= ~FMASK | (FREAD|FWRITE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
254 fp->f_flag |= (iarg - FOPEN) & ~(FREAD|FWRITE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
255 mutex_exit(&fp->f_tlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
256 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
257 retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
258 goto done;
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 * Finally, deal with the expensive cases.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
263 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
264 retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
265 in_crit = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
266 maxoffset = MAXOFF_T;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
267 datamodel = DATAMODEL_NATIVE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
268 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
269 if ((datamodel = get_udatamodel()) == DATAMODEL_ILP32)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
270 maxoffset = MAXOFF32_T;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
271 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
273 vp = fp->f_vnode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
274 flag = fp->f_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
275 offset = fp->f_offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
277 switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
278 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
279 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
280 * The file system and vnode layers understand and implement
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
281 * locking with flock64 structures. So here once we pass through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
282 * the test for compatibility as defined by LFS API, (for F_SETLK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
283 * F_SETLKW, F_GETLK, F_GETLKW, F_FREESP) we transform
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
284 * the flock structure to a flock64 structure and send it to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
285 * lower layers. Similarly in case of GETLK the returned flock64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
286 * structure is transformed to a flock structure if everything fits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
287 * in nicely, otherwise we return EOVERFLOW.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
288 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
290 case F_GETLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
291 case F_O_GETLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
292 case F_SETLK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
293 case F_SETLKW:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
294 case F_SETLK_NBMAND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
296 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
297 * Copy in input fields only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
298 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
300 if (cmd == F_O_GETLK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
301 if (datamodel != DATAMODEL_ILP32) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
302 error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
303 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
304 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
306 if (copyin((void *)arg, &obf, sizeof (obf))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
307 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
308 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
309 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
310 bf.l_type = obf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
311 bf.l_whence = obf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
312 bf.l_start = (off64_t)obf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
313 bf.l_len = (off64_t)obf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
314 bf.l_sysid = (int)obf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
315 bf.l_pid = obf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
316 } else if (datamodel == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
317 if (copyin((void *)arg, &sbf, sizeof (sbf))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
318 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
319 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
320 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
321 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
322 * XXX In an LP64 kernel with an LP64 application
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
323 * there's no need to do a structure copy here
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
324 * struct flock == struct flock64. However,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
325 * we did it this way to avoid more conditional
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
326 * compilation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
327 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
328 bf.l_type = sbf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
329 bf.l_whence = sbf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
330 bf.l_start = (off64_t)sbf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
331 bf.l_len = (off64_t)sbf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
332 bf.l_sysid = sbf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
333 bf.l_pid = sbf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
334 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
335 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
336 else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
337 struct flock32 sbf32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
338 if (copyin((void *)arg, &sbf32, sizeof (sbf32))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
339 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
340 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
341 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
342 bf.l_type = sbf32.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
343 bf.l_whence = sbf32.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
344 bf.l_start = (off64_t)sbf32.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
345 bf.l_len = (off64_t)sbf32.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
346 bf.l_sysid = sbf32.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
347 bf.l_pid = sbf32.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
348 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
349 #endif /* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
351 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
352 * 64-bit support: check for overflow for 32-bit lock ops
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
353 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
354 if ((error = flock_check(vp, &bf, offset, maxoffset)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
355 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
357 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
358 * Not all of the filesystems understand F_O_GETLK, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
359 * there's no need for them to know. Map it to F_GETLK.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
360 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
361 if ((error = VOP_FRLOCK(vp, (cmd == F_O_GETLK) ? F_GETLK : cmd,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
362 &bf, flag, offset, NULL, fp->f_cred, NULL)) != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
363 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
365 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
366 * If command is GETLK and no lock is found, only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
367 * the type field is changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
368 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
369 if ((cmd == F_O_GETLK || cmd == F_GETLK) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
370 bf.l_type == F_UNLCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
371 /* l_type always first entry, always a short */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
372 if (copyout(&bf.l_type, &((struct flock *)arg)->l_type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
373 sizeof (bf.l_type)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
374 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
375 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
376 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
378 if (cmd == F_O_GETLK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
379 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
380 * Return an SVR3 flock structure to the user.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
381 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
382 obf.l_type = (int16_t)bf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
383 obf.l_whence = (int16_t)bf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
384 obf.l_start = (int32_t)bf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
385 obf.l_len = (int32_t)bf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
386 if (bf.l_sysid > SHRT_MAX || bf.l_pid > SHRT_MAX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
387 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
388 * One or both values for the above fields
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
389 * is too large to store in an SVR3 flock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
390 * structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
391 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
392 error = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
393 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
394 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
395 obf.l_sysid = (int16_t)bf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
396 obf.l_pid = (int16_t)bf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
397 if (copyout(&obf, (void *)arg, sizeof (obf)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
398 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
399 } else if (cmd == F_GETLK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
400 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
401 * Copy out SVR4 flock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
402 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
403 int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
405 if (bf.l_start > maxoffset || bf.l_len > maxoffset) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
406 error = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
407 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
408 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
409
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
410 if (datamodel == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
411 for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
412 sbf.l_pad[i] = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
413 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
414 * XXX In an LP64 kernel with an LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
415 * application there's no need to do a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
416 * structure copy here as currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
417 * struct flock == struct flock64.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
418 * We did it this way to avoid more
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
419 * conditional compilation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
420 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
421 sbf.l_type = bf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
422 sbf.l_whence = bf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
423 sbf.l_start = (off_t)bf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
424 sbf.l_len = (off_t)bf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
425 sbf.l_sysid = bf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
426 sbf.l_pid = bf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
427 if (copyout(&sbf, (void *)arg, sizeof (sbf)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
428 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
429 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
430 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
431 else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
432 struct flock32 sbf32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
433 if (bf.l_start > MAXOFF32_T ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
434 bf.l_len > MAXOFF32_T) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
435 error = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
436 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
437 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
438 for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
439 sbf32.l_pad[i] = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
440 sbf32.l_type = (int16_t)bf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
441 sbf32.l_whence = (int16_t)bf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
442 sbf32.l_start = (off32_t)bf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
443 sbf32.l_len = (off32_t)bf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
444 sbf32.l_sysid = (int32_t)bf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
445 sbf32.l_pid = (pid32_t)bf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
446 if (copyout(&sbf32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
447 (void *)arg, sizeof (sbf32)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
448 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
449 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
450 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
451 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
452 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
453 /* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
455 case F_CHKFL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
456 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
457 * This is for internal use only, to allow the vnode layer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
458 * to validate a flags setting before applying it. User
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
459 * programs can't issue it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
460 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
461 error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
462 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
464 case F_ALLOCSP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
465 case F_FREESP:
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
466 case F_ALLOCSP64:
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
467 case F_FREESP64:
7088
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
468 /*
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
469 * Test for not-a-regular-file (and returning EINVAL)
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
470 * before testing for open-for-writing (and returning EBADF).
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
471 * This is relied upon by posix_fallocate() in libc.
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
472 */
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
473 if (vp->v_type != VREG) {
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
474 error = EINVAL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
475 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
476 }
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
477
7088
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
478 if ((flag & FWRITE) == 0) {
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
479 error = EBADF;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
480 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
481 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
482
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
483 if (datamodel != DATAMODEL_ILP32 &&
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
484 (cmd == F_ALLOCSP64 || cmd == F_FREESP64)) {
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
485 error = EINVAL;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
486 break;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
487 }
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
488
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
489 #if defined(_ILP32) || defined(_SYSCALL32_IMPL)
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
490 if (datamodel == DATAMODEL_ILP32 &&
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
491 (cmd == F_ALLOCSP || cmd == F_FREESP)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
492 struct flock32 sbf32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
493 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
494 * For compatibility we overlay an SVR3 flock on an SVR4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
495 * flock. This works because the input field offsets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
496 * in "struct flock" were preserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
497 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
498 if (copyin((void *)arg, &sbf32, sizeof (sbf32))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
499 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
500 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
501 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
502 bf.l_type = sbf32.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
503 bf.l_whence = sbf32.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
504 bf.l_start = (off64_t)sbf32.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
505 bf.l_len = (off64_t)sbf32.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
506 bf.l_sysid = sbf32.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
507 bf.l_pid = sbf32.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
508 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
509 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
510 #endif /* _ILP32 || _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
511
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
512 #if defined(_LP64)
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
513 if (datamodel == DATAMODEL_LP64 &&
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
514 (cmd == F_ALLOCSP || cmd == F_FREESP)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
515 if (copyin((void *)arg, &bf, sizeof (bf))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
516 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
517 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
518 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
519 }
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
520 #endif /* defined(_LP64) */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
521
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
522 #if !defined(_LP64) || defined(_SYSCALL32_IMPL)
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
523 if (datamodel == DATAMODEL_ILP32 &&
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
524 (cmd == F_ALLOCSP64 || cmd == F_FREESP64)) {
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
525 if (copyin((void *)arg, &bf64_32, sizeof (bf64_32))) {
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
526 error = EFAULT;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
527 break;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
528 } else {
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
529 /*
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
530 * Note that the size of flock64 is different in
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
531 * the ILP32 and LP64 models, due to the l_pad
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
532 * field. We do not want to assume that the
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
533 * flock64 structure is laid out the same in
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
534 * ILP32 and LP64 environments, so we will
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
535 * copy in the ILP32 version of flock64
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
536 * explicitly and copy it to the native
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
537 * flock64 structure.
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
538 */
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
539 bf.l_type = (short)bf64_32.l_type;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
540 bf.l_whence = (short)bf64_32.l_whence;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
541 bf.l_start = bf64_32.l_start;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
542 bf.l_len = bf64_32.l_len;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
543 bf.l_sysid = (int)bf64_32.l_sysid;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
544 bf.l_pid = (pid_t)bf64_32.l_pid;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
545 }
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
546 }
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
547 #endif /* !defined(_LP64) || defined(_SYSCALL32_IMPL) */
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
548
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
549 if (cmd == F_ALLOCSP || cmd == F_FREESP)
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
550 error = flock_check(vp, &bf, offset, maxoffset);
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
551 else if (cmd == F_ALLOCSP64 || cmd == F_FREESP64)
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
552 error = flock_check(vp, &bf, offset, MAXOFFSET_T);
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
553 if (error)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
554 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
556 if (vp->v_type == VREG && bf.l_len == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
557 bf.l_start > OFFSET_MAX(fp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
558 error = EFBIG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
559 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
560 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
562 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
563 * Make sure that there are no conflicting non-blocking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
564 * mandatory locks in the region being manipulated. If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
565 * there are such locks then return EACCES.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
566 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
567 if ((error = flock_get_start(vp, &bf, offset, &start)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
568 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
570 if (nbl_need_check(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
571 u_offset_t begin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
572 ssize_t length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
574 nbl_start_crit(vp, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
575 in_crit = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
576 vattr.va_mask = AT_SIZE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
577 if ((error = VOP_GETATTR(vp, &vattr, 0, CRED(), NULL))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
578 != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
579 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
580 begin = start > vattr.va_size ? vattr.va_size : start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
581 length = vattr.va_size > start ? vattr.va_size - start :
7088
87e6b40103da PSARC 2008/421 _POSIX_ADVISORY_INFO
raf
parents: 5331
diff changeset
582 start - vattr.va_size;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
583 if (nbl_conflict(vp, NBL_WRITE, begin, length, 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
584 NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
585 error = EACCES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
586 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
587 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
588 }
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
589
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
590 if (cmd == F_ALLOCSP64)
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
591 cmd = F_ALLOCSP;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
592 else if (cmd == F_FREESP64)
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
593 cmd = F_FREESP;
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
594
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
595 error = VOP_SPACE(vp, cmd, &bf, flag, offset, fp->f_cred, NULL);
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
596
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
597 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
598
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
599 #if !defined(_LP64) || defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
600 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
601 case F_GETLK64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
602 case F_SETLK64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
603 case F_SETLKW64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
604 case F_SETLK64_NBMAND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
605 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
606 * Large Files: Here we set cmd as *LK and send it to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
607 * lower layers. *LK64 is only for the user land.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
608 * Most of the comments described above for F_SETLK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
609 * applies here too.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
610 * Large File support is only needed for ILP32 apps!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
611 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
612 if (datamodel != DATAMODEL_ILP32) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
613 error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
614 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
615 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
617 if (cmd == F_GETLK64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
618 cmd = F_GETLK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
619 else if (cmd == F_SETLK64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
620 cmd = F_SETLK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
621 else if (cmd == F_SETLKW64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
622 cmd = F_SETLKW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
623 else if (cmd == F_SETLK64_NBMAND)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
624 cmd = F_SETLK_NBMAND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
625
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
626 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
627 * Note that the size of flock64 is different in the ILP32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
628 * and LP64 models, due to the sucking l_pad field.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
629 * We do not want to assume that the flock64 structure is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
630 * laid out in the same in ILP32 and LP64 environments, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
631 * we will copy in the ILP32 version of flock64 explicitly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
632 * and copy it to the native flock64 structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
633 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
635 if (copyin((void *)arg, &bf64_32, sizeof (bf64_32))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
636 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
637 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
638 }
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
639
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
640 bf.l_type = (short)bf64_32.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
641 bf.l_whence = (short)bf64_32.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
642 bf.l_start = bf64_32.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
643 bf.l_len = bf64_32.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
644 bf.l_sysid = (int)bf64_32.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
645 bf.l_pid = (pid_t)bf64_32.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
647 if ((error = flock_check(vp, &bf, offset, MAXOFFSET_T)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
648 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
650 if ((error = VOP_FRLOCK(vp, cmd, &bf, flag, offset,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
651 NULL, fp->f_cred, NULL)) != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
652 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
654 if ((cmd == F_GETLK) && bf.l_type == F_UNLCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
655 if (copyout(&bf.l_type, &((struct flock *)arg)->l_type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
656 sizeof (bf.l_type)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
657 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
658 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
659 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
661 if (cmd == F_GETLK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
662 int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
664 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
665 * We do not want to assume that the flock64 structure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
666 * is laid out in the same in ILP32 and LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
667 * environments, so we will copy out the ILP32 version
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
668 * of flock64 explicitly after copying the native
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
669 * flock64 structure to it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
670 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
671 for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
672 bf64_32.l_pad[i] = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
673 bf64_32.l_type = (int16_t)bf.l_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
674 bf64_32.l_whence = (int16_t)bf.l_whence;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
675 bf64_32.l_start = bf.l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
676 bf64_32.l_len = bf.l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
677 bf64_32.l_sysid = (int32_t)bf.l_sysid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
678 bf64_32.l_pid = (pid32_t)bf.l_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
679 if (copyout(&bf64_32, (void *)arg, sizeof (bf64_32)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
680 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
681 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
682 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
683 /* ONC_PLUS EXTRACT END */
923
78f6e60ae914 PSARC 2004/422 posix_fallocate
sdebnath
parents: 0
diff changeset
684 #endif /* !defined(_LP64) || defined(_SYSCALL32_IMPL) */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
685
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
686 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
687 case F_SHARE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
688 case F_SHARE_NBMAND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
689 case F_UNSHARE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
691 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
692 * Copy in input fields only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
693 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
694 if (copyin((void *)arg, &fsh, sizeof (fsh))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
695 error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
696 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
697 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
698
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
699 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
700 * Local share reservations always have this simple form
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
701 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
702 shr.s_access = fsh.f_access;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
703 shr.s_deny = fsh.f_deny;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
704 shr.s_sysid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
705 shr.s_pid = ttoproc(curthread)->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
706 shr_own.sl_pid = shr.s_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
707 shr_own.sl_id = fsh.f_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
708 shr.s_own_len = sizeof (shr_own);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
709 shr.s_owner = (caddr_t)&shr_own;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
710 error = VOP_SHRLOCK(vp, cmd, &shr, flag, fp->f_cred, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
711 /* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
712 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
714 default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
715 error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
716 break;
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 (in_crit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
720 nbl_end_crit(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
722 done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
723 releasef(fdes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
724 out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
725 if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
726 return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
727 return (retval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
728 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
730 /* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
731 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
732 flock_check(vnode_t *vp, flock64_t *flp, offset_t offset, offset_t max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
733 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
734 struct vattr vattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
735 int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
736 u_offset_t start, end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
738 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
739 * Determine the starting point of the request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
740 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
741 switch (flp->l_whence) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
742 case 0: /* SEEK_SET */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
743 start = (u_offset_t)flp->l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
744 if (start > max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
745 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
746 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
747 case 1: /* SEEK_CUR */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
748 if (flp->l_start > (max - offset))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
749 return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
750 start = (u_offset_t)(flp->l_start + offset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
751 if (start > max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
752 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
753 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
754 case 2: /* SEEK_END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
755 vattr.va_mask = AT_SIZE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
756 if (error = VOP_GETATTR(vp, &vattr, 0, CRED(), NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
757 return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
758 if (flp->l_start > (max - (offset_t)vattr.va_size))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
759 return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
760 start = (u_offset_t)(flp->l_start + (offset_t)vattr.va_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
761 if (start > max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
762 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
763 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
764 default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
765 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
766 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
768 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
769 * Determine the range covered by the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
770 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
771 if (flp->l_len == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
772 end = MAXEND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
773 else if ((offset_t)flp->l_len > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
774 if (flp->l_len > (max - start + 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
775 return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
776 end = (u_offset_t)(start + (flp->l_len - 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
777 ASSERT(end <= max);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
778 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
779 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
780 * Negative length; why do we even allow this ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
781 * Because this allows easy specification of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
782 * the last n bytes of the file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
783 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
784 end = start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
785 start += (u_offset_t)flp->l_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
786 (start)++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
787 if (start > max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
788 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
789 ASSERT(end <= max);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
790 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
791 ASSERT(start <= max);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
792 if (flp->l_type == F_UNLCK && flp->l_len > 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
793 end == (offset_t)max) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
794 flp->l_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
795 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
796 if (start > end)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
797 return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
798 return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
799 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
801 static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
802 flock_get_start(vnode_t *vp, flock64_t *flp, offset_t offset, u_offset_t *start)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
803 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
804 struct vattr vattr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
805 int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
807 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
808 * Determine the starting point of the request. Assume that it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
809 * a valid starting point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
810 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
811 switch (flp->l_whence) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
812 case 0: /* SEEK_SET */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
813 *start = (u_offset_t)flp->l_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
814 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
815 case 1: /* SEEK_CUR */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
816 *start = (u_offset_t)(flp->l_start + offset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
817 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
818 case 2: /* SEEK_END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
819 vattr.va_mask = AT_SIZE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 1846
diff changeset
820 if (error = VOP_GETATTR(vp, &vattr, 0, CRED(), NULL))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
821 return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
822 *start = (u_offset_t)(flp->l_start + (offset_t)vattr.va_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
823 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
824 default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
825 return (EINVAL);
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 return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
829 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
831 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
832 * Take rctl action when the requested file descriptor is too big.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
833 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
834 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
835 fd_too_big(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
836 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
837 mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
838 (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
839 p->p_rctls, p, RCA_SAFE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
840 mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
841 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
842 /* ONC_PLUS EXTRACT END */