diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/clntlock.c linux-2.2.18-lockd/fs/lockd/clntlock.c --- linux-2.2.18-mm/fs/lockd/clntlock.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/clntlock.c Sun Nov 19 21:52:54 2000 @@ -138,18 +138,15 @@ void nlmclnt_recovery(struct nlm_host *host, u32 newstate) { - if (!host->h_reclaiming++) { + if (host->h_reclaiming++) { if (host->h_nsmstate == newstate) return; printk(KERN_WARNING "lockd: Uh-oh! Interfering reclaims for host %s", host->h_name); - host->h_monitored = 0; host->h_nsmstate = newstate; host->h_state++; - nlm_release_host(host); } else { - host->h_monitored = 0; host->h_nsmstate = newstate; host->h_state++; nlm_get_host(host); @@ -168,7 +165,11 @@ /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ lock_kernel(); + daemonize(); + lockd_up(); + + exit_files(current); /* First, reclaim all locks that have been granted previously. */ do { diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/host.c linux-2.2.18-lockd/fs/lockd/host.c --- linux-2.2.18-mm/fs/lockd/host.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/host.c Sun Nov 19 21:52:54 2000 @@ -26,7 +26,6 @@ #define NLM_HOST_REBIND (60 * HZ) #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) -#define NLM_HOST_ADDR(sv) (&(sv)->s_nlmclnt->cl_xprt->addr) static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; static unsigned long next_gc = 0; @@ -37,24 +36,6 @@ static void nlm_gc_hosts(void); /* - * 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(NULL, sin, proto, version); -} - -/* - * 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(rqstp->rq_client, &rqstp->rq_addr, 0, 0); -} - -/* * Match the given host against client/address */ static inline int @@ -67,60 +48,33 @@ } /* - * Common host lookup routine for server & client + * Hash the host */ -struct nlm_host * -nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, - int proto, int version) +static inline int +nlm_hash_host(struct svc_client *clnt, struct sockaddr_in *sin) { - struct nlm_host *host, **hp; - u32 addr; - int hash; - - if (!clnt && !sin) { - printk(KERN_NOTICE "lockd: no clnt or addr in lookup_host!\n"); - return NULL; - } - - dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", - (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); - if (clnt) - hash = NLM_PTRHASH(clnt); - else - hash = NLM_ADDRHASH(sin->sin_addr.s_addr); + return NLM_PTRHASH(clnt); + return NLM_ADDRHASH(sin->sin_addr.s_addr); +} - /* Lock hash table */ - down(&nlm_host_sema); +static struct nlm_host * +nlm_create_host(struct svc_client *clnt, struct sockaddr_in *sin, + int proto, int version) +{ + struct nlm_host *host; + u32 addr; + int hash; if (time_after_eq(jiffies, next_gc)) nlm_gc_hosts(); - for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) { - if (host->h_version != version || host->h_proto != proto) - continue; - - if (nlm_match_host(host, clnt, 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; - } + if (!(host = (struct nlm_host *) kmalloc(sizeof(*host), GFP_KERNEL))) { + dprintk("lockd: attempt to create host entry failed.\n"); + return NULL; } - /* special hack for nlmsvc_invalidate_client */ - if (sin == NULL) - goto nohost; - - /* Ooops, no host found, create it */ - dprintk("lockd: creating host entry\n"); - - if (!(host = (struct nlm_host *) kmalloc(sizeof(*host), GFP_KERNEL))) - goto nohost; + dprintk("lockd: creating host entry.\n"); memset(host, 0, sizeof(*host)); addr = sin->sin_addr.s_addr; @@ -135,22 +89,103 @@ host->h_version = version; host->h_proto = proto; host->h_authflavor = RPC_AUTH_UNIX; - host->h_rpcclnt = NULL; host->h_sema = MUTEX; - host->h_nextrebind = jiffies + NLM_HOST_REBIND; host->h_expires = jiffies + NLM_HOST_EXPIRE; host->h_count = 1; - host->h_state = 0; /* pseudo NSM state */ - host->h_nsmstate = 0; /* real NSM state */ host->h_exportent = clnt; + hash = nlm_hash_host(clnt, sin); host->h_next = nlm_hosts[hash]; nlm_hosts[hash] = host; if (++nrhosts > NLM_HOST_MAX) - next_gc = 0; + next_gc = jiffies; + + return host; +} + +static struct nlm_host * +__nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, + int proto, int version) +{ + struct nlm_host *host, **hp; + int hash; + + if (!clnt && !sin) { + printk(KERN_NOTICE "lockd: no clnt or addr in lookup_host!\n"); + return NULL; + } + + dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", + (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); + + hash = nlm_hash_host(clnt, sin); + for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) { + if (proto && host->h_proto != proto) + continue; + if (version && host->h_version != version) + continue; + + if (nlm_match_host(host, clnt, sin)) { + if (hp != nlm_hosts + hash) { + *hp = host->h_next; + host->h_next = nlm_hosts[hash]; + nlm_hosts[hash] = host; + } + nlm_get_host(host); + break; + } + } + return host; +} + +/* + * Common host lookup routine for server & client + */ +struct nlm_host * +nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, + int proto, int version) +{ + struct nlm_host *host; -nohost: + /* Lock hash table */ + down(&nlm_host_sema); + host = __nlm_lookup_host(clnt, sin, proto, version); + up(&nlm_host_sema); + return host; +} + +/* + * 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 prot, int vers) +{ + struct nlm_host *host; + + /* Lock hash table */ + down(&nlm_host_sema); + if ((host = __nlm_lookup_host(NULL, sin, prot, vers)) == NULL) + host = nlm_create_host(NULL, sin, prot, vers); + up(&nlm_host_sema); + return host; +} + +/* + * Find an NLM client handle in the cache. If there is none, create it. + */ +struct nlm_host * +nlmsvc_lookup_host(struct svc_rqst *rqstp) +{ + struct nlm_host *host; + struct svc_client *clnt = rqstp->rq_client; + int prot = rqstp->rq_prot, + vers = rqstp->rq_vers; + + /* Lock hash table */ + down(&nlm_host_sema); + if ((host = __nlm_lookup_host(clnt, NULL, prot, vers)) == NULL) + host = nlm_create_host(clnt, &rqstp->rq_addr, prot, vers); up(&nlm_host_sema); return host; } @@ -206,6 +241,7 @@ clnt->cl_autobind = 1; /* turn on pmap queries */ xprt->nocong = 1; /* No congestion control for NLM */ + host->h_nextrebind = jiffies + NLM_HOST_REBIND; host->h_rpcclnt = clnt; } @@ -272,7 +308,7 @@ dprintk("lockd: nuking all hosts...\n"); for (i = 0; i < NLM_HOST_NRHASH; i++) { for (host = nlm_hosts[i]; host; host = host->h_next) - host->h_expires = 0; + host->h_expires = jiffies; } /* Then, perform a garbage collection pass */ @@ -326,15 +362,8 @@ *q = host->h_next; if (host->h_monitored) nsm_unmonitor(host); - if ((clnt = host->h_rpcclnt) != NULL) { - if (atomic_read(&clnt->cl_users)) { - printk(KERN_WARNING - "lockd: active RPC handle\n"); - clnt->cl_dead = 1; - } else { - rpc_destroy_client(host->h_rpcclnt); - } - } + if ((clnt = host->h_rpcclnt) != NULL) + rpc_shutdown_client(clnt); kfree(host); nrhosts--; } diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/mon.c linux-2.2.18-lockd/fs/lockd/mon.c --- linux-2.2.18-mm/fs/lockd/mon.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/mon.c Sun Nov 19 21:52:54 2000 @@ -47,7 +47,7 @@ args.addr = host->h_addr.sin_addr.s_addr; args.prog = NLM_PROGRAM; - args.vers = 1; + args.vers = host->h_version; args.proc = NLMPROC_NSM_NOTIFY; memset(res, 0, sizeof(*res)); @@ -76,8 +76,10 @@ if (status < 0 || res.status != 0) printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name); - else + else { host->h_monitored = 1; + host->h_nsmstate = res.state; + } return status; } diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svc.c linux-2.2.18-lockd/fs/lockd/svc.c --- linux-2.2.18-mm/fs/lockd/svc.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svc.c Sun Nov 19 21:52:54 2000 @@ -77,9 +77,7 @@ nlmsvc_pid = current->pid; up(&lockd_start); - exit_mm(current); - current->session = 1; - current->pgrp = 1; + daemonize(); sprintf(current->comm, "lockd"); /* Process request with signals blocked. */ @@ -105,12 +103,8 @@ #ifdef RPC_DEBUG nlmsvc_grace_period = 10 * HZ; #else - if (nlm_grace_period) { - nlmsvc_grace_period += (1 + nlm_grace_period / nlm_timeout) - * nlm_timeout * HZ; - } else { - nlmsvc_grace_period += 5 * nlm_timeout * HZ; - } + nlmsvc_grace_period = (1 + nlm_grace_period / nlm_timeout) + * nlm_timeout * HZ; #endif grace_period_expire = nlmsvc_grace_period + jiffies; @@ -138,8 +132,11 @@ */ if (!nlmsvc_grace_period) { timeout = nlmsvc_retry_blocked(); - } else if (time_before(nlmsvc_grace_period, jiffies)) + } else if (time_before(grace_period_expire, jiffies)) { nlmsvc_grace_period = 0; + continue; + } else + timeout = nlmsvc_timeout; /* * Find a socket with data available and call its @@ -349,7 +346,7 @@ * Define NLM program and procedures */ static struct svc_version nlmsvc_version1 = { - 1, 16, nlmsvc_procedures, NULL + 1, 17, nlmsvc_procedures, NULL }; static struct svc_version nlmsvc_version3 = { 3, 24, nlmsvc_procedures, NULL diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svc4proc.c linux-2.2.18-lockd/fs/lockd/svc4proc.c --- linux-2.2.18-mm/fs/lockd/svc4proc.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svc4proc.c Sun Nov 19 21:52:54 2000 @@ -422,6 +422,8 @@ void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; + int vers = rqstp->rq_vers; + int prot = rqstp->rq_prot; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); @@ -438,7 +440,7 @@ * 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) { + if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } @@ -448,7 +450,7 @@ 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) { + && (host = nlm_lookup_host(clnt, NULL, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); nlm_release_host(host); } @@ -551,7 +553,8 @@ PROC(cancel_res, cancelres, norep, res, void), PROC(unlock_res, unlockres, norep, res, void), PROC(granted_res, grantedres, norep, res, void), - PROC(none, void, void, void, void), + /* statd callback */ + PROC(sm_notify, reboot, void, reboot, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), @@ -560,6 +563,4 @@ PROC(nm_lock, lockargs, res, args, res), PROC(free_all, notify, void, args, void), - /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), }; diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svclock.c linux-2.2.18-lockd/fs/lockd/svclock.c --- linux-2.2.18-mm/fs/lockd/svclock.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svclock.c Sun Nov 19 21:52:54 2000 @@ -53,9 +53,15 @@ dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); if (block->b_queued) nlmsvc_remove_block(block); - for (bp = &nlm_blocked; (b = *bp); bp = &b->b_next) - if (when < b->b_when) - break; + bp = &nlm_blocked; + if (when != NLM_NEVER) { + if ((when += jiffies) == NLM_NEVER) + when ++; + while ((b = *bp) && time_before_eq(b->b_when,when)) + bp = &b->b_next; + } else + while ((b = *bp)) + bp = &b->b_next; block->b_queued = 1; block->b_when = when; @@ -159,8 +165,7 @@ struct nlm_rqst *call; /* Create host handle for callback */ - host = nlmclnt_lookup_host(&rqstp->rq_addr, - rqstp->rq_prot, rqstp->rq_vers); + host = nlmsvc_lookup_host(rqstp); if (host == NULL) return NULL; @@ -169,10 +174,11 @@ goto failed; memset(block, 0, sizeof(*block)); - /* Set notifier function for VFS, and init args */ - lock->fl.fl_notify = nlmsvc_notify_blocked; if (!nlmclnt_setgrantargs(&block->b_call, lock)) goto failed_free; + + /* Set notifier function for VFS, and init args */ + block->b_call.a_args.lock.fl.fl_notify = nlmsvc_notify_blocked; block->b_call.a_args.cookie = *cookie; /* see above */ dprintk("lockd: created block %p...\n", block); @@ -263,12 +269,12 @@ down(&file->f_sema); for (block = file->f_blocks; block; block = next) { next = block->b_fnext; + if (host && block->b_host != host) + continue; if (action == NLM_ACT_MARK) block->b_host->h_inuse = 1; - else if (action == NLM_ACT_UNLOCK) { - if (host == NULL || host == block->b_host) - nlmsvc_delete_block(block, 1); - } + else if (action == NLM_ACT_UNLOCK) + nlmsvc_delete_block(block, 1); } up(&file->f_sema); return 0; @@ -455,8 +461,8 @@ posix_unblock_lock(fl); for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) { if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { - svc_wake_up(block->b_daemon); nlmsvc_insert_block(block, 0); + svc_wake_up(block->b_daemon); return; } } @@ -516,7 +522,7 @@ if ((error = posix_lock_file(&file->f_file, &lock->fl, 0)) < 0) { printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", -error, __FUNCTION__); - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); up(&file->f_sema); return; } @@ -528,7 +534,7 @@ block->b_incall = 1; /* Schedule next grant callback in 30 seconds */ - nlmsvc_insert_block(block, jiffies + 30 * HZ); + nlmsvc_insert_block(block, 30 * HZ); /* Call the client */ nlm_get_host(block->b_call.a_host); @@ -566,13 +572,13 @@ * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ - timeout = jiffies + 10 * HZ; + timeout = 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ - timeout = jiffies + 60 * HZ; + timeout = 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); @@ -600,7 +606,7 @@ if ((block = nlmsvc_find_block(cookie)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. @@ -631,7 +637,11 @@ dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", nlm_blocked, nlm_blocked? nlm_blocked->b_when : 0); - while ((block = nlm_blocked) && block->b_when <= jiffies) { + while ((block = nlm_blocked)) { + if (block->b_when == NLM_NEVER) + break; + if (time_after(block->b_when,jiffies)) + break; dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", block, block->b_when, block->b_done); if (block->b_done) diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svcproc.c linux-2.2.18-lockd/fs/lockd/svcproc.c --- linux-2.2.18-mm/fs/lockd/svcproc.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svcproc.c Sun Nov 19 21:52:54 2000 @@ -435,6 +435,8 @@ void *resp) { struct sockaddr_in saddr = rqstp->rq_addr; + int vers = rqstp->rq_vers; + int prot = rqstp->rq_prot; struct nlm_host *host; dprintk("lockd: SM_NOTIFY called\n"); @@ -450,8 +452,8 @@ /* 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) { + saddr.sin_addr.s_addr = htonl(argp->addr); + if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { nlmclnt_recovery(host, argp->state); nlm_release_host(host); } @@ -461,7 +463,7 @@ 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) { + && (host = nlm_lookup_host(clnt, NULL, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); nlm_release_host(host); } @@ -585,7 +587,8 @@ PROC(cancel_res, cancelres, norep, res, void), PROC(unlock_res, unlockres, norep, res, void), PROC(granted_res, grantedres, norep, res, void), - PROC(none, void, void, void, void), + /* statd callback */ + PROC(sm_notify, reboot, void, reboot, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), PROC(none, void, void, void, void), @@ -594,6 +597,4 @@ PROC(nm_lock, lockargs, res, args, res), PROC(free_all, notify, void, args, void), - /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), }; diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svcshare.c linux-2.2.18-lockd/fs/lockd/svcshare.c --- linux-2.2.18-mm/fs/lockd/svcshare.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svcshare.c Sun Nov 19 21:52:54 2000 @@ -95,14 +95,16 @@ shpp = &file->f_shares; while ((share = *shpp) != NULL) { + if (host && host != share->s_host) { + shpp = &share->s_next; + continue; + } if (action == NLM_ACT_MARK) share->s_host->h_inuse = 1; else if (action == NLM_ACT_UNLOCK) { - if (host == NULL || host == share->s_host) { - *shpp = share->s_next; - kfree(share); - continue; - } + *shpp = share->s_next; + kfree(share); + continue; } shpp = &share->s_next; } diff -u --recursive --new-file linux-2.2.18-mm/fs/lockd/svcsubs.c linux-2.2.18-lockd/fs/lockd/svcsubs.c --- linux-2.2.18-mm/fs/lockd/svcsubs.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/lockd/svcsubs.c Sun Nov 19 21:52:54 2000 @@ -147,6 +147,7 @@ struct inode *inode = nlmsvc_file_inode(file); struct file_lock *fl; struct nlm_host *lockhost; + int status = 0; again: file->f_locks = 0; @@ -157,29 +158,27 @@ /* update current lock count */ file->f_locks++; lockhost = (struct nlm_host *) fl->fl_owner; + if (host && lockhost != host) + continue; if (action == NLM_ACT_MARK) lockhost->h_inuse = 1; else if (action == NLM_ACT_CHECK) - return 1; + status = 1; else if (action == NLM_ACT_UNLOCK) { - struct file_lock lock = *fl; - - if (host && lockhost != host) - continue; + struct file_lock lock; + lock = *fl; lock.fl_type = F_UNLCK; - lock.fl_start = 0; - lock.fl_end = NLM_OFFSET_MAX; if (posix_lock_file(&file->f_file, &lock, 0) < 0) { printk("lockd: unlock failure in %s:%d\n", __FILE__, __LINE__); - return 1; - } - goto again; + status = 1; + } else + goto again; } } - return 0; + return status; } /* @@ -208,6 +207,7 @@ { struct nlm_file *file, **fp; int i; + int res = 0; down(&nlm_file_sema); for (i = 0; i < FILE_NRHASH; i++) { @@ -215,24 +215,21 @@ while ((file = *fp) != NULL) { /* Traverse locks, blocks and shares of this file * and update file->f_locks count */ - if (nlm_inspect_file(host, file, action)) { - up(&nlm_file_sema); - return 1; - } + if (nlm_inspect_file(host, file, action)) + res = 1; - /* No more references to this file. Let go of it. */ - if (!file->f_blocks && !file->f_locks - && !file->f_shares && !file->f_count) { - *fp = file->f_next; - nlmsvc_ops->fclose(&file->f_file); - kfree(file); - } else { + if (file->f_blocks || file->f_locks + || file->f_shares || file->f_count) { fp = &file->f_next; + continue; } + *fp = file->f_next; + nlmsvc_ops->fclose(&file->f_file); + kfree(file); } } up(&nlm_file_sema); - return 0; + return res; } /* @@ -298,7 +295,7 @@ if ((host = nlm_lookup_host(clnt, NULL, 0, 0)) != NULL) { dprintk("lockd: invalidating client for %s\n", host->h_name); nlmsvc_free_host_resources(host); - host->h_expires = 0; + host->h_expires = jiffies; nlm_release_host(host); } } diff -u --recursive --new-file linux-2.2.18-mm/fs/locks.c linux-2.2.18-lockd/fs/locks.c --- linux-2.2.18-mm/fs/locks.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/locks.c Sun Nov 19 21:52:54 2000 @@ -258,6 +258,15 @@ return; } +static inline void +locks_notify_blocked(struct file_lock *waiter) +{ + if (waiter->fl_notify) + waiter->fl_notify(waiter); + else + wake_up(&waiter->fl_wait); +} + /* Wake up processes blocked waiting for blocker. * If told to wait then schedule the processes until the block list * is empty, otherwise empty the block list ourselves. @@ -268,23 +277,21 @@ while ((waiter = blocker->fl_nextblock) != NULL) { /* N.B. Is it possible for the notify function to block?? */ - if (waiter->fl_notify) - waiter->fl_notify(waiter); - wake_up(&waiter->fl_wait); - if (wait) { + if (!wait) { + /* Remove waiter from the block list, because by the + * time it wakes up blocker won't exist any more. + */ + locks_delete_block(blocker, waiter); + locks_notify_blocked(waiter); + } else { + locks_notify_blocked(waiter); /* Let the blocked process remove waiter from the * block list when it gets scheduled. */ current->policy |= SCHED_YIELD; schedule(); - } else { - /* Remove waiter from the block list, because by the - * time it wakes up blocker won't exist any more. - */ - locks_delete_block(blocker, waiter); } } - return; } /* flock() system call entry point. Apply a FL_FLOCK style lock to diff -u --recursive --new-file linux-2.2.18-mm/fs/nfs/file.c linux-2.2.18-lockd/fs/nfs/file.c --- linux-2.2.18-mm/fs/nfs/file.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/nfs/file.c Sun Nov 19 21:52:54 2000 @@ -265,7 +265,9 @@ * Flush all pending writes before doing anything * with locks.. */ + down(&inode->i_sem); status = nfs_wb_all(inode); + up(&inode->i_sem); if (status < 0) goto out_unlock; @@ -280,8 +282,10 @@ out_unlock: out_ok: if ((cmd == F_SETLK || cmd == F_SETLKW) && fl->fl_type != F_UNLCK) { + down(&inode->i_sem); nfs_wb_all(inode); /* we may have slept */ nfs_zap_caches(inode); + up(&inode->i_sem); } return status; } diff -u --recursive --new-file linux-2.2.18-mm/fs/nfsd/nfssvc.c linux-2.2.18-lockd/fs/nfsd/nfssvc.c --- linux-2.2.18-mm/fs/nfsd/nfssvc.c Sun Nov 19 21:42:39 2000 +++ linux-2.2.18-lockd/fs/nfsd/nfssvc.c Sun Nov 19 22:17:27 2000 @@ -110,10 +110,8 @@ /* Set up kernel thread */ lock_kernel(); - exit_mm(current); sprintf(current->comm, "nfsd"); - current->session = 1; - current->pgrp = 1; + daemonize(); current->fs->umask = 0; /* Count active threads */ @@ -121,6 +119,8 @@ /* Start lockd */ lockd_up(); + + exit_files(current); /* Let svc_process check client's authentication. */ rqstp->rq_auth = 1; diff -u --recursive --new-file linux-2.2.18-mm/include/linux/lockd/nlm.h linux-2.2.18-lockd/include/linux/lockd/nlm.h --- linux-2.2.18-mm/include/linux/lockd/nlm.h Sun Nov 19 21:42:48 2000 +++ linux-2.2.18-lockd/include/linux/lockd/nlm.h Sun Nov 19 21:52:54 2000 @@ -45,10 +45,10 @@ #define NLMPROC_CANCEL_RES 13 #define NLMPROC_UNLOCK_RES 14 #define NLMPROC_GRANTED_RES 15 +#define NLMPROC_NSM_NOTIFY 16 /* statd callback */ #define NLMPROC_SHARE 20 #define NLMPROC_UNSHARE 21 #define NLMPROC_NM_LOCK 22 #define NLMPROC_FREE_ALL 23 -#define NLMPROC_NSM_NOTIFY 24 /* statd callback */ #endif /* LINUX_LOCKD_NLM_H */ diff -u --recursive --new-file linux-2.2.18-mm/net/sunrpc/sched.c linux-2.2.18-lockd/net/sunrpc/sched.c --- linux-2.2.18-mm/net/sunrpc/sched.c Sun Nov 19 21:51:28 2000 +++ linux-2.2.18-lockd/net/sunrpc/sched.c Sun Nov 19 21:52:54 2000 @@ -1067,15 +1067,13 @@ up(&rpciod_running); exit_files(current); - exit_mm(current); + daemonize(); spin_lock_irq(¤t->sigmask_lock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - current->session = 1; - current->pgrp = 1; sprintf(current->comm, "rpciod"); dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid); diff -u --recursive --new-file linux-2.2.18-mm/net/sunrpc/svcsock.c linux-2.2.18-lockd/net/sunrpc/svcsock.c --- linux-2.2.18-mm/net/sunrpc/svcsock.c Sun Nov 19 21:51:28 2000 +++ linux-2.2.18-lockd/net/sunrpc/svcsock.c Sun Nov 19 21:52:54 2000 @@ -771,7 +771,6 @@ "svc_recv: service %p, wait queue active!\n", rqstp); -again: /* Initialize the buffers */ rqstp->rq_argbuf = rqstp->rq_defbuf; rqstp->rq_resbuf = rqstp->rq_defbuf; @@ -816,7 +815,7 @@ /* No data, incomplete (TCP) read, or accept() */ if (len == 0 || len == -EAGAIN) { svc_sock_release(rqstp); - goto again; + return -EAGAIN; } rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024;