Page MenuHomeFreeBSD

D22933.id66008.diff
No OneTemporary

D22933.id66008.diff

Index: nfs/nfs_lock.c
===================================================================
--- nfs/nfs_lock.c
+++ nfs/nfs_lock.c
@@ -81,6 +81,7 @@
static struct cdev *nfslock_dev;
static struct mtx nfslock_mtx;
+static struct mtx nfsinfolock_mtx;
static int nfslock_isopen;
static TAILQ_HEAD(,__lock_msg) nfslock_list;
@@ -165,14 +166,13 @@
return (error);
}
+/* Consumes *lm2. */
static int
-nfslock_send(struct __lock_msg *lm)
+nfslock_send(struct __lock_msg *lm, struct __lock_msg *lm2)
{
- struct __lock_msg *lm2;
int error;
error = 0;
- lm2 = malloc(sizeof *lm2, M_NFSLOCK, M_WAITOK);
mtx_lock(&nfslock_mtx);
if (nfslock_isopen) {
memcpy(lm2, lm, sizeof *lm2);
@@ -205,6 +205,7 @@
if (bootverbose)
printf("nfslock: pseudo-device\n");
mtx_init(&nfslock_mtx, "nfslock", NULL, MTX_DEF);
+ mtx_init(&nfsinfolock_mtx, "nfsinfolock", NULL, MTX_DEF);
TAILQ_INIT(&nfslock_list);
nlminfo_release_p = nlminfo_release;
nfslock_dev = make_dev(&nfslock_cdevsw, 0,
@@ -244,6 +245,8 @@
struct proc *p;
struct nfsmount *nmp;
struct timeval boottime;
+ struct nlminfo *nlminf;
+ struct __lock_msg *lm2;
td = curthread;
p = td->td_proc;
@@ -279,13 +282,17 @@
msg.lm_version = LOCKD_MSG_VERSION;
msg.lm_msg_ident.pid = p->p_pid;
- mtx_lock(&Giant);
+ /* Malloc structures needed before acquiring the mutex. */
+ lm2 = malloc(sizeof *lm2, M_NFSLOCK, M_WAITOK);
+ nlminf = malloc(sizeof(struct nlminfo), M_NLMINFO, M_WAITOK | M_ZERO);
+
+ mtx_lock(&nfsinfolock_mtx);
/*
* if there is no nfsowner table yet, allocate one.
*/
if (p->p_nlminfo == NULL) {
- p->p_nlminfo = malloc(sizeof(struct nlminfo),
- M_NLMINFO, M_WAITOK | M_ZERO);
+ p->p_nlminfo = nlminf;
+ nlminf = NULL;
p->p_nlminfo->pid_start = p->p_stats->p_start;
getboottime(&boottime);
timevaladd(&p->p_nlminfo->pid_start, &boottime);
@@ -299,7 +306,7 @@
cru2x(td->td_ucred, &msg.lm_cred);
for (;;) {
- error = nfslock_send(&msg);
+ error = nfslock_send(&msg, lm2);
if (error)
goto out;
@@ -322,18 +329,23 @@
* permit aborting, the lock attempt would "get lost"
* and the lock would get stuck in the locked state.
*/
- error = tsleep(p->p_nlminfo, PUSER, "lockd", 20*hz);
+ error = msleep(p->p_nlminfo, &nfsinfolock_mtx, PUSER | PDROP,
+ "lockd", 20*hz);
if (error != 0) {
if (error == EWOULDBLOCK) {
/*
* We timed out, so we rewrite the request
* to the fifo.
*/
+ lm2 = malloc(sizeof *lm2, M_NFSLOCK, M_WAITOK);
+ mtx_lock(&nfsinfolock_mtx);
continue;
}
+ mtx_lock(&nfsinfolock_mtx);
break;
}
+ mtx_lock(&nfsinfolock_mtx);
if (msg.lm_getlk && p->p_nlminfo->retcode == 0) {
if (p->p_nlminfo->set_getlk_pid) {
@@ -347,7 +359,8 @@
break;
}
out:
- mtx_unlock(&Giant);
+ mtx_unlock(&nfsinfolock_mtx);
+ free(nlminf, M_NLMINFO); /* If not consumed above. */
return (error);
}
@@ -367,6 +380,7 @@
/* Find the process, set its return errno and wake it up. */
if ((targetp = pfind(ansp->la_msg_ident.pid)) == NULL)
return (ESRCH);
+ mtx_lock(&nfsinfolock_mtx);
/* verify the pid hasn't been reused (if we can), and it isn't waiting
* for an answer from a more recent request. We return an EPIPE if
@@ -378,6 +392,7 @@
(timevalcmp(&targetp->p_nlminfo->pid_start,
&ansp->la_msg_ident.pid_start, !=) ||
targetp->p_nlminfo->msg_seq != ansp->la_msg_ident.msg_seq))) {
+ mtx_unlock(&nfsinfolock_mtx);
PROC_UNLOCK(targetp);
return (EPIPE);
}
@@ -388,6 +403,7 @@
wakeup(targetp->p_nlminfo);
+ mtx_unlock(&nfsinfolock_mtx);
PROC_UNLOCK(targetp);
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 21, 2:45 AM (9 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27105476
Default Alt Text
D22933.id66008.diff (3 KB)

Event Timeline