/* * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ static int nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) || ntohs(saddr.sin_port) >= 1024) { printk(KERN_WARNING "lockd: rejected NSM callback from %08x:%d\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port)); return rpc_system_err; } /* Obtain the host pointer for this NFS server and try to * reclaim all locks we hold on this server. */ saddr.sin_addr.s_addr = argp->addr; if ((host = nlm_lookup_host(NULL, &saddr, IPPROTO_UDP, 1)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } /* If we run on an NFS server, delete all locks held by the client */ if (nlmsvc_ops != NULL) { struct svc_client *clnt; saddr.sin_addr.s_addr = argp->addr; if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); } nlm_release_host(host); } return rpc_success; }
/* * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ static int nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; int vers = argp->vers; int prot = argp->proto >> 1; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) || ntohs(saddr.sin_port) >= 1024) { printk(KERN_WARNING "lockd: rejected NSM callback from %08x:%d\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port)); return rpc_system_err; } /* Obtain the host pointer for this NFS server and try to * reclaim all locks we hold on this server. */ saddr.sin_addr.s_addr = argp->addr; if ((argp->proto & 1)==0) { if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } } else { /* If we run on an NFS server, delete all locks held by the client */ if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) { nlmsvc_free_host_resources(host); nlm_release_host(host); } } return rpc_success; }
/* * Find an NLM client handle in the cache. If there is none, create it. */ struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *rqstp) { return nlm_lookup_host(1, &rqstp->rq_addr, rqstp->rq_prot, rqstp->rq_vers); }
/* * Find an NLM server handle in the cache. If there is none, create it. */ struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version) { return nlm_lookup_host(0, sin, proto, version); }