1*8329232eSGordon Ross /*
2*8329232eSGordon Ross  * CDDL HEADER START
3*8329232eSGordon Ross  *
4*8329232eSGordon Ross  * The contents of this file are subject to the terms of the
5*8329232eSGordon Ross  * Common Development and Distribution License (the "License").
6*8329232eSGordon Ross  * You may not use this file except in compliance with the License.
7*8329232eSGordon Ross  *
8*8329232eSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*8329232eSGordon Ross  * or http://www.opensolaris.org/os/licensing.
10*8329232eSGordon Ross  * See the License for the specific language governing permissions
11*8329232eSGordon Ross  * and limitations under the License.
12*8329232eSGordon Ross  *
13*8329232eSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14*8329232eSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*8329232eSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16*8329232eSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17*8329232eSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18*8329232eSGordon Ross  *
19*8329232eSGordon Ross  * CDDL HEADER END
20*8329232eSGordon Ross  */
21*8329232eSGordon Ross /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
22*8329232eSGordon Ross /*	  All Rights Reserved	*/
23*8329232eSGordon Ross 
24*8329232eSGordon Ross 
25*8329232eSGordon Ross /*
26*8329232eSGordon Ross  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
27*8329232eSGordon Ross  * Copyright 2017 Joyent, Inc.
28*8329232eSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
29*8329232eSGordon Ross  */
30*8329232eSGordon Ross 
31*8329232eSGordon Ross /*
32*8329232eSGordon Ross  * Generic vnode operations.
33*8329232eSGordon Ross  */
34*8329232eSGordon Ross #include <sys/types.h>
35*8329232eSGordon Ross #include <sys/param.h>
36*8329232eSGordon Ross #include <sys/systm.h>
37*8329232eSGordon Ross #include <sys/errno.h>
38*8329232eSGordon Ross #include <sys/fcntl.h>
39*8329232eSGordon Ross #include <sys/flock.h>
40*8329232eSGordon Ross #include <sys/statvfs.h>
41*8329232eSGordon Ross #include <sys/vfs.h>
42*8329232eSGordon Ross #include <sys/vnode.h>
43*8329232eSGordon Ross #include <sys/cred.h>
44*8329232eSGordon Ross #include <sys/poll.h>
45*8329232eSGordon Ross #include <sys/debug.h>
46*8329232eSGordon Ross #include <sys/cmn_err.h>
47*8329232eSGordon Ross #include <sys/share.h>
48*8329232eSGordon Ross #include <sys/file.h>
49*8329232eSGordon Ross #include <sys/kmem.h>
50*8329232eSGordon Ross #include <sys/nbmlock.h>
51*8329232eSGordon Ross #include <sys/acl.h>
52*8329232eSGordon Ross 
53*8329232eSGordon Ross #include <acl/acl_common.h>
54*8329232eSGordon Ross #include <fs/fs_subr.h>
55*8329232eSGordon Ross 
56*8329232eSGordon Ross /*
57*8329232eSGordon Ross  * Tunable to limit the number of retry to recover from STALE error.
58*8329232eSGordon Ross  */
59*8329232eSGordon Ross int fs_estale_retry = 5;
60*8329232eSGordon Ross 
61*8329232eSGordon Ross /*
62*8329232eSGordon Ross  * The associated operation is not supported by the file system.
63*8329232eSGordon Ross  */
64*8329232eSGordon Ross int
fs_nosys()65*8329232eSGordon Ross fs_nosys()
66*8329232eSGordon Ross {
67*8329232eSGordon Ross 	return (ENOSYS);
68*8329232eSGordon Ross }
69*8329232eSGordon Ross 
70*8329232eSGordon Ross /*
71*8329232eSGordon Ross  * The associated operation is invalid (on this vnode).
72*8329232eSGordon Ross  */
73*8329232eSGordon Ross int
fs_inval()74*8329232eSGordon Ross fs_inval()
75*8329232eSGordon Ross {
76*8329232eSGordon Ross 	return (EINVAL);
77*8329232eSGordon Ross }
78*8329232eSGordon Ross 
79*8329232eSGordon Ross /*
80*8329232eSGordon Ross  * The associated operation is valid only for directories.
81*8329232eSGordon Ross  */
82*8329232eSGordon Ross int
fs_notdir()83*8329232eSGordon Ross fs_notdir()
84*8329232eSGordon Ross {
85*8329232eSGordon Ross 	return (ENOTDIR);
86*8329232eSGordon Ross }
87*8329232eSGordon Ross 
88*8329232eSGordon Ross /*
89*8329232eSGordon Ross  * Free the file system specific resources. For the file systems that
90*8329232eSGordon Ross  * do not support the forced unmount, it will be a nop function.
91*8329232eSGordon Ross  */
92*8329232eSGordon Ross 
93*8329232eSGordon Ross /*ARGSUSED*/
94*8329232eSGordon Ross void
fs_freevfs(vfs_t * vfsp)95*8329232eSGordon Ross fs_freevfs(vfs_t *vfsp)
96*8329232eSGordon Ross {
97*8329232eSGordon Ross }
98*8329232eSGordon Ross 
99*8329232eSGordon Ross /* ARGSUSED */
100*8329232eSGordon Ross int
fs_nosys_map(struct vnode * vp,offset_t off,struct as * as,caddr_t * addrp,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,struct cred * cr,caller_context_t * ct)101*8329232eSGordon Ross fs_nosys_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
102*8329232eSGordon Ross     size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr,
103*8329232eSGordon Ross     caller_context_t *ct)
104*8329232eSGordon Ross {
105*8329232eSGordon Ross 	return (ENOSYS);
106*8329232eSGordon Ross }
107*8329232eSGordon Ross 
108*8329232eSGordon Ross /* ARGSUSED */
109*8329232eSGordon Ross int
fs_nosys_addmap(struct vnode * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,struct cred * cr,caller_context_t * ct)110*8329232eSGordon Ross fs_nosys_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
111*8329232eSGordon Ross     size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr,
112*8329232eSGordon Ross     caller_context_t *ct)
113*8329232eSGordon Ross {
114*8329232eSGordon Ross 	return (ENOSYS);
115*8329232eSGordon Ross }
116*8329232eSGordon Ross 
117*8329232eSGordon Ross /* ARGSUSED */
118*8329232eSGordon Ross int
fs_nosys_poll(vnode_t * vp,short events,int anyyet,short * reventsp,struct pollhead ** phpp,caller_context_t * ct)119*8329232eSGordon Ross fs_nosys_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
120*8329232eSGordon Ross     struct pollhead **phpp, caller_context_t *ct)
121*8329232eSGordon Ross {
122*8329232eSGordon Ross 	return (ENOSYS);
123*8329232eSGordon Ross }
124*8329232eSGordon Ross 
125*8329232eSGordon Ross 
126*8329232eSGordon Ross /*
127*8329232eSGordon Ross  * The file system has nothing to sync to disk.  However, the
128*8329232eSGordon Ross  * VFS_SYNC operation must not fail.
129*8329232eSGordon Ross  */
130*8329232eSGordon Ross /* ARGSUSED */
131*8329232eSGordon Ross int
fs_sync(struct vfs * vfspp,short flag,cred_t * cr)132*8329232eSGordon Ross fs_sync(struct vfs *vfspp, short flag, cred_t *cr)
133*8329232eSGordon Ross {
134*8329232eSGordon Ross 	return (0);
135*8329232eSGordon Ross }
136*8329232eSGordon Ross 
137*8329232eSGordon Ross /*
138*8329232eSGordon Ross  * Does nothing but VOP_FSYNC must not fail.
139*8329232eSGordon Ross  */
140*8329232eSGordon Ross /* ARGSUSED */
141*8329232eSGordon Ross int
fs_fsync(vnode_t * vp,int syncflag,cred_t * cr,caller_context_t * ct)142*8329232eSGordon Ross fs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
143*8329232eSGordon Ross {
144*8329232eSGordon Ross 	return (0);
145*8329232eSGordon Ross }
146*8329232eSGordon Ross 
147*8329232eSGordon Ross /*
148*8329232eSGordon Ross  * Does nothing but VOP_PUTPAGE must not fail.
149*8329232eSGordon Ross  */
150*8329232eSGordon Ross /* ARGSUSED */
151*8329232eSGordon Ross int
fs_putpage(vnode_t * vp,offset_t off,size_t len,int flags,cred_t * cr,caller_context_t * ctp)152*8329232eSGordon Ross fs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr,
153*8329232eSGordon Ross     caller_context_t *ctp)
154*8329232eSGordon Ross {
155*8329232eSGordon Ross 	return (0);
156*8329232eSGordon Ross }
157*8329232eSGordon Ross 
158*8329232eSGordon Ross /*
159*8329232eSGordon Ross  * Does nothing but VOP_IOCTL must not fail.
160*8329232eSGordon Ross  */
161*8329232eSGordon Ross /* ARGSUSED */
162*8329232eSGordon Ross int
fs_ioctl(vnode_t * vp,int com,intptr_t data,int flag,cred_t * cred,int * rvalp)163*8329232eSGordon Ross fs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred,
164*8329232eSGordon Ross     int *rvalp)
165*8329232eSGordon Ross {
166*8329232eSGordon Ross 	return (0);
167*8329232eSGordon Ross }
168*8329232eSGordon Ross 
169*8329232eSGordon Ross /*
170*8329232eSGordon Ross  * Read/write lock/unlock.  Does nothing.
171*8329232eSGordon Ross  */
172*8329232eSGordon Ross /* ARGSUSED */
173*8329232eSGordon Ross int
fs_rwlock(vnode_t * vp,int write_lock,caller_context_t * ctp)174*8329232eSGordon Ross fs_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
175*8329232eSGordon Ross {
176*8329232eSGordon Ross 	return (-1);
177*8329232eSGordon Ross }
178*8329232eSGordon Ross 
179*8329232eSGordon Ross /* ARGSUSED */
180*8329232eSGordon Ross void
fs_rwunlock(vnode_t * vp,int write_lock,caller_context_t * ctp)181*8329232eSGordon Ross fs_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
182*8329232eSGordon Ross {
183*8329232eSGordon Ross }
184*8329232eSGordon Ross 
185*8329232eSGordon Ross /*
186*8329232eSGordon Ross  * Compare two vnodes.
187*8329232eSGordon Ross  */
188*8329232eSGordon Ross /*ARGSUSED2*/
189*8329232eSGordon Ross int
fs_cmp(vnode_t * vp1,vnode_t * vp2,caller_context_t * ct)190*8329232eSGordon Ross fs_cmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
191*8329232eSGordon Ross {
192*8329232eSGordon Ross 	return (vp1 == vp2);
193*8329232eSGordon Ross }
194*8329232eSGordon Ross 
195*8329232eSGordon Ross /*
196*8329232eSGordon Ross  * No-op seek operation.
197*8329232eSGordon Ross  */
198*8329232eSGordon Ross /* ARGSUSED */
199*8329232eSGordon Ross int
fs_seek(vnode_t * vp,offset_t ooff,offset_t * noffp,caller_context_t * ct)200*8329232eSGordon Ross fs_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
201*8329232eSGordon Ross {
202*8329232eSGordon Ross 	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
203*8329232eSGordon Ross }
204*8329232eSGordon Ross 
205*8329232eSGordon Ross /*
206*8329232eSGordon Ross  * File and record locking.
207*8329232eSGordon Ross  */
208*8329232eSGordon Ross /* ARGSUSED */
209*8329232eSGordon Ross int
fs_frlock(vnode_t * vp,int cmd,struct flock64 * bfp,int flag,offset_t offset,flk_callback_t * flk_cbp,cred_t * cr,caller_context_t * ct)210*8329232eSGordon Ross fs_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, offset_t offset,
211*8329232eSGordon Ross     flk_callback_t *flk_cbp, cred_t *cr, caller_context_t *ct)
212*8329232eSGordon Ross {
213*8329232eSGordon Ross 	return (ENOSYS);
214*8329232eSGordon Ross }
215*8329232eSGordon Ross 
216*8329232eSGordon Ross /*
217*8329232eSGordon Ross  * Allow any flags.
218*8329232eSGordon Ross  */
219*8329232eSGordon Ross /* ARGSUSED */
220*8329232eSGordon Ross int
fs_setfl(vnode_t * vp,int oflags,int nflags,cred_t * cr,caller_context_t * ct)221*8329232eSGordon Ross fs_setfl(vnode_t *vp, int oflags, int nflags, cred_t *cr, caller_context_t *ct)
222*8329232eSGordon Ross {
223*8329232eSGordon Ross 	return (0);
224*8329232eSGordon Ross }
225*8329232eSGordon Ross 
226*8329232eSGordon Ross /*
227*8329232eSGordon Ross  * Return the answer requested to poll() for non-device files.
228*8329232eSGordon Ross  * Only POLLIN, POLLRDNORM, and POLLOUT are recognized.
229*8329232eSGordon Ross  */
230*8329232eSGordon Ross struct pollhead fs_pollhd;
231*8329232eSGordon Ross 
232*8329232eSGordon Ross /* ARGSUSED */
233*8329232eSGordon Ross int
fs_poll(vnode_t * vp,short events,int anyyet,short * reventsp,struct pollhead ** phpp,caller_context_t * ct)234*8329232eSGordon Ross fs_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
235*8329232eSGordon Ross     struct pollhead **phpp, caller_context_t *ct)
236*8329232eSGordon Ross {
237*8329232eSGordon Ross 	if (events & POLLET) {
238*8329232eSGordon Ross 		return (EPERM);
239*8329232eSGordon Ross 	}
240*8329232eSGordon Ross 
241*8329232eSGordon Ross 	*reventsp = 0;
242*8329232eSGordon Ross 	if (events & POLLIN)
243*8329232eSGordon Ross 		*reventsp |= POLLIN;
244*8329232eSGordon Ross 	if (events & POLLRDNORM)
245*8329232eSGordon Ross 		*reventsp |= POLLRDNORM;
246*8329232eSGordon Ross 	if (events & POLLRDBAND)
247*8329232eSGordon Ross 		*reventsp |= POLLRDBAND;
248*8329232eSGordon Ross 	if (events & POLLOUT)
249*8329232eSGordon Ross 		*reventsp |= POLLOUT;
250*8329232eSGordon Ross 	if (events & POLLWRBAND)
251*8329232eSGordon Ross 		*reventsp |= POLLWRBAND;
252*8329232eSGordon Ross 	if (*reventsp == 0 && !anyyet) {
253*8329232eSGordon Ross 		*phpp = &fs_pollhd;
254*8329232eSGordon Ross 	}
255*8329232eSGordon Ross 	return (0);
256*8329232eSGordon Ross }
257*8329232eSGordon Ross 
258*8329232eSGordon Ross /*
259*8329232eSGordon Ross  * POSIX pathconf() support.
260*8329232eSGordon Ross  */
261*8329232eSGordon Ross /* ARGSUSED */
262*8329232eSGordon Ross int
fs_pathconf(vnode_t * vp,int cmd,ulong_t * valp,cred_t * cr,caller_context_t * ct)263*8329232eSGordon Ross fs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
264*8329232eSGordon Ross     caller_context_t *ct)
265*8329232eSGordon Ross {
266*8329232eSGordon Ross 	/* not called */
267*8329232eSGordon Ross 	return (EINVAL);
268*8329232eSGordon Ross }
269*8329232eSGordon Ross 
270*8329232eSGordon Ross /*
271*8329232eSGordon Ross  * Dispose of a page.
272*8329232eSGordon Ross  */
273*8329232eSGordon Ross /* ARGSUSED */
274*8329232eSGordon Ross void
fs_dispose(struct vnode * vp,page_t * pp,int fl,int dn,struct cred * cr,caller_context_t * ct)275*8329232eSGordon Ross fs_dispose(struct vnode *vp, page_t *pp, int fl, int dn, struct cred *cr,
276*8329232eSGordon Ross     caller_context_t *ct)
277*8329232eSGordon Ross {
278*8329232eSGordon Ross }
279*8329232eSGordon Ross 
280*8329232eSGordon Ross /* ARGSUSED */
281*8329232eSGordon Ross void
fs_nodispose(struct vnode * vp,page_t * pp,int fl,int dn,struct cred * cr,caller_context_t * ct)282*8329232eSGordon Ross fs_nodispose(struct vnode *vp, page_t *pp, int fl, int dn, struct cred *cr,
283*8329232eSGordon Ross     caller_context_t *ct)
284*8329232eSGordon Ross {
285*8329232eSGordon Ross 	cmn_err(CE_PANIC, "fs_nodispose invoked");
286*8329232eSGordon Ross }
287*8329232eSGordon Ross 
288*8329232eSGordon Ross /*
289*8329232eSGordon Ross  * fabricate acls for file systems that do not support acls.
290*8329232eSGordon Ross  */
291*8329232eSGordon Ross /* ARGSUSED */
292*8329232eSGordon Ross int
fs_fab_acl(vnode_t * vp,vsecattr_t * vsecattr,int flag,cred_t * cr,caller_context_t * ct)293*8329232eSGordon Ross fs_fab_acl(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr,
294*8329232eSGordon Ross     caller_context_t *ct)
295*8329232eSGordon Ross {
296*8329232eSGordon Ross 	struct vattr	vattr;
297*8329232eSGordon Ross 	int		error;
298*8329232eSGordon Ross 
299*8329232eSGordon Ross 	vsecattr->vsa_aclcnt	= 0;
300*8329232eSGordon Ross 	vsecattr->vsa_aclentsz	= 0;
301*8329232eSGordon Ross 	vsecattr->vsa_aclentp	= NULL;
302*8329232eSGordon Ross 	vsecattr->vsa_dfaclcnt	= 0;	/* Default ACLs are not fabricated */
303*8329232eSGordon Ross 	vsecattr->vsa_dfaclentp	= NULL;
304*8329232eSGordon Ross 
305*8329232eSGordon Ross 	vattr.va_mask = AT_MODE | AT_UID | AT_GID;
306*8329232eSGordon Ross 	if (error = VOP_GETATTR(vp, &vattr, 0, cr, ct))
307*8329232eSGordon Ross 		return (error);
308*8329232eSGordon Ross 
309*8329232eSGordon Ross 	if (vsecattr->vsa_mask & (VSA_ACLCNT | VSA_ACL)) {
310*8329232eSGordon Ross 		return (ENOSYS);
311*8329232eSGordon Ross 	}
312*8329232eSGordon Ross 
313*8329232eSGordon Ross 	if (vsecattr->vsa_mask & (VSA_ACECNT | VSA_ACE)) {
314*8329232eSGordon Ross 		VERIFY(0 == acl_trivial_create(vattr.va_mode,
315*8329232eSGordon Ross 		    (vp->v_type == VDIR), (ace_t **)&vsecattr->vsa_aclentp,
316*8329232eSGordon Ross 		    &vsecattr->vsa_aclcnt));
317*8329232eSGordon Ross 		vsecattr->vsa_aclentsz = vsecattr->vsa_aclcnt * sizeof (ace_t);
318*8329232eSGordon Ross 	}
319*8329232eSGordon Ross 
320*8329232eSGordon Ross 	return (error);
321*8329232eSGordon Ross }
322*8329232eSGordon Ross 
323*8329232eSGordon Ross /*
324*8329232eSGordon Ross  * Common code for implementing DOS share reservations
325*8329232eSGordon Ross  */
326*8329232eSGordon Ross /* ARGSUSED */
327*8329232eSGordon Ross int
fs_shrlock(struct vnode * vp,int cmd,struct shrlock * shr,int flag,cred_t * cr,caller_context_t * ct)328*8329232eSGordon Ross fs_shrlock(struct vnode *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr,
329*8329232eSGordon Ross     caller_context_t *ct)
330*8329232eSGordon Ross {
331*8329232eSGordon Ross 	return (ENOSYS);
332*8329232eSGordon Ross }
333*8329232eSGordon Ross 
334*8329232eSGordon Ross /*ARGSUSED1*/
335*8329232eSGordon Ross int
fs_vnevent_nosupport(vnode_t * vp,vnevent_t e,vnode_t * dvp,char * fnm,caller_context_t * ct)336*8329232eSGordon Ross fs_vnevent_nosupport(vnode_t *vp, vnevent_t e, vnode_t *dvp, char *fnm,
337*8329232eSGordon Ross     caller_context_t *ct)
338*8329232eSGordon Ross {
339*8329232eSGordon Ross 	ASSERT(vp != NULL);
340*8329232eSGordon Ross 	return (ENOTSUP);
341*8329232eSGordon Ross }
342*8329232eSGordon Ross 
343*8329232eSGordon Ross /*ARGSUSED1*/
344*8329232eSGordon Ross int
fs_vnevent_support(vnode_t * vp,vnevent_t e,vnode_t * dvp,char * fnm,caller_context_t * ct)345*8329232eSGordon Ross fs_vnevent_support(vnode_t *vp, vnevent_t e, vnode_t *dvp, char *fnm,
346*8329232eSGordon Ross     caller_context_t *ct)
347*8329232eSGordon Ross {
348*8329232eSGordon Ross 	ASSERT(vp != NULL);
349*8329232eSGordon Ross 	return (0);
350*8329232eSGordon Ross }
351*8329232eSGordon Ross 
352*8329232eSGordon Ross // fs_acl_nontrivial
353*8329232eSGordon Ross 
354*8329232eSGordon Ross /*
355*8329232eSGordon Ross  * Check whether we need a retry to recover from STALE error.
356*8329232eSGordon Ross  */
357*8329232eSGordon Ross int
fs_need_estale_retry(int retry_count)358*8329232eSGordon Ross fs_need_estale_retry(int retry_count)
359*8329232eSGordon Ross {
360*8329232eSGordon Ross 	if (retry_count < fs_estale_retry)
361*8329232eSGordon Ross 		return (1);
362*8329232eSGordon Ross 	else
363*8329232eSGordon Ross 		return (0);
364*8329232eSGordon Ross }
365*8329232eSGordon Ross 
366*8329232eSGordon Ross // fs_vscan...
367*8329232eSGordon Ross // reparse...
368*8329232eSGordon Ross 
369*8329232eSGordon Ross /*
370*8329232eSGordon Ross  * A few things from os/flock.c
371*8329232eSGordon Ross  */
372*8329232eSGordon Ross 
373*8329232eSGordon Ross /* ARGSUSED */
374*8329232eSGordon Ross void
cleanlocks(vnode_t * vp,pid_t pid,int sysid)375*8329232eSGordon Ross cleanlocks(vnode_t *vp, pid_t pid, int sysid)
376*8329232eSGordon Ross {
377*8329232eSGordon Ross }
378*8329232eSGordon Ross 
379*8329232eSGordon Ross /* ARGSUSED */
380*8329232eSGordon Ross void
cleanshares(struct vnode * vp,pid_t pid)381*8329232eSGordon Ross cleanshares(struct vnode *vp, pid_t pid)
382*8329232eSGordon Ross {
383*8329232eSGordon Ross }
384*8329232eSGordon Ross 
385*8329232eSGordon Ross /*
386*8329232eSGordon Ross  * convoff - converts the given data (start, whence) to the
387*8329232eSGordon Ross  * given whence.
388*8329232eSGordon Ross  */
389*8329232eSGordon Ross int
convoff(struct vnode * vp,struct flock64 * lckdat,int whence,offset_t offset)390*8329232eSGordon Ross convoff(struct vnode *vp, struct flock64 *lckdat, int whence, offset_t offset)
391*8329232eSGordon Ross {
392*8329232eSGordon Ross 	int		error;
393*8329232eSGordon Ross 	struct vattr	vattr;
394*8329232eSGordon Ross 
395*8329232eSGordon Ross 	if ((lckdat->l_whence == 2) || (whence == 2)) {
396*8329232eSGordon Ross 		vattr.va_mask = AT_SIZE;
397*8329232eSGordon Ross 		if (error = VOP_GETATTR(vp, &vattr, 0, CRED(), NULL))
398*8329232eSGordon Ross 			return (error);
399*8329232eSGordon Ross 	}
400*8329232eSGordon Ross 
401*8329232eSGordon Ross 	switch (lckdat->l_whence) {
402*8329232eSGordon Ross 	case 1:
403*8329232eSGordon Ross 		lckdat->l_start += offset;
404*8329232eSGordon Ross 		break;
405*8329232eSGordon Ross 	case 2:
406*8329232eSGordon Ross 		lckdat->l_start += vattr.va_size;
407*8329232eSGordon Ross 		/* FALLTHRU */
408*8329232eSGordon Ross 	case 0:
409*8329232eSGordon Ross 		break;
410*8329232eSGordon Ross 	default:
411*8329232eSGordon Ross 		return (EINVAL);
412*8329232eSGordon Ross 	}
413*8329232eSGordon Ross 
414*8329232eSGordon Ross 	if (lckdat->l_start < 0)
415*8329232eSGordon Ross 		return (EINVAL);
416*8329232eSGordon Ross 
417*8329232eSGordon Ross 	switch (whence) {
418*8329232eSGordon Ross 	case 1:
419*8329232eSGordon Ross 		lckdat->l_start -= offset;
420*8329232eSGordon Ross 		break;
421*8329232eSGordon Ross 	case 2:
422*8329232eSGordon Ross 		lckdat->l_start -= vattr.va_size;
423*8329232eSGordon Ross 		/* FALLTHRU */
424*8329232eSGordon Ross 	case 0:
425*8329232eSGordon Ross 		break;
426*8329232eSGordon Ross 	default:
427*8329232eSGordon Ross 		return (EINVAL);
428*8329232eSGordon Ross 	}
429*8329232eSGordon Ross 
430*8329232eSGordon Ross 	lckdat->l_whence = (short)whence;
431*8329232eSGordon Ross 	return (0);
432*8329232eSGordon Ross }
433