0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/time.h>
0011 #include <linux/unistd.h>
0012 #include <linux/string.h>
0013 #include <linux/slab.h>
0014
0015 #include <linux/sunrpc/clnt.h>
0016 #include <linux/sunrpc/svc.h>
0017 #include <linux/lockd/lockd.h>
0018 #include <linux/lockd/share.h>
0019
0020 static inline int
0021 nlm_cmp_owner(struct nlm_share *share, struct xdr_netobj *oh)
0022 {
0023 return share->s_owner.len == oh->len
0024 && !memcmp(share->s_owner.data, oh->data, oh->len);
0025 }
0026
0027 __be32
0028 nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file,
0029 struct nlm_args *argp)
0030 {
0031 struct nlm_share *share;
0032 struct xdr_netobj *oh = &argp->lock.oh;
0033 u8 *ohdata;
0034
0035 for (share = file->f_shares; share; share = share->s_next) {
0036 if (share->s_host == host && nlm_cmp_owner(share, oh))
0037 goto update;
0038 if ((argp->fsm_access & share->s_mode)
0039 || (argp->fsm_mode & share->s_access ))
0040 return nlm_lck_denied;
0041 }
0042
0043 share = kmalloc(sizeof(*share) + oh->len,
0044 GFP_KERNEL);
0045 if (share == NULL)
0046 return nlm_lck_denied_nolocks;
0047
0048
0049 ohdata = (u8 *) (share + 1);
0050 memcpy(ohdata, oh->data, oh->len);
0051
0052 share->s_file = file;
0053 share->s_host = host;
0054 share->s_owner.data = ohdata;
0055 share->s_owner.len = oh->len;
0056 share->s_next = file->f_shares;
0057 file->f_shares = share;
0058
0059 update:
0060 share->s_access = argp->fsm_access;
0061 share->s_mode = argp->fsm_mode;
0062 return nlm_granted;
0063 }
0064
0065
0066
0067
0068 __be32
0069 nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file,
0070 struct nlm_args *argp)
0071 {
0072 struct nlm_share *share, **shpp;
0073 struct xdr_netobj *oh = &argp->lock.oh;
0074
0075 for (shpp = &file->f_shares; (share = *shpp) != NULL;
0076 shpp = &share->s_next) {
0077 if (share->s_host == host && nlm_cmp_owner(share, oh)) {
0078 *shpp = share->s_next;
0079 kfree(share);
0080 return nlm_granted;
0081 }
0082 }
0083
0084
0085
0086 return nlm_granted;
0087 }
0088
0089
0090
0091
0092
0093 void nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file,
0094 nlm_host_match_fn_t match)
0095 {
0096 struct nlm_share *share, **shpp;
0097
0098 shpp = &file->f_shares;
0099 while ((share = *shpp) != NULL) {
0100 if (match(share->s_host, host)) {
0101 *shpp = share->s_next;
0102 kfree(share);
0103 continue;
0104 }
0105 shpp = &share->s_next;
0106 }
0107 }