2 * linux/fs/lockd/svcshare.c
4 * Management of DOS shares.
6 * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
9 #include <linux/time.h>
10 #include <linux/unistd.h>
11 #include <linux/string.h>
12 #include <linux/slab.h>
14 #include <linux/sunrpc/clnt.h>
15 #include <linux/sunrpc/svc.h>
16 #include <linux/lockd/lockd.h>
17 #include <linux/lockd/share.h>
20 nlm_cmp_owner(struct nlm_share
*share
, struct xdr_netobj
*oh
)
22 return share
->s_owner
.len
== oh
->len
23 && !memcmp(share
->s_owner
.data
, oh
->data
, oh
->len
);
27 nlmsvc_share_file(struct nlm_host
*host
, struct nlm_file
*file
,
28 struct nlm_args
*argp
)
30 struct nlm_share
*share
;
31 struct xdr_netobj
*oh
= &argp
->lock
.oh
;
34 for (share
= file
->f_shares
; share
; share
= share
->s_next
) {
35 if (share
->s_host
== host
&& nlm_cmp_owner(share
, oh
))
37 if ((argp
->fsm_access
& share
->s_mode
)
38 || (argp
->fsm_mode
& share
->s_access
))
39 return nlm_lck_denied
;
42 share
= kmalloc(sizeof(*share
) + oh
->len
,
45 return nlm_lck_denied_nolocks
;
47 /* Copy owner handle */
48 ohdata
= (u8
*) (share
+ 1);
49 memcpy(ohdata
, oh
->data
, oh
->len
);
53 share
->s_owner
.data
= ohdata
;
54 share
->s_owner
.len
= oh
->len
;
55 share
->s_next
= file
->f_shares
;
56 file
->f_shares
= share
;
59 share
->s_access
= argp
->fsm_access
;
60 share
->s_mode
= argp
->fsm_mode
;
68 nlmsvc_unshare_file(struct nlm_host
*host
, struct nlm_file
*file
,
69 struct nlm_args
*argp
)
71 struct nlm_share
*share
, **shpp
;
72 struct xdr_netobj
*oh
= &argp
->lock
.oh
;
74 for (shpp
= &file
->f_shares
; (share
= *shpp
) != NULL
;
75 shpp
= &share
->s_next
) {
76 if (share
->s_host
== host
&& nlm_cmp_owner(share
, oh
)) {
77 *shpp
= share
->s_next
;
83 /* X/Open spec says return success even if there was no
84 * corresponding share. */
89 * Traverse all shares for a given file, and delete
90 * those owned by the given (type of) host
92 void nlmsvc_traverse_shares(struct nlm_host
*host
, struct nlm_file
*file
,
93 nlm_host_match_fn_t match
)
95 struct nlm_share
*share
, **shpp
;
97 shpp
= &file
->f_shares
;
98 while ((share
= *shpp
) != NULL
) {
99 if (match(share
->s_host
, host
)) {
100 *shpp
= share
->s_next
;
104 shpp
= &share
->s_next
;