xref: /illumos-gate/usr/src/lib/smbsrv/libfksmbsrv/common/fake_nblk.c (revision b819cea2f73f98c5662230cc9affc8cc84f77fcf)
1*b819cea2SGordon Ross /*
2*b819cea2SGordon Ross  * CDDL HEADER START
3*b819cea2SGordon Ross  *
4*b819cea2SGordon Ross  * The contents of this file are subject to the terms of the
5*b819cea2SGordon Ross  * Common Development and Distribution License (the "License").
6*b819cea2SGordon Ross  * You may not use this file except in compliance with the License.
7*b819cea2SGordon Ross  *
8*b819cea2SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*b819cea2SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10*b819cea2SGordon Ross  * See the License for the specific language governing permissions
11*b819cea2SGordon Ross  * and limitations under the License.
12*b819cea2SGordon Ross  *
13*b819cea2SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14*b819cea2SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*b819cea2SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16*b819cea2SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17*b819cea2SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18*b819cea2SGordon Ross  *
19*b819cea2SGordon Ross  * CDDL HEADER END
20*b819cea2SGordon Ross  */
21*b819cea2SGordon Ross /*
22*b819cea2SGordon Ross  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*b819cea2SGordon Ross  * Use is subject to license terms.
24*b819cea2SGordon Ross  *
25*b819cea2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
26*b819cea2SGordon Ross  */
27*b819cea2SGordon Ross 
28*b819cea2SGordon Ross /*
29*b819cea2SGordon Ross  * Utility routines and top-level conflict detection code for NBMAND
30*b819cea2SGordon Ross  * locks.
31*b819cea2SGordon Ross  */
32*b819cea2SGordon Ross 
33*b819cea2SGordon Ross #include <sys/types.h>
34*b819cea2SGordon Ross #include <sys/cmn_err.h>
35*b819cea2SGordon Ross #include <sys/debug.h>
36*b819cea2SGordon Ross #include <sys/fcntl.h>
37*b819cea2SGordon Ross #include <sys/rwlock.h>
38*b819cea2SGordon Ross #include <sys/vnode.h>
39*b819cea2SGordon Ross #include <sys/vfs.h>
40*b819cea2SGordon Ross #include <sys/nbmlock.h>
41*b819cea2SGordon Ross 
42*b819cea2SGordon Ross /*
43*b819cea2SGordon Ross  * Enter the critical region for synchronizing I/O requests with lock/share
44*b819cea2SGordon Ross  * requests.  "mode" specifies whether the caller intends to update
45*b819cea2SGordon Ross  * lock/share state (as opposed to just query it).
46*b819cea2SGordon Ross  */
47*b819cea2SGordon Ross 
48*b819cea2SGordon Ross void
49*b819cea2SGordon Ross nbl_start_crit(vnode_t *vp, krw_t mode)
50*b819cea2SGordon Ross {
51*b819cea2SGordon Ross 	rw_enter(&vp->v_nbllock, mode);
52*b819cea2SGordon Ross }
53*b819cea2SGordon Ross 
54*b819cea2SGordon Ross /*
55*b819cea2SGordon Ross  * Leave the critical region.
56*b819cea2SGordon Ross  */
57*b819cea2SGordon Ross 
58*b819cea2SGordon Ross void
59*b819cea2SGordon Ross nbl_end_crit(vnode_t *vp)
60*b819cea2SGordon Ross {
61*b819cea2SGordon Ross 	rw_exit(&vp->v_nbllock);
62*b819cea2SGordon Ross }
63*b819cea2SGordon Ross 
64*b819cea2SGordon Ross /*
65*b819cea2SGordon Ross  * Return non-zero if some thread is in the critical region.
66*b819cea2SGordon Ross  * Note that this is appropriate for use in ASSERT()s only.
67*b819cea2SGordon Ross  */
68*b819cea2SGordon Ross 
69*b819cea2SGordon Ross int
70*b819cea2SGordon Ross nbl_in_crit(vnode_t *vp)
71*b819cea2SGordon Ross {
72*b819cea2SGordon Ross 	return (RW_LOCK_HELD(&vp->v_nbllock));
73*b819cea2SGordon Ross }
74*b819cea2SGordon Ross 
75*b819cea2SGordon Ross /*
76*b819cea2SGordon Ross  * Returns non-zero if we need to look further for an NBMAND lock or
77*b819cea2SGordon Ross  * share conflict.
78*b819cea2SGordon Ross  */
79*b819cea2SGordon Ross /* ARGSUSED */
80*b819cea2SGordon Ross int
81*b819cea2SGordon Ross nbl_need_check(vnode_t *vp)
82*b819cea2SGordon Ross {
83*b819cea2SGordon Ross 	/*
84*b819cea2SGordon Ross 	 * Currently we only check if NBMAND locks/shares are allowed on
85*b819cea2SGordon Ross 	 * the filesystem.  An option for the future would be to have a
86*b819cea2SGordon Ross 	 * flag on the vnode, though the locking for that can get tricky.
87*b819cea2SGordon Ross 	 */
88*b819cea2SGordon Ross 	/* (vp->v_vfsp) && (vp->v_vfsp->vfs_flag & VFS_NBMAND)) */
89*b819cea2SGordon Ross 	return (0);
90*b819cea2SGordon Ross }
91*b819cea2SGordon Ross 
92*b819cea2SGordon Ross /*
93*b819cea2SGordon Ross  * Top-level conflict detection routine.  The arguments describe the
94*b819cea2SGordon Ross  * operation that is being attempted.  If the operation conflicts with an
95*b819cea2SGordon Ross  * existing lock or share reservation, a non-zero value is returned.  If
96*b819cea2SGordon Ross  * the operation is allowed, zero is returned.  Note that there is an
97*b819cea2SGordon Ross  * implicit argument, which is the process ID of the requester.
98*b819cea2SGordon Ross  *
99*b819cea2SGordon Ross  * svmand indicates that the file has System V mandatory locking enabled,
100*b819cea2SGordon Ross  * so we should look at all record locks, not just NBMAND record locks.
101*b819cea2SGordon Ross  * (This is to avoid a deadlock between a process making an I/O request and
102*b819cea2SGordon Ross  * a process trying to release a lock.  Instead of letting the first
103*b819cea2SGordon Ross  * process block in the filesystem code, we flag a conflict here.)
104*b819cea2SGordon Ross  */
105*b819cea2SGordon Ross 
106*b819cea2SGordon Ross int
107*b819cea2SGordon Ross nbl_conflict(vnode_t *vp,
108*b819cea2SGordon Ross 		nbl_op_t op,		/* attempted operation */
109*b819cea2SGordon Ross 		u_offset_t offset,	/* ignore if not I/O */
110*b819cea2SGordon Ross 		ssize_t length,		/* ignore if not I/O */
111*b819cea2SGordon Ross 		int svmand,		/* System V mandatory locking */
112*b819cea2SGordon Ross 		caller_context_t *ct)	/* caller context */
113*b819cea2SGordon Ross {
114*b819cea2SGordon Ross 	ASSERT(nbl_in_crit(vp));
115*b819cea2SGordon Ross 	ASSERT(op == NBL_READ || op == NBL_WRITE || op == NBL_RENAME ||
116*b819cea2SGordon Ross 	    op == NBL_REMOVE || op == NBL_READWRITE);
117*b819cea2SGordon Ross 
118*b819cea2SGordon Ross 	if (nbl_share_conflict(vp, op, ct)) {
119*b819cea2SGordon Ross 		return (1);
120*b819cea2SGordon Ross 	}
121*b819cea2SGordon Ross 
122*b819cea2SGordon Ross 	/*
123*b819cea2SGordon Ross 	 * If this is not an I/O request, there's no need to check against
124*b819cea2SGordon Ross 	 * the locks on the file.
125*b819cea2SGordon Ross 	 */
126*b819cea2SGordon Ross 	if (op == NBL_REMOVE || op == NBL_RENAME)
127*b819cea2SGordon Ross 		return (0);
128*b819cea2SGordon Ross 
129*b819cea2SGordon Ross 	return (nbl_lock_conflict(vp, op, offset, length, svmand, ct));
130*b819cea2SGordon Ross }
131*b819cea2SGordon Ross 
132*b819cea2SGordon Ross /*
133*b819cea2SGordon Ross  * Determine if the given file has mode bits for System V mandatory locks.
134*b819cea2SGordon Ross  * If there was an error, the errno value is returned.  Otherwise, zero is
135*b819cea2SGordon Ross  * returned and *svp is set appropriately (non-zero for mandatory locks,
136*b819cea2SGordon Ross  * zero for no mandatory locks).
137*b819cea2SGordon Ross  */
138*b819cea2SGordon Ross 
139*b819cea2SGordon Ross int
140*b819cea2SGordon Ross nbl_svmand(vnode_t *vp, cred_t *cr, int *svp)
141*b819cea2SGordon Ross {
142*b819cea2SGordon Ross 	struct vattr va;
143*b819cea2SGordon Ross 	int error;
144*b819cea2SGordon Ross 
145*b819cea2SGordon Ross 	va.va_mask = AT_MODE;
146*b819cea2SGordon Ross 	error = VOP_GETATTR(vp, &va, 0, cr, NULL);
147*b819cea2SGordon Ross 	if (error != 0)
148*b819cea2SGordon Ross 		return (error);
149*b819cea2SGordon Ross 
150*b819cea2SGordon Ross 	*svp = MANDLOCK(vp, va.va_mode);
151*b819cea2SGordon Ross 	return (0);
152*b819cea2SGordon Ross }
153*b819cea2SGordon Ross 
154*b819cea2SGordon Ross /*
155*b819cea2SGordon Ross  * The kernel handles this for us when we actually try I/O.
156*b819cea2SGordon Ross  */
157*b819cea2SGordon Ross /* ARGSUSED */
158*b819cea2SGordon Ross int
159*b819cea2SGordon Ross nbl_share_conflict(vnode_t *vp, nbl_op_t op, caller_context_t *ct)
160*b819cea2SGordon Ross {
161*b819cea2SGordon Ross 	return (0);
162*b819cea2SGordon Ross }
163*b819cea2SGordon Ross 
164*b819cea2SGordon Ross /*
165*b819cea2SGordon Ross  * The kernel handles this for us when we actually try I/O.
166*b819cea2SGordon Ross  */
167*b819cea2SGordon Ross /* ARGSUSED */
168*b819cea2SGordon Ross int
169*b819cea2SGordon Ross nbl_lock_conflict(vnode_t *vp, nbl_op_t op, u_offset_t offset,
170*b819cea2SGordon Ross 		ssize_t length, int svmand, caller_context_t *ct)
171*b819cea2SGordon Ross {
172*b819cea2SGordon Ross 	return (0);
173*b819cea2SGordon Ross }
174