^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/lockd/svcshare.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Management of DOS shares.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sunrpc/svc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/lockd/lockd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/lockd/share.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) nlm_cmp_owner(struct nlm_share *share, struct xdr_netobj *oh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return share->s_owner.len == oh->len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) && !memcmp(share->s_owner.data, oh->data, oh->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct nlm_args *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct nlm_share *share;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct xdr_netobj *oh = &argp->lock.oh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u8 *ohdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (share = file->f_shares; share; share = share->s_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (share->s_host == host && nlm_cmp_owner(share, oh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if ((argp->fsm_access & share->s_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) || (argp->fsm_mode & share->s_access ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return nlm_lck_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) share = kmalloc(sizeof(*share) + oh->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (share == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return nlm_lck_denied_nolocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Copy owner handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ohdata = (u8 *) (share + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) memcpy(ohdata, oh->data, oh->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) share->s_file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) share->s_host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) share->s_owner.data = ohdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) share->s_owner.len = oh->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) share->s_next = file->f_shares;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) file->f_shares = share;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) share->s_access = argp->fsm_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) share->s_mode = argp->fsm_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Delete a share.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct nlm_args *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct nlm_share *share, **shpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct xdr_netobj *oh = &argp->lock.oh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) for (shpp = &file->f_shares; (share = *shpp) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) shpp = &share->s_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (share->s_host == host && nlm_cmp_owner(share, oh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *shpp = share->s_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) kfree(share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* X/Open spec says return success even if there was no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * corresponding share. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Traverse all shares for a given file, and delete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * those owned by the given (type of) host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) void nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) nlm_host_match_fn_t match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct nlm_share *share, **shpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) shpp = &file->f_shares;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) while ((share = *shpp) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (match(share->s_host, host)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *shpp = share->s_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kfree(share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) shpp = &share->s_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }