6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/sysmacros.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/fcntl.h>
31 #include <sys/vfs.h>
32 #include <sys/vnode.h>
33 #include <sys/share.h>
34 #include <sys/cmn_err.h>
35 #include <sys/kmem.h>
36 #include <sys/debug.h>
37 #include <sys/t_lock.h>
38 #include <sys/errno.h>
39 #include <sys/nbmlock.h>
40
41 int share_debug = 0;
42
43 #ifdef DEBUG
44 static void print_shares(struct vnode *);
45 static void print_share(struct shrlock *);
46 #endif
47
48 static int isreadonly(struct vnode *);
49
50 /*
51 * Add the share reservation shr to vp.
52 */
53 int
54 add_share(struct vnode *vp, struct shrlock *shr)
55 {
56 struct shrlocklist *shrl;
57
58 /*
59 * An access of zero is not legal, however some older clients
60 * generate it anyways. Allow the request only if it is
61 * coming from a remote system. Be generous in what you
62 * accept and strict in what you send.
63 */
64 if ((shr->s_access == 0) && (GETSYSID(shr->s_sysid) == 0)) {
65 return (EINVAL);
66 }
67
68 /*
69 * Sanity check to make sure we have valid options.
318 found++;
319 continue;
320 }
321 shrlp = &(*shrlp)->next;
322 }
323
324 if (is_nbmand)
325 cv_broadcast(&vp->v_cv);
326
327 mutex_exit(&vp->v_lock);
328 return (found ? 0 : EINVAL);
329 }
330
331 /*
332 * Clean up all local share reservations that the given process has with
333 * the given file.
334 */
335 void
336 cleanshares(struct vnode *vp, pid_t pid)
337 {
338 struct shrlock shr;
339
340 if (vp->v_shrlocks == NULL)
341 return;
342
343 shr.s_access = 0;
344 shr.s_deny = 0;
345 shr.s_pid = pid;
346 shr.s_sysid = 0;
347 shr.s_own_len = 0;
348 shr.s_owner = NULL;
349
350 (void) del_share(vp, &shr);
351 }
352
353 static int
354 is_match_for_has_remote(int32_t sysid1, int32_t sysid2)
355 {
356 int result = 0;
357
358 if (GETNLMID(sysid1) != 0) { /* in a cluster */
359 if (GETSYSID(sysid1) != 0) {
360 /*
361 * Lock obtained through nlm server. Just need to
362 * compare whole sysids.
363 */
364 result = (sysid1 == sysid2);
365 } else if (GETSYSID(sysid1) == 0) {
366 /*
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/fcntl.h>
35 #include <sys/vfs.h>
36 #include <sys/vnode.h>
37 #include <sys/share.h>
38 #include <sys/cmn_err.h>
39 #include <sys/kmem.h>
40 #include <sys/debug.h>
41 #include <sys/t_lock.h>
42 #include <sys/errno.h>
43 #include <sys/nbmlock.h>
44
45 int share_debug = 0;
46
47 #ifdef DEBUG
48 static void print_shares(struct vnode *);
49 static void print_share(struct shrlock *);
50 #endif
51
52 static int isreadonly(struct vnode *);
53 static void do_cleanshares(struct vnode *, pid_t, int32_t);
54
55
56 /*
57 * Add the share reservation shr to vp.
58 */
59 int
60 add_share(struct vnode *vp, struct shrlock *shr)
61 {
62 struct shrlocklist *shrl;
63
64 /*
65 * An access of zero is not legal, however some older clients
66 * generate it anyways. Allow the request only if it is
67 * coming from a remote system. Be generous in what you
68 * accept and strict in what you send.
69 */
70 if ((shr->s_access == 0) && (GETSYSID(shr->s_sysid) == 0)) {
71 return (EINVAL);
72 }
73
74 /*
75 * Sanity check to make sure we have valid options.
324 found++;
325 continue;
326 }
327 shrlp = &(*shrlp)->next;
328 }
329
330 if (is_nbmand)
331 cv_broadcast(&vp->v_cv);
332
333 mutex_exit(&vp->v_lock);
334 return (found ? 0 : EINVAL);
335 }
336
337 /*
338 * Clean up all local share reservations that the given process has with
339 * the given file.
340 */
341 void
342 cleanshares(struct vnode *vp, pid_t pid)
343 {
344 do_cleanshares(vp, pid, 0);
345 }
346
347 /*
348 * Cleanup all remote share reservations that
349 * were made by the given sysid on given vnode.
350 */
351 void
352 cleanshares_by_sysid(struct vnode *vp, int32_t sysid)
353 {
354 if (sysid == 0)
355 return;
356
357 do_cleanshares(vp, 0, sysid);
358 }
359
360 /*
361 * Cleanup share reservations on given vnode made
362 * by the either given pid or sysid.
363 * If sysid is 0, remove all shares made by given pid,
364 * otherwise all shares made by the given sysid will
365 * be removed.
366 */
367 static void
368 do_cleanshares(struct vnode *vp, pid_t pid, int32_t sysid)
369 {
370 struct shrlock shr;
371
372 if (vp->v_shrlocks == NULL)
373 return;
374
375 shr.s_access = 0;
376 shr.s_deny = 0;
377 shr.s_pid = pid;
378 shr.s_sysid = sysid;
379 shr.s_own_len = 0;
380 shr.s_owner = NULL;
381
382 (void) del_share(vp, &shr);
383 }
384
385 static int
386 is_match_for_has_remote(int32_t sysid1, int32_t sysid2)
387 {
388 int result = 0;
389
390 if (GETNLMID(sysid1) != 0) { /* in a cluster */
391 if (GETSYSID(sysid1) != 0) {
392 /*
393 * Lock obtained through nlm server. Just need to
394 * compare whole sysids.
395 */
396 result = (sysid1 == sysid2);
397 } else if (GETSYSID(sysid1) == 0) {
398 /*
|