1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/lockd/svcshare.c
5 * Management of DOS shares.
7 * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
10 #include <linux/time.h>
11 #include <linux/unistd.h>
12 #include <linux/string.h>
13 #include <linux/slab.h>
15 #include <linux/sunrpc/clnt.h>
16 #include <linux/sunrpc/svc.h>
17 #include <linux/lockd/lockd.h>
18 #include <linux/lockd/share.h>
21 nlm_cmp_owner(struct nlm_share
*share
, struct xdr_netobj
*oh
)
23 return share
->s_owner
.len
== oh
->len
24 && !memcmp(share
->s_owner
.data
, oh
->data
, oh
->len
);
28 nlmsvc_share_file(struct nlm_host
*host
, struct nlm_file
*file
,
29 struct nlm_args
*argp
)
31 struct nlm_share
*share
;
32 struct xdr_netobj
*oh
= &argp
->lock
.oh
;
35 for (share
= file
->f_shares
; share
; share
= share
->s_next
) {
36 if (share
->s_host
== host
&& nlm_cmp_owner(share
, oh
))
38 if ((argp
->fsm_access
& share
->s_mode
)
39 || (argp
->fsm_mode
& share
->s_access
))
40 return nlm_lck_denied
;
43 share
= kmalloc(sizeof(*share
) + oh
->len
,
46 return nlm_lck_denied_nolocks
;
48 /* Copy owner handle */
49 ohdata
= (u8
*) (share
+ 1);
50 memcpy(ohdata
, oh
->data
, oh
->len
);
54 share
->s_owner
.data
= ohdata
;
55 share
->s_owner
.len
= oh
->len
;
56 share
->s_next
= file
->f_shares
;
57 file
->f_shares
= share
;
60 share
->s_access
= argp
->fsm_access
;
61 share
->s_mode
= argp
->fsm_mode
;
69 nlmsvc_unshare_file(struct nlm_host
*host
, struct nlm_file
*file
,
70 struct nlm_args
*argp
)
72 struct nlm_share
*share
, **shpp
;
73 struct xdr_netobj
*oh
= &argp
->lock
.oh
;
75 for (shpp
= &file
->f_shares
; (share
= *shpp
) != NULL
;
76 shpp
= &share
->s_next
) {
77 if (share
->s_host
== host
&& nlm_cmp_owner(share
, oh
)) {
78 *shpp
= share
->s_next
;
84 /* X/Open spec says return success even if there was no
85 * corresponding share. */
90 * Traverse all shares for a given file, and delete
91 * those owned by the given (type of) host
93 void nlmsvc_traverse_shares(struct nlm_host
*host
, struct nlm_file
*file
,
94 nlm_host_match_fn_t match
)
96 struct nlm_share
*share
, **shpp
;
98 shpp
= &file
->f_shares
;
99 while ((share
= *shpp
) != NULL
) {
100 if (match(share
->s_host
, host
)) {
101 *shpp
= share
->s_next
;
105 shpp
= &share
->s_next
;