static void test_lockd(void){ struct nlm_file file; struct sockaddr_in sin1, sin2; struct file_lock fl1, fl2; nlm_compare_locks(&fl1, &fl2); nlm_cmp_addr(&sin1,&sin2); nlmsvc_file_inode(&file); printk("finished lockd test\n"); }
/* * Find a block with a given NLM cookie. */ static inline struct nlm_block * nlmsvc_find_block(struct nlm_cookie *cookie, struct sockaddr_in *sin) { struct nlm_block *block; for (block = nlm_blocked; block; block = block->b_next) { dprintk("cookie: head of blocked queue %p, block %p\n", nlm_blocked, block); if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie) && nlm_cmp_addr(sin, &block->b_host->h_addr)) break; } return block; }
static int reclaimer(void *ptr) { struct nlm_host *host = (struct nlm_host *) ptr; struct nlm_wait *block; struct list_head *tmp; /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ lock_kernel(); lockd_up(); /* First, reclaim all locks that have been granted previously. */ restart: tmp = file_lock_list.next; while (tmp != &file_lock_list) { struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); struct inode *inode = fl->fl_file->f_dentry->d_inode; if (inode->i_sb->s_magic == NFS_SUPER_MAGIC && nlm_cmp_addr(NFS_ADDR(inode), &host->h_addr) && fl->fl_u.nfs_fl.state != host->h_state && (fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) { fl->fl_u.nfs_fl.flags &= ~ NFS_LCK_GRANTED; nlmclnt_reclaim(host, fl); /* This sleeps */ goto restart; } tmp = tmp->next; } host->h_reclaiming = 0; wake_up(&host->h_gracewait); /* Now, wake up all processes that sleep on a blocked lock */ for (block = nlm_blocked; block; block = block->b_next) { if (block->b_host == host) { block->b_status = NLM_LCK_DENIED_GRACE_PERIOD; wake_up(&block->b_wait); } } /* Release host handle after use */ nlm_release_host(host); lockd_down(); unlock_kernel(); return 0; }
/* * Common host lookup routine for server & client */ struct nlm_host * nlm_lookup_host(int server, struct sockaddr_in *sin, int proto, int version) { struct nlm_host *host, **hp; u32 addr; int hash; dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); hash = NLM_ADDRHASH(sin->sin_addr.s_addr); /* Lock hash table */ down(&nlm_host_sema); if (time_after_eq(jiffies, next_gc)) nlm_gc_hosts(); for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) { if (host->h_proto != proto) continue; if (host->h_version != version) continue; if (host->h_server != server) continue; if (nlm_cmp_addr(&host->h_addr, sin)) { if (hp != nlm_hosts + hash) { *hp = host->h_next; host->h_next = nlm_hosts[hash]; nlm_hosts[hash] = host; } nlm_get_host(host); up(&nlm_host_sema); return host; } } /* Ooops, no host found, create it */ dprintk("lockd: creating host entry\n"); if (!(host = (struct nlm_host *) kmalloc(sizeof(*host), GFP_KERNEL))) goto nohost; memset(host, 0, sizeof(*host)); addr = sin->sin_addr.s_addr; sprintf(host->h_name, "%u.%u.%u.%u", NIPQUAD(addr)); host->h_addr = *sin; host->h_addr.sin_port = 0; /* ouch! */ host->h_version = version; host->h_proto = proto; host->h_authflavor = RPC_AUTH_UNIX; host->h_rpcclnt = NULL; init_MUTEX(&host->h_sema); host->h_nextrebind = jiffies + NLM_HOST_REBIND; host->h_expires = jiffies + NLM_HOST_EXPIRE; atomic_set(&host->h_count, 1); init_waitqueue_head(&host->h_gracewait); host->h_state = 0; /* pseudo NSM state */ host->h_nsmstate = 0; /* real NSM state */ host->h_server = server; host->h_next = nlm_hosts[hash]; nlm_hosts[hash] = host; INIT_LIST_HEAD(&host->h_lockowners); spin_lock_init(&host->h_lock); if (++nrhosts > NLM_HOST_MAX) next_gc = 0; nohost: up(&nlm_host_sema); return host; }