diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/sysv_msg.c | 260 | ||||
-rw-r--r-- | sys/kern/sysv_sem.c | 257 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 176 | ||||
-rw-r--r-- | sys/sys/msg.h | 9 |
4 files changed, 353 insertions, 349 deletions
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index f16b636..ddc593b 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -57,16 +57,6 @@ static sy_call_t *msgcalls[] = { (sy_call_t *)msgsnd, (sy_call_t *)msgrcv }; -struct msg { - struct msg *msg_next; /* next msg in the chain */ - long msg_type; /* type of this message */ - /* >0 -> type of this message */ - /* 0 -> free header */ - u_short msg_ts; /* size of this message */ - short msg_spot; /* location of start of msg in buffer */ -}; - - #ifndef MSGSSZ #define MSGSSZ 8 /* Each segment must be 2^N long */ #endif @@ -130,7 +120,7 @@ static struct msg *free_msghdrs;/* list of free msg headers */ static char *msgpool; /* MSGMAX byte long msg buffer pool */ static struct msgmap *msgmaps; /* MSGSEG msgmap structures */ static struct msg *msghdrs; /* MSGTQL msg headers */ -static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ +static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */ static struct mtx msq_mtx; /* global mutex for message queues. */ static void @@ -152,7 +142,8 @@ msginit() msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK); if (msghdrs == NULL) panic("msghdrs is NULL"); - msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK); + msqids = malloc(sizeof(struct msqid_kernel) * msginfo.msgmni, M_MSG, + M_WAITOK); if (msqids == NULL) panic("msqids is NULL"); @@ -202,9 +193,9 @@ msginit() panic("msqids is NULL"); for (i = 0; i < msginfo.msgmni; i++) { - msqids[i].msg_qbytes = 0; /* implies entry is available */ - msqids[i].msg_perm.seq = 0; /* reset to a known value */ - msqids[i].msg_perm.mode = 0; + msqids[i].u.msg_qbytes = 0; /* implies entry is available */ + msqids[i].u.msg_perm.seq = 0; /* reset to a known value */ + msqids[i].u.msg_perm.mode = 0; } mtx_init(&msq_mtx, "msq", NULL, MTX_DEF); } @@ -212,7 +203,7 @@ msginit() static int msgunload() { - struct msqid_ds *msqptr; + struct msqid_kernel *msqkptr; int msqid; for (msqid = 0; msqid < msginfo.msgmni; msqid++) { @@ -222,9 +213,9 @@ msgunload() * they are copying the message in/out. We can't * re-use the entry until they release it. */ - msqptr = &msqids[msqid]; - if (msqptr->msg_qbytes != 0 || - (msqptr->msg_perm.mode & MSG_LOCKED) != 0) + msqkptr = &msqids[msqid]; + if (msqkptr->u.msg_qbytes != 0 || + (msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) break; } if (msqid != msginfo.msgmni) @@ -350,7 +341,7 @@ msgctl(td, uap) struct msqid_ds *user_msqptr = uap->buf; int rval, error; struct msqid_ds msqbuf; - register struct msqid_ds *msqptr; + register struct msqid_kernel *msqkptr; DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr)); if (!jail_sysvipc_allowed && jailed(td->td_ucred)) @@ -367,15 +358,15 @@ msgctl(td, uap) (error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) return (error); - msqptr = &msqids[msqid]; + msqkptr = &msqids[msqid]; mtx_lock(&msq_mtx); - if (msqptr->msg_qbytes == 0) { + if (msqkptr->u.msg_qbytes == 0) { DPRINTF(("no such msqid\n")); error = EINVAL; goto done2; } - if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { + if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { DPRINTF(("wrong sequence number\n")); error = EINVAL; goto done2; @@ -389,37 +380,38 @@ msgctl(td, uap) case IPC_RMID: { struct msg *msghdr; - if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M))) + if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M))) goto done2; + /* Free the message headers */ - msghdr = msqptr->msg_first; + msghdr = msqkptr->u.msg_first; while (msghdr != NULL) { struct msg *msghdr_tmp; /* Free the segments of each message */ - msqptr->msg_cbytes -= msghdr->msg_ts; - msqptr->msg_qnum--; + msqkptr->u.msg_cbytes -= msghdr->msg_ts; + msqkptr->u.msg_qnum--; msghdr_tmp = msghdr; msghdr = msghdr->msg_next; msg_freehdr(msghdr_tmp); } - if (msqptr->msg_cbytes != 0) + if (msqkptr->u.msg_cbytes != 0) panic("msg_cbytes is screwed up"); - if (msqptr->msg_qnum != 0) + if (msqkptr->u.msg_qnum != 0) panic("msg_qnum is screwed up"); - msqptr->msg_qbytes = 0; /* Mark it as free */ + msqkptr->u.msg_qbytes = 0; /* Mark it as free */ - wakeup(msqptr); + wakeup(msqkptr); } break; case IPC_SET: - if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M))) + if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M))) goto done2; - if (msqbuf.msg_qbytes > msqptr->msg_qbytes) { + if (msqbuf.msg_qbytes > msqkptr->u.msg_qbytes) { error = suser(td); if (error) goto done2; @@ -434,16 +426,16 @@ msgctl(td, uap) error = EINVAL; /* non-standard errno! */ goto done2; } - msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ - msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ - msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | + msqkptr->u.msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ + msqkptr->u.msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ + msqkptr->u.msg_perm.mode = (msqkptr->u.msg_perm.mode & ~0777) | (msqbuf.msg_perm.mode & 0777); - msqptr->msg_qbytes = msqbuf.msg_qbytes; - msqptr->msg_ctime = time_second; + msqkptr->u.msg_qbytes = msqbuf.msg_qbytes; + msqkptr->u.msg_ctime = time_second; break; case IPC_STAT: - if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { + if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) { DPRINTF(("requester doesn't have read access\n")); goto done2; } @@ -460,7 +452,7 @@ msgctl(td, uap) done2: mtx_unlock(&msq_mtx); if (cmd == IPC_STAT && error == 0) - error = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds)); + error = copyout(&(msqkptr->u), user_msqptr, sizeof(struct msqid_ds)); return(error); } @@ -483,7 +475,7 @@ msgget(td, uap) int key = uap->key; int msgflg = uap->msgflg; struct ucred *cred = td->td_ucred; - register struct msqid_ds *msqptr = NULL; + register struct msqid_kernel *msqkptr = NULL; DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg)); @@ -493,9 +485,9 @@ msgget(td, uap) mtx_lock(&msq_mtx); if (key != IPC_PRIVATE) { for (msqid = 0; msqid < msginfo.msgmni; msqid++) { - msqptr = &msqids[msqid]; - if (msqptr->msg_qbytes != 0 && - msqptr->msg_perm.key == key) + msqkptr = &msqids[msqid]; + if (msqkptr->u.msg_qbytes != 0 && + msqkptr->u.msg_perm.key == key) break; } if (msqid < msginfo.msgmni) { @@ -505,7 +497,8 @@ msgget(td, uap) error = EEXIST; goto done2; } - if ((error = ipcperm(td, &msqptr->msg_perm, msgflg & 0700))) { + if ((error = ipcperm(td, &msqkptr->u.msg_perm, + msgflg & 0700))) { DPRINTF(("requester doesn't have 0%o access\n", msgflg & 0700)); goto done2; @@ -523,9 +516,9 @@ msgget(td, uap) * they are copying the message in/out. We can't * re-use the entry until they release it. */ - msqptr = &msqids[msqid]; - if (msqptr->msg_qbytes == 0 && - (msqptr->msg_perm.mode & MSG_LOCKED) == 0) + msqkptr = &msqids[msqid]; + if (msqkptr->u.msg_qbytes == 0 && + (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0) break; } if (msqid == msginfo.msgmni) { @@ -534,24 +527,24 @@ msgget(td, uap) goto done2; } DPRINTF(("msqid %d is available\n", msqid)); - msqptr->msg_perm.key = key; - msqptr->msg_perm.cuid = cred->cr_uid; - msqptr->msg_perm.uid = cred->cr_uid; - msqptr->msg_perm.cgid = cred->cr_gid; - msqptr->msg_perm.gid = cred->cr_gid; - msqptr->msg_perm.mode = (msgflg & 0777); + msqkptr->u.msg_perm.key = key; + msqkptr->u.msg_perm.cuid = cred->cr_uid; + msqkptr->u.msg_perm.uid = cred->cr_uid; + msqkptr->u.msg_perm.cgid = cred->cr_gid; + msqkptr->u.msg_perm.gid = cred->cr_gid; + msqkptr->u.msg_perm.mode = (msgflg & 0777); /* Make sure that the returned msqid is unique */ - msqptr->msg_perm.seq = (msqptr->msg_perm.seq + 1) & 0x7fff; - msqptr->msg_first = NULL; - msqptr->msg_last = NULL; - msqptr->msg_cbytes = 0; - msqptr->msg_qnum = 0; - msqptr->msg_qbytes = msginfo.msgmnb; - msqptr->msg_lspid = 0; - msqptr->msg_lrpid = 0; - msqptr->msg_stime = 0; - msqptr->msg_rtime = 0; - msqptr->msg_ctime = time_second; + msqkptr->u.msg_perm.seq = (msqkptr->u.msg_perm.seq + 1) & 0x7fff; + msqkptr->u.msg_first = NULL; + msqkptr->u.msg_last = NULL; + msqkptr->u.msg_cbytes = 0; + msqkptr->u.msg_qnum = 0; + msqkptr->u.msg_qbytes = msginfo.msgmnb; + msqkptr->u.msg_lspid = 0; + msqkptr->u.msg_lrpid = 0; + msqkptr->u.msg_stime = 0; + msqkptr->u.msg_rtime = 0; + msqkptr->u.msg_ctime = time_second; } else { DPRINTF(("didn't find it and wasn't asked to create it\n")); error = ENOENT; @@ -560,7 +553,7 @@ msgget(td, uap) found: /* Construct the unique msqid */ - td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); + td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqkptr->u.msg_perm); done2: mtx_unlock(&msq_mtx); return (error); @@ -588,7 +581,7 @@ msgsnd(td, uap) size_t msgsz = uap->msgsz; int msgflg = uap->msgflg; int segs_needed, error = 0; - register struct msqid_ds *msqptr; + register struct msqid_kernel *msqkptr; register struct msg *msghdr; short next; @@ -607,19 +600,19 @@ msgsnd(td, uap) goto done2; } - msqptr = &msqids[msqid]; - if (msqptr->msg_qbytes == 0) { + msqkptr = &msqids[msqid]; + if (msqkptr->u.msg_qbytes == 0) { DPRINTF(("no such message queue id\n")); error = EINVAL; goto done2; } - if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { + if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { DPRINTF(("wrong sequence number\n")); error = EINVAL; goto done2; } - if ((error = ipcperm(td, &msqptr->msg_perm, IPC_W))) { + if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) { DPRINTF(("requester doesn't have write access\n")); goto done2; } @@ -635,17 +628,17 @@ msgsnd(td, uap) * (inside this loop in case msg_qbytes changes while we sleep) */ - if (msgsz > msqptr->msg_qbytes) { - DPRINTF(("msgsz > msqptr->msg_qbytes\n")); + if (msgsz > msqkptr->u.msg_qbytes) { + DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n")); error = EINVAL; goto done2; } - if (msqptr->msg_perm.mode & MSG_LOCKED) { + if (msqkptr->u.msg_perm.mode & MSG_LOCKED) { DPRINTF(("msqid is locked\n")); need_more_resources = 1; } - if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) { + if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) { DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n")); need_more_resources = 1; } @@ -668,22 +661,22 @@ msgsnd(td, uap) goto done2; } - if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) { + if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) { DPRINTF(("we don't own the msqid_ds\n")); we_own_it = 0; } else { /* Force later arrivals to wait for our request */ DPRINTF(("we own the msqid_ds\n")); - msqptr->msg_perm.mode |= MSG_LOCKED; + msqkptr->u.msg_perm.mode |= MSG_LOCKED; we_own_it = 1; } DPRINTF(("goodnight\n")); - error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH, + error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH, "msgwait", 0); DPRINTF(("good morning, error=%d\n", error)); if (we_own_it) - msqptr->msg_perm.mode &= ~MSG_LOCKED; + msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; if (error != 0) { DPRINTF(("msgsnd: interrupted system call\n")); error = EINTR; @@ -694,7 +687,7 @@ msgsnd(td, uap) * Make sure that the msq queue still exists */ - if (msqptr->msg_qbytes == 0) { + if (msqkptr->u.msg_qbytes == 0) { DPRINTF(("msqid deleted\n")); error = EIDRM; goto done2; @@ -711,11 +704,11 @@ msgsnd(td, uap) * Make sure! */ - if (msqptr->msg_perm.mode & MSG_LOCKED) + if (msqkptr->u.msg_perm.mode & MSG_LOCKED) panic("msg_perm.mode & MSG_LOCKED"); if (segs_needed > nfree_msgmaps) panic("segs_needed > nfree_msgmaps"); - if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) + if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) panic("msgsz + msg_cbytes > msg_qbytes"); if (free_msghdrs == NULL) panic("no more msghdrs"); @@ -725,9 +718,9 @@ msgsnd(td, uap) * message */ - if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) + if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) panic("msqid_ds is already locked"); - msqptr->msg_perm.mode |= MSG_LOCKED; + msqkptr->u.msg_perm.mode |= MSG_LOCKED; /* * Allocate a message header @@ -770,8 +763,8 @@ msgsnd(td, uap) mtx_lock(&msq_mtx); DPRINTF(("error %d copying the message type\n", error)); msg_freehdr(msghdr); - msqptr->msg_perm.mode &= ~MSG_LOCKED; - wakeup(msqptr); + msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; + wakeup(msqkptr); goto done2; } mtx_lock(&msq_mtx); @@ -783,8 +776,8 @@ msgsnd(td, uap) if (msghdr->msg_type < 1) { msg_freehdr(msghdr); - msqptr->msg_perm.mode &= ~MSG_LOCKED; - wakeup(msqptr); + msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; + wakeup(msqkptr); DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type)); error = EINVAL; goto done2; @@ -812,8 +805,8 @@ msgsnd(td, uap) DPRINTF(("error %d copying in message segment\n", error)); msg_freehdr(msghdr); - msqptr->msg_perm.mode &= ~MSG_LOCKED; - wakeup(msqptr); + msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; + wakeup(msqkptr); goto done2; } mtx_lock(&msq_mtx); @@ -828,15 +821,15 @@ msgsnd(td, uap) * We've got the message. Unlock the msqid_ds. */ - msqptr->msg_perm.mode &= ~MSG_LOCKED; + msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; /* * Make sure that the msqid_ds is still allocated. */ - if (msqptr->msg_qbytes == 0) { + if (msqkptr->u.msg_qbytes == 0) { msg_freehdr(msghdr); - wakeup(msqptr); + wakeup(msqkptr); error = EIDRM; goto done2; } @@ -844,22 +837,21 @@ msgsnd(td, uap) /* * Put the message into the queue */ - - if (msqptr->msg_first == NULL) { - msqptr->msg_first = msghdr; - msqptr->msg_last = msghdr; + if (msqkptr->u.msg_first == NULL) { + msqkptr->u.msg_first = msghdr; + msqkptr->u.msg_last = msghdr; } else { - msqptr->msg_last->msg_next = msghdr; - msqptr->msg_last = msghdr; + msqkptr->u.msg_last->msg_next = msghdr; + msqkptr->u.msg_last = msghdr; } - msqptr->msg_last->msg_next = NULL; + msqkptr->u.msg_last->msg_next = NULL; - msqptr->msg_cbytes += msghdr->msg_ts; - msqptr->msg_qnum++; - msqptr->msg_lspid = td->td_proc->p_pid; - msqptr->msg_stime = time_second; + msqkptr->u.msg_cbytes += msghdr->msg_ts; + msqkptr->u.msg_qnum++; + msqkptr->u.msg_lspid = td->td_proc->p_pid; + msqkptr->u.msg_stime = time_second; - wakeup(msqptr); + wakeup(msqkptr); td->td_retval[0] = 0; done2: mtx_unlock(&msq_mtx); @@ -890,7 +882,7 @@ msgrcv(td, uap) long msgtyp = uap->msgtyp; int msgflg = uap->msgflg; size_t len; - register struct msqid_ds *msqptr; + register struct msqid_kernel *msqkptr; register struct msg *msghdr; int error = 0; short next; @@ -909,20 +901,20 @@ msgrcv(td, uap) return (EINVAL); } - msqptr = &msqids[msqid]; + msqkptr = &msqids[msqid]; mtx_lock(&msq_mtx); - if (msqptr->msg_qbytes == 0) { + if (msqkptr->u.msg_qbytes == 0) { DPRINTF(("no such message queue id\n")); error = EINVAL; goto done2; } - if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { + if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { DPRINTF(("wrong sequence number\n")); error = EINVAL; goto done2; } - if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) { + if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) { DPRINTF(("requester doesn't have read access\n")); goto done2; } @@ -930,7 +922,7 @@ msgrcv(td, uap) msghdr = NULL; while (msghdr == NULL) { if (msgtyp == 0) { - msghdr = msqptr->msg_first; + msghdr = msqkptr->u.msg_first; if (msghdr != NULL) { if (msgsz < msghdr->msg_ts && (msgflg & MSG_NOERROR) == 0) { @@ -940,12 +932,12 @@ msgrcv(td, uap) error = E2BIG; goto done2; } - if (msqptr->msg_first == msqptr->msg_last) { - msqptr->msg_first = NULL; - msqptr->msg_last = NULL; + if (msqkptr->u.msg_first == msqkptr->u.msg_last) { + msqkptr->u.msg_first = NULL; + msqkptr->u.msg_last = NULL; } else { - msqptr->msg_first = msghdr->msg_next; - if (msqptr->msg_first == NULL) + msqkptr->u.msg_first = msghdr->msg_next; + if (msqkptr->u.msg_first == NULL) panic("msg_first/last screwed up #1"); } } @@ -954,7 +946,7 @@ msgrcv(td, uap) struct msg **prev; previous = NULL; - prev = &(msqptr->msg_first); + prev = &(msqkptr->u.msg_first); while ((msghdr = *prev) != NULL) { /* * Is this message's type an exact match or is @@ -980,20 +972,20 @@ msgrcv(td, uap) goto done2; } *prev = msghdr->msg_next; - if (msghdr == msqptr->msg_last) { + if (msghdr == msqkptr->u.msg_last) { if (previous == NULL) { if (prev != - &msqptr->msg_first) + &msqkptr->u.msg_first) panic("msg_first/last screwed up #2"); - msqptr->msg_first = + msqkptr->u.msg_first = NULL; - msqptr->msg_last = + msqkptr->u.msg_last = NULL; } else { if (prev == - &msqptr->msg_first) + &msqkptr->u.msg_first) panic("msg_first/last screwed up #3"); - msqptr->msg_last = + msqkptr->u.msg_last = previous; } } @@ -1030,7 +1022,7 @@ msgrcv(td, uap) */ DPRINTF(("msgrcv: goodnight\n")); - error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH, + error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH, "msgwait", 0); DPRINTF(("msgrcv: good morning (error=%d)\n", error)); @@ -1044,8 +1036,8 @@ msgrcv(td, uap) * Make sure that the msq queue still exists */ - if (msqptr->msg_qbytes == 0 || - msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { + if (msqkptr->u.msg_qbytes == 0 || + msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { DPRINTF(("msqid deleted\n")); error = EIDRM; goto done2; @@ -1058,10 +1050,10 @@ msgrcv(td, uap) * First, do the bookkeeping (before we risk being interrupted). */ - msqptr->msg_cbytes -= msghdr->msg_ts; - msqptr->msg_qnum--; - msqptr->msg_lrpid = td->td_proc->p_pid; - msqptr->msg_rtime = time_second; + msqkptr->u.msg_cbytes -= msghdr->msg_ts; + msqkptr->u.msg_qnum--; + msqkptr->u.msg_lrpid = td->td_proc->p_pid; + msqkptr->u.msg_rtime = time_second; /* * Make msgsz the actual amount that we'll be returning. @@ -1085,7 +1077,7 @@ msgrcv(td, uap) if (error != 0) { DPRINTF(("error (%d) copying out message type\n", error)); msg_freehdr(msghdr); - wakeup(msqptr); + wakeup(msqkptr); goto done2; } user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type); @@ -1114,7 +1106,7 @@ msgrcv(td, uap) DPRINTF(("error (%d) copying out message segment\n", error)); msg_freehdr(msghdr); - wakeup(msqptr); + wakeup(msqkptr); goto done2; } user_msgp = (char *)user_msgp + tlen; @@ -1126,7 +1118,7 @@ msgrcv(td, uap) */ msg_freehdr(msghdr); - wakeup(msqptr); + wakeup(msqkptr); td->td_retval[0] = msgsz; done2: mtx_unlock(&msq_mtx); @@ -1138,7 +1130,7 @@ sysctl_msqids(SYSCTL_HANDLER_ARGS) { return (SYSCTL_OUT(req, msqids, - sizeof(struct msqid_ds) * msginfo.msgmni)); + sizeof(struct msqid_kernel) * msginfo.msgmni)); } SYSCTL_DECL(_kern_ipc); diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index b141bc2..4f2779b 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -40,7 +40,7 @@ static int sysvsem_modload(struct module *, int, void *); static int semunload(void); static void semexit_myhook(void *arg, struct proc *p); static int sysctl_sema(SYSCTL_HANDLER_ARGS); -static int semvalid(int semid, struct semid_ds *semaptr); +static int semvalid(int semid, struct semid_kernel *semakptr); #ifndef _SYS_SYSPROTO_H_ struct __semctl_args; @@ -64,7 +64,7 @@ static sy_call_t *semcalls[] = { static struct mtx sem_mtx; /* semaphore global lock */ static int semtot = 0; -static struct semid_ds *sema; /* semaphore id pool */ +static struct semid_kernel *sema; /* semaphore id pool */ static struct mtx *sema_mtx; /* semaphore id pool mutexes*/ static struct sem *sem; /* semaphore pool */ SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */ @@ -190,16 +190,16 @@ seminit(void) TUNABLE_INT_FETCH("kern.ipc.semaem", &seminfo.semaem); sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK); - sema = malloc(sizeof(struct semid_ds) * seminfo.semmni, M_SEM, + sema = malloc(sizeof(struct semid_kernel) * seminfo.semmni, M_SEM, M_WAITOK); sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM, M_WAITOK | M_ZERO); semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK); for (i = 0; i < seminfo.semmni; i++) { - sema[i].sem_base = 0; - sema[i].sem_perm.mode = 0; - sema[i].sem_perm.seq = 0; + sema[i].u.sem_base = 0; + sema[i].u.sem_perm.mode = 0; + sema[i].u.sem_perm.seq = 0; } for (i = 0; i < seminfo.semmni; i++) mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF); @@ -472,13 +472,13 @@ semundo_clear(semid, semnum) } static int -semvalid(semid, semaptr) +semvalid(semid, semakptr) int semid; - struct semid_ds *semaptr; + struct semid_kernel *semakptr; { - return ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || - semaptr->sem_perm.seq != IPCID_TO_SEQ(semid) ? EINVAL : 0); + return ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 || + semakptr->u.sem_perm.seq != IPCID_TO_SEQ(semid) ? EINVAL : 0); } /* @@ -510,7 +510,7 @@ __semctl(td, uap) struct ucred *cred = td->td_ucred; int i, rval, error; struct semid_ds sbuf; - struct semid_ds *semaptr; + struct semid_kernel *semakptr; struct mtx *sema_mtxp; u_short usval, count; @@ -527,18 +527,19 @@ __semctl(td, uap) return (EINVAL); if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) return (error); - semaptr = &sema[semid]; + semakptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; mtx_lock(sema_mtxp); - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) { + if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0) { error = EINVAL; goto done2; } - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; mtx_unlock(sema_mtxp); - error = copyout(semaptr, real_arg.buf, sizeof(struct semid_ds)); - rval = IXSEQ_TO_IPCID(semid,semaptr->sem_perm); + error = copyout(&semakptr->u, real_arg.buf, + sizeof(struct semid_ds)); + rval = IXSEQ_TO_IPCID(semid, semakptr->u.sem_perm); if (error == 0) td->td_retval[0] = rval; return (error); @@ -548,7 +549,7 @@ __semctl(td, uap) if (semid < 0 || semid >= seminfo.semmni) return (EINVAL); - semaptr = &sema[semid]; + semakptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; error = 0; @@ -557,25 +558,25 @@ __semctl(td, uap) switch (cmd) { case IPC_RMID: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_M))) goto done2; - semaptr->sem_perm.cuid = cred->cr_uid; - semaptr->sem_perm.uid = cred->cr_uid; - semtot -= semaptr->sem_nsems; - for (i = semaptr->sem_base - sem; i < semtot; i++) - sem[i] = sem[i + semaptr->sem_nsems]; + semakptr->u.sem_perm.cuid = cred->cr_uid; + semakptr->u.sem_perm.uid = cred->cr_uid; + semtot -= semakptr->u.sem_nsems; + for (i = semakptr->u.sem_base - sem; i < semtot; i++) + sem[i] = sem[i + semakptr->u.sem_nsems]; for (i = 0; i < seminfo.semmni; i++) { - if ((sema[i].sem_perm.mode & SEM_ALLOC) && - sema[i].sem_base > semaptr->sem_base) - sema[i].sem_base -= semaptr->sem_nsems; + if ((sema[i].u.sem_perm.mode & SEM_ALLOC) && + sema[i].u.sem_base > semakptr->u.sem_base) + sema[i].u.sem_base -= semakptr->u.sem_nsems; } - semaptr->sem_perm.mode = 0; + semakptr->u.sem_perm.mode = 0; SEMUNDO_LOCK(); semundo_clear(semid, -1); SEMUNDO_UNLOCK(); - wakeup(semaptr); + wakeup(semakptr); break; case IPC_SET: @@ -584,82 +585,82 @@ __semctl(td, uap) if ((error = copyin(real_arg.buf, &sbuf, sizeof(sbuf))) != 0) goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_M))) goto done2; - semaptr->sem_perm.uid = sbuf.sem_perm.uid; - semaptr->sem_perm.gid = sbuf.sem_perm.gid; - semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | - (sbuf.sem_perm.mode & 0777); - semaptr->sem_ctime = time_second; + semakptr->u.sem_perm.uid = sbuf.sem_perm.uid; + semakptr->u.sem_perm.gid = sbuf.sem_perm.gid; + semakptr->u.sem_perm.mode = (semakptr->u.sem_perm.mode & + ~0777) | (sbuf.sem_perm.mode & 0777); + semakptr->u.sem_ctime = time_second; break; case IPC_STAT: if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - sbuf = *semaptr; + sbuf = semakptr->u; mtx_unlock(sema_mtxp); - error = copyout(semaptr, real_arg.buf, + error = copyout(&semakptr->u, real_arg.buf, sizeof(struct semid_ds)); break; case GETNCNT: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - if (semnum < 0 || semnum >= semaptr->sem_nsems) { + if (semnum < 0 || semnum >= semakptr->u.sem_nsems) { error = EINVAL; goto done2; } - rval = semaptr->sem_base[semnum].semncnt; + rval = semakptr->u.sem_base[semnum].semncnt; break; case GETPID: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - if (semnum < 0 || semnum >= semaptr->sem_nsems) { + if (semnum < 0 || semnum >= semakptr->u.sem_nsems) { error = EINVAL; goto done2; } - rval = semaptr->sem_base[semnum].sempid; + rval = semakptr->u.sem_base[semnum].sempid; break; case GETVAL: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - if (semnum < 0 || semnum >= semaptr->sem_nsems) { + if (semnum < 0 || semnum >= semakptr->u.sem_nsems) { error = EINVAL; goto done2; } - rval = semaptr->sem_base[semnum].semval; + rval = semakptr->u.sem_base[semnum].semval; break; case GETALL: if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) goto done2; - array = malloc(sizeof(*array) * semaptr->sem_nsems, M_TEMP, + array = malloc(sizeof(*array) * semakptr->u.sem_nsems, M_TEMP, M_WAITOK); mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - for (i = 0; i < semaptr->sem_nsems; i++) - array[i] = semaptr->sem_base[i].semval; + for (i = 0; i < semakptr->u.sem_nsems; i++) + array[i] = semakptr->u.sem_base[i].semval; mtx_unlock(sema_mtxp); error = copyout(array, real_arg.array, i * sizeof(real_arg.array[0])); @@ -667,26 +668,26 @@ __semctl(td, uap) case GETZCNT: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) goto done2; - if (semnum < 0 || semnum >= semaptr->sem_nsems) { + if (semnum < 0 || semnum >= semakptr->u.sem_nsems) { error = EINVAL; goto done2; } - rval = semaptr->sem_base[semnum].semzcnt; + rval = semakptr->u.sem_base[semnum].semzcnt; break; case SETVAL: if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_W))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_W))) goto done2; - if (semnum < 0 || semnum >= semaptr->sem_nsems) { + if (semnum < 0 || semnum >= semakptr->u.sem_nsems) { error = EINVAL; goto done2; } @@ -694,19 +695,19 @@ __semctl(td, uap) error = ERANGE; goto done2; } - semaptr->sem_base[semnum].semval = real_arg.val; + semakptr->u.sem_base[semnum].semval = real_arg.val; SEMUNDO_LOCK(); semundo_clear(semid, semnum); SEMUNDO_UNLOCK(); - wakeup(semaptr); + wakeup(semakptr); break; case SETALL: mtx_lock(sema_mtxp); raced: - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; - count = semaptr->sem_nsems; + count = semakptr->u.sem_nsems; mtx_unlock(sema_mtxp); if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) goto done2; @@ -715,28 +716,28 @@ raced: if (error) break; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(uap->semid, semakptr)) != 0) goto done2; /* we could have raced? */ - if (count != semaptr->sem_nsems) { + if (count != semakptr->u.sem_nsems) { free(array, M_TEMP); array = NULL; goto raced; } - if ((error = ipcperm(td, &semaptr->sem_perm, IPC_W))) + if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_W))) goto done2; - for (i = 0; i < semaptr->sem_nsems; i++) { + for (i = 0; i < semakptr->u.sem_nsems; i++) { usval = array[i]; if (usval > seminfo.semvmx) { error = ERANGE; break; } - semaptr->sem_base[i].semval = usval; + semakptr->u.sem_base[i].semval = usval; } SEMUNDO_LOCK(); semundo_clear(semid, -1); SEMUNDO_UNLOCK(); - wakeup(semaptr); + wakeup(semakptr); break; default: @@ -783,17 +784,17 @@ semget(td, uap) mtx_lock(&Giant); if (key != IPC_PRIVATE) { for (semid = 0; semid < seminfo.semmni; semid++) { - if ((sema[semid].sem_perm.mode & SEM_ALLOC) && - sema[semid].sem_perm.key == key) + if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) && + sema[semid].u.sem_perm.key == key) break; } if (semid < seminfo.semmni) { DPRINTF(("found public key\n")); - if ((error = ipcperm(td, &sema[semid].sem_perm, + if ((error = ipcperm(td, &sema[semid].u.sem_perm, semflg & 0700))) { goto done2; } - if (nsems > 0 && sema[semid].sem_nsems < nsems) { + if (nsems > 0 && sema[semid].u.sem_nsems < nsems) { DPRINTF(("too small\n")); error = EINVAL; goto done2; @@ -807,7 +808,7 @@ semget(td, uap) } } - DPRINTF(("need to allocate the semid_ds\n")); + DPRINTF(("need to allocate the semid_kernel\n")); if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { if (nsems <= 0 || nsems > seminfo.semmsl) { DPRINTF(("nsems out of range (0<%d<=%d)\n", nsems, @@ -823,32 +824,32 @@ semget(td, uap) goto done2; } for (semid = 0; semid < seminfo.semmni; semid++) { - if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) + if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0) break; } if (semid == seminfo.semmni) { - DPRINTF(("no more semid_ds's available\n")); + DPRINTF(("no more semid_kernel's available\n")); error = ENOSPC; goto done2; } DPRINTF(("semid %d is available\n", semid)); - sema[semid].sem_perm.key = key; - sema[semid].sem_perm.cuid = cred->cr_uid; - sema[semid].sem_perm.uid = cred->cr_uid; - sema[semid].sem_perm.cgid = cred->cr_gid; - sema[semid].sem_perm.gid = cred->cr_gid; - sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; - sema[semid].sem_perm.seq = - (sema[semid].sem_perm.seq + 1) & 0x7fff; - sema[semid].sem_nsems = nsems; - sema[semid].sem_otime = 0; - sema[semid].sem_ctime = time_second; - sema[semid].sem_base = &sem[semtot]; + sema[semid].u.sem_perm.key = key; + sema[semid].u.sem_perm.cuid = cred->cr_uid; + sema[semid].u.sem_perm.uid = cred->cr_uid; + sema[semid].u.sem_perm.cgid = cred->cr_gid; + sema[semid].u.sem_perm.gid = cred->cr_gid; + sema[semid].u.sem_perm.mode = (semflg & 0777) | SEM_ALLOC; + sema[semid].u.sem_perm.seq = + (sema[semid].u.sem_perm.seq + 1) & 0x7fff; + sema[semid].u.sem_nsems = nsems; + sema[semid].u.sem_otime = 0; + sema[semid].u.sem_ctime = time_second; + sema[semid].u.sem_base = &sem[semtot]; semtot += nsems; - bzero(sema[semid].sem_base, - sizeof(sema[semid].sem_base[0])*nsems); - DPRINTF(("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base, - &sem[semtot])); + bzero(sema[semid].u.sem_base, + sizeof(sema[semid].u.sem_base[0])*nsems); + DPRINTF(("sembase = 0x%x, next = 0x%x\n", + sema[semid].u.sem_base, &sem[semtot])); } else { DPRINTF(("didn't find it and wasn't asked to create it\n")); error = ENOENT; @@ -856,7 +857,7 @@ semget(td, uap) } found: - td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); + td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].u.sem_perm); done2: mtx_unlock(&Giant); return (error); @@ -883,7 +884,7 @@ semop(td, uap) int semid = uap->semid; size_t nsops = uap->nsops; struct sembuf *sops; - struct semid_ds *semaptr; + struct semid_kernel *semakptr; struct sembuf *sopptr = 0; struct sem *semptr = 0; struct sem_undo *suptr; @@ -900,7 +901,7 @@ semop(td, uap) semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ if (semid < 0 || semid >= seminfo.semmni) - return (EINVAL); + error = EINVAL; /* Allocate memory for sem_ops */ if (nsops <= SMALL_SOPS) @@ -920,14 +921,14 @@ semop(td, uap) return (error); } - semaptr = &sema[semid]; + semakptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; mtx_lock(sema_mtxp); - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) { + if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0) { error = EINVAL; goto done2; } - if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + if (semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { error = EINVAL; goto done2; } @@ -940,7 +941,7 @@ semop(td, uap) do_undos = 0; for (i = 0; i < nsops; i++) { sopptr = &sops[i]; - if (sopptr->sem_num >= semaptr->sem_nsems) { + if (sopptr->sem_num >= semakptr->u.sem_nsems) { error = EFBIG; goto done2; } @@ -949,7 +950,7 @@ semop(td, uap) j |= (sopptr->sem_op == 0) ? SEM_R : SEM_A; } - if ((error = ipcperm(td, &semaptr->sem_perm, j))) { + if ((error = ipcperm(td, &semakptr->u.sem_perm, j))) { DPRINTF(("error = %d from ipaccess\n", error)); goto done2; } @@ -969,12 +970,12 @@ semop(td, uap) for (i = 0; i < nsops; i++) { sopptr = &sops[i]; - semptr = &semaptr->sem_base[sopptr->sem_num]; + semptr = &semakptr->u.sem_base[sopptr->sem_num]; DPRINTF(( - "semop: semaptr=%x, sem_base=%x, " + "semop: semakptr=%x, sem_base=%x, " "semptr=%x, sem[%d]=%d : op=%d, flag=%s\n", - semaptr, semaptr->sem_base, semptr, + semakptr, semakptr->u.sem_base, semptr, sopptr->sem_num, semptr->semval, sopptr->sem_op, (sopptr->sem_flg & IPC_NOWAIT) ? "nowait" : "wait")); @@ -1016,7 +1017,7 @@ semop(td, uap) */ DPRINTF(("semop: rollback 0 through %d\n", i-1)); for (j = 0; j < i; j++) - semaptr->sem_base[sops[j].sem_num].semval -= + semakptr->u.sem_base[sops[j].sem_num].semval -= sops[j].sem_op; /* If we detected an error, return it */ @@ -1038,7 +1039,7 @@ semop(td, uap) semptr->semncnt++; DPRINTF(("semop: good night!\n")); - error = msleep(semaptr, sema_mtxp, (PZERO - 4) | PCATCH, + error = msleep(semakptr, sema_mtxp, (PZERO - 4) | PCATCH, "semwait", 0); DPRINTF(("semop: good morning (error=%d)!\n", error)); /* return code is checked below, after sem[nz]cnt-- */ @@ -1046,8 +1047,8 @@ semop(td, uap) /* * Make sure that the semaphore still exists */ - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || - semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 || + semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { error = EIDRM; goto done2; } @@ -1119,7 +1120,7 @@ done: } for (j = 0; j < nsops; j++) - semaptr->sem_base[sops[j].sem_num].semval -= + semakptr->u.sem_base[sops[j].sem_num].semval -= sops[j].sem_op; DPRINTF(("error = %d from semundo_adjust\n", error)); @@ -1132,10 +1133,10 @@ done: /* We're definitely done - set the sempid's and time */ for (i = 0; i < nsops; i++) { sopptr = &sops[i]; - semptr = &semaptr->sem_base[sopptr->sem_num]; + semptr = &semakptr->u.sem_base[sopptr->sem_num]; semptr->sempid = td->td_proc->p_pid; } - semaptr->sem_otime = time_second; + semakptr->u.sem_otime = time_second; /* * Do a wakeup if any semaphore was up'd whilst something was @@ -1143,7 +1144,7 @@ done: */ if (do_wakeup) { DPRINTF(("semop: doing wakeup\n")); - wakeup(semaptr); + wakeup(semakptr); DPRINTF(("semop: back from wakeup\n")); } DPRINTF(("semop: done\n")); @@ -1152,6 +1153,7 @@ done2: mtx_unlock(sema_mtxp); if (sops != small_sops) free(sops, M_SEM); + free(sops, M_SEM); return (error); } @@ -1194,16 +1196,16 @@ semexit_myhook(arg, p) int semid = suptr->un_ent[ix].un_id; int semnum = suptr->un_ent[ix].un_num; int adjval = suptr->un_ent[ix].un_adjval; - struct semid_ds *semaptr; + struct semid_kernel *semakptr; struct mtx *sema_mtxp; - semaptr = &sema[semid]; + semakptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; mtx_lock(sema_mtxp); SEMUNDO_LOCK(); - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) + if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0) panic("semexit - semid not allocated"); - if (semnum >= semaptr->sem_nsems) + if (semnum >= semakptr->u.sem_nsems) panic("semexit - semnum out of range"); DPRINTF(( @@ -1211,18 +1213,19 @@ semexit_myhook(arg, p) suptr->un_proc, suptr->un_ent[ix].un_id, suptr->un_ent[ix].un_num, suptr->un_ent[ix].un_adjval, - semaptr->sem_base[semnum].semval)); + semakptr->u.sem_base[semnum].semval)); if (adjval < 0) { - if (semaptr->sem_base[semnum].semval < -adjval) - semaptr->sem_base[semnum].semval = 0; + if (semakptr->u.sem_base[semnum].semval < + -adjval) + semakptr->u.sem_base[semnum].semval = 0; else - semaptr->sem_base[semnum].semval += + semakptr->u.sem_base[semnum].semval += adjval; } else - semaptr->sem_base[semnum].semval += adjval; + semakptr->u.sem_base[semnum].semval += adjval; - wakeup(semaptr); + wakeup(semakptr); DPRINTF(("semexit: back from wakeup\n")); mtx_unlock(sema_mtxp); SEMUNDO_UNLOCK(); @@ -1242,5 +1245,5 @@ sysctl_sema(SYSCTL_HANDLER_ARGS) { return (SYSCTL_OUT(req, sema, - sizeof(struct semid_ds) * seminfo.semmni)); + sizeof(struct semid_kernel) * seminfo.semmni)); } diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 1173583..1e0ea40 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -85,17 +85,17 @@ static sy_call_t *shmcalls[] = { #define SHMSEG_WANTED 0x1000 static int shm_last_free, shm_nused, shm_committed, shmalloced; -static struct shmid_ds *shmsegs; +static struct shmid_kernel *shmsegs; struct shmmap_state { vm_offset_t va; int shmid; }; -static void shm_deallocate_segment(struct shmid_ds *); +static void shm_deallocate_segment(struct shmid_kernel *); static int shm_find_segment_by_key(key_t); -static struct shmid_ds *shm_find_segment_by_shmid(int); -static struct shmid_ds *shm_find_segment_by_shmidx(int); +static struct shmid_kernel *shm_find_segment_by_shmid(int); +static struct shmid_kernel *shm_find_segment_by_shmidx(int); static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *); static void shmrealloc(void); static void shminit(void); @@ -158,65 +158,65 @@ shm_find_segment_by_key(key) int i; for (i = 0; i < shmalloced; i++) - if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && - shmsegs[i].shm_perm.key == key) + if ((shmsegs[i].u.shm_perm.mode & SHMSEG_ALLOCATED) && + shmsegs[i].u.shm_perm.key == key) return (i); return (-1); } -static struct shmid_ds * +static struct shmid_kernel * shm_find_segment_by_shmid(int shmid) { int segnum; - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; segnum = IPCID_TO_IX(shmid); if (segnum < 0 || segnum >= shmalloced) return (NULL); shmseg = &shmsegs[segnum]; - if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 || + if ((shmseg->u.shm_perm.mode & SHMSEG_ALLOCATED) == 0 || (!shm_allow_removed && - (shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0) || - shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) + (shmseg->u.shm_perm.mode & SHMSEG_REMOVED) != 0) || + shmseg->u.shm_perm.seq != IPCID_TO_SEQ(shmid)) return (NULL); return (shmseg); } -static struct shmid_ds * +static struct shmid_kernel * shm_find_segment_by_shmidx(int segnum) { - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; if (segnum < 0 || segnum >= shmalloced) return (NULL); shmseg = &shmsegs[segnum]; - if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 || + if ((shmseg->u.shm_perm.mode & SHMSEG_ALLOCATED) == 0 || (!shm_allow_removed && - (shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0)) + (shmseg->u.shm_perm.mode & SHMSEG_REMOVED) != 0)) return (NULL); return (shmseg); } static void shm_deallocate_segment(shmseg) - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; { size_t size; GIANT_REQUIRED; - vm_object_deallocate(shmseg->shm_internal); - shmseg->shm_internal = NULL; - size = round_page(shmseg->shm_segsz); + vm_object_deallocate(shmseg->u.shm_internal); + shmseg->u.shm_internal = NULL; + size = round_page(shmseg->u.shm_segsz); shm_committed -= btoc(size); shm_nused--; - shmseg->shm_perm.mode = SHMSEG_FREE; + shmseg->u.shm_perm.mode = SHMSEG_FREE; } static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s) { - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; int segnum, result; size_t size; @@ -224,14 +224,14 @@ shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s) segnum = IPCID_TO_IX(shmmap_s->shmid); shmseg = &shmsegs[segnum]; - size = round_page(shmseg->shm_segsz); + size = round_page(shmseg->u.shm_segsz); result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size); if (result != KERN_SUCCESS) return (EINVAL); shmmap_s->shmid = -1; - shmseg->shm_dtime = time_second; - if ((--shmseg->shm_nattch <= 0) && - (shmseg->shm_perm.mode & SHMSEG_REMOVED)) { + shmseg->u.shm_dtime = time_second; + if ((--shmseg->u.shm_nattch <= 0) && + (shmseg->u.shm_perm.mode & SHMSEG_REMOVED)) { shm_deallocate_segment(shmseg); shm_last_free = segnum; } @@ -301,7 +301,7 @@ kern_shmat(td, shmid, shmaddr, shmflg) { struct proc *p = td->td_proc; int i, flags; - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; struct shmmap_state *shmmap_s = NULL; vm_offset_t attach_va; vm_prot_t prot; @@ -325,7 +325,7 @@ kern_shmat(td, shmid, shmaddr, shmflg) error = EINVAL; goto done2; } - error = ipcperm(td, &shmseg->shm_perm, + error = ipcperm(td, &shmseg->u.shm_perm, (shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W); if (error) goto done2; @@ -338,7 +338,7 @@ kern_shmat(td, shmid, shmaddr, shmflg) error = EMFILE; goto done2; } - size = round_page(shmseg->shm_segsz); + size = round_page(shmseg->u.shm_segsz); #ifdef VM_PROT_READ_IS_EXEC prot = VM_PROT_READ | VM_PROT_EXECUTE; #else @@ -368,11 +368,11 @@ kern_shmat(td, shmid, shmaddr, shmflg) PROC_UNLOCK(p); } - vm_object_reference(shmseg->shm_internal); - rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->shm_internal, + vm_object_reference(shmseg->u.shm_internal); + rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->u.shm_internal, 0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0); if (rv != KERN_SUCCESS) { - vm_object_deallocate(shmseg->shm_internal); + vm_object_deallocate(shmseg->u.shm_internal); error = ENOMEM; goto done2; } @@ -381,9 +381,9 @@ kern_shmat(td, shmid, shmaddr, shmflg) shmmap_s->va = attach_va; shmmap_s->shmid = shmid; - shmseg->shm_lpid = p->p_pid; - shmseg->shm_atime = time_second; - shmseg->shm_nattch++; + shmseg->u.shm_lpid = p->p_pid; + shmseg->u.shm_atime = time_second; + shmseg->u.shm_nattch++; td->td_retval[0] = attach_va; done2: mtx_unlock(&Giant); @@ -426,7 +426,7 @@ oshmctl(td, uap) { #ifdef COMPAT_43 int error = 0; - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; struct oshmid_ds outbuf; if (!jail_sysvipc_allowed && jailed(td->td_ucred)) @@ -439,18 +439,18 @@ oshmctl(td, uap) } switch (uap->cmd) { case IPC_STAT: - error = ipcperm(td, &shmseg->shm_perm, IPC_R); + error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); if (error) goto done2; - outbuf.shm_perm = shmseg->shm_perm; - outbuf.shm_segsz = shmseg->shm_segsz; - outbuf.shm_cpid = shmseg->shm_cpid; - outbuf.shm_lpid = shmseg->shm_lpid; - outbuf.shm_nattch = shmseg->shm_nattch; - outbuf.shm_atime = shmseg->shm_atime; - outbuf.shm_dtime = shmseg->shm_dtime; - outbuf.shm_ctime = shmseg->shm_ctime; - outbuf.shm_handle = shmseg->shm_internal; + outbuf.shm_perm = shmseg->u.shm_perm; + outbuf.shm_segsz = shmseg->u.shm_segsz; + outbuf.shm_cpid = shmseg->u.shm_cpid; + outbuf.shm_lpid = shmseg->u.shm_lpid; + outbuf.shm_nattch = shmseg->u.shm_nattch; + outbuf.shm_atime = shmseg->u.shm_atime; + outbuf.shm_dtime = shmseg->u.shm_dtime; + outbuf.shm_ctime = shmseg->u.shm_ctime; + outbuf.shm_handle = shmseg->u.shm_internal; error = copyout(&outbuf, uap->ubuf, sizeof(outbuf)); if (error) goto done2; @@ -487,7 +487,7 @@ kern_shmctl(td, shmid, cmd, buf, bufsz) size_t *bufsz; { int error = 0; - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS); @@ -526,37 +526,37 @@ kern_shmctl(td, shmid, cmd, buf, bufsz) switch (cmd) { case SHM_STAT: case IPC_STAT: - error = ipcperm(td, &shmseg->shm_perm, IPC_R); + error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); if (error) goto done2; - memcpy(buf, shmseg, sizeof(struct shmid_ds)); + memcpy(buf, &shmseg->u, sizeof(struct shmid_ds)); if (bufsz) *bufsz = sizeof(struct shmid_ds); if (cmd == SHM_STAT) - td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->shm_perm); + td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->u.shm_perm); break; case IPC_SET: { struct shmid_ds *shmid; shmid = (struct shmid_ds *)buf; - error = ipcperm(td, &shmseg->shm_perm, IPC_M); + error = ipcperm(td, &shmseg->u.shm_perm, IPC_M); if (error) goto done2; - shmseg->shm_perm.uid = shmid->shm_perm.uid; - shmseg->shm_perm.gid = shmid->shm_perm.gid; - shmseg->shm_perm.mode = - (shmseg->shm_perm.mode & ~ACCESSPERMS) | + shmseg->u.shm_perm.uid = shmid->shm_perm.uid; + shmseg->u.shm_perm.gid = shmid->shm_perm.gid; + shmseg->u.shm_perm.mode = + (shmseg->u.shm_perm.mode & ~ACCESSPERMS) | (shmid->shm_perm.mode & ACCESSPERMS); - shmseg->shm_ctime = time_second; + shmseg->u.shm_ctime = time_second; break; } case IPC_RMID: - error = ipcperm(td, &shmseg->shm_perm, IPC_M); + error = ipcperm(td, &shmseg->u.shm_perm, IPC_M); if (error) goto done2; - shmseg->shm_perm.key = IPC_PRIVATE; - shmseg->shm_perm.mode |= SHMSEG_REMOVED; - if (shmseg->shm_nattch <= 0) { + shmseg->u.shm_perm.key = IPC_PRIVATE; + shmseg->u.shm_perm.mode |= SHMSEG_REMOVED; + if (shmseg->u.shm_nattch <= 0) { shm_deallocate_segment(shmseg); shm_last_free = IPCID_TO_IX(shmid); } @@ -627,17 +627,17 @@ shmget_existing(td, uap, mode, segnum) int mode; int segnum; { - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; int error; shmseg = &shmsegs[segnum]; - if (shmseg->shm_perm.mode & SHMSEG_REMOVED) { + if (shmseg->u.shm_perm.mode & SHMSEG_REMOVED) { /* * This segment is in the process of being allocated. Wait * until it's done, and look the key up again (in case the * allocation failed or it was freed). */ - shmseg->shm_perm.mode |= SHMSEG_WANTED; + shmseg->u.shm_perm.mode |= SHMSEG_WANTED; error = tsleep(shmseg, PLOCK | PCATCH, "shmget", 0); if (error) return (error); @@ -645,12 +645,12 @@ shmget_existing(td, uap, mode, segnum) } if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL)) return (EEXIST); - error = ipcperm(td, &shmseg->shm_perm, mode); + error = ipcperm(td, &shmseg->u.shm_perm, mode); if (error) return (error); - if (uap->size && uap->size > shmseg->shm_segsz) + if (uap->size && uap->size > shmseg->u.shm_segsz) return (EINVAL); - td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); + td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm); return (0); } @@ -662,7 +662,7 @@ shmget_allocate_segment(td, uap, mode) { int i, segnum, shmid, size; struct ucred *cred = td->td_ucred; - struct shmid_ds *shmseg; + struct shmid_kernel *shmseg; vm_object_t shm_object; GIANT_REQUIRED; @@ -677,7 +677,7 @@ shmget_allocate_segment(td, uap, mode) if (shm_last_free < 0) { shmrealloc(); /* Maybe expand the shmsegs[] array. */ for (i = 0; i < shmalloced; i++) - if (shmsegs[i].shm_perm.mode & SHMSEG_FREE) + if (shmsegs[i].u.shm_perm.mode & SHMSEG_FREE) break; if (i == shmalloced) return (ENOSPC); @@ -691,10 +691,10 @@ shmget_allocate_segment(td, uap, mode) * In case we sleep in malloc(), mark the segment present but deleted * so that noone else tries to create the same key. */ - shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED; - shmseg->shm_perm.key = uap->key; - shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff; - shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); + shmseg->u.shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED; + shmseg->u.shm_perm.key = uap->key; + shmseg->u.shm_perm.seq = (shmseg->u.shm_perm.seq + 1) & 0x7fff; + shmid = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm); /* * We make sure that we have allocated a pager before we need @@ -712,24 +712,24 @@ shmget_allocate_segment(td, uap, mode) vm_object_set_flag(shm_object, OBJ_NOSPLIT); VM_OBJECT_UNLOCK(shm_object); - shmseg->shm_internal = shm_object; - shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid; - shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid; - shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) | + shmseg->u.shm_internal = shm_object; + shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid; + shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid; + shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) | (mode & ACCESSPERMS) | SHMSEG_ALLOCATED; - shmseg->shm_segsz = uap->size; - shmseg->shm_cpid = td->td_proc->p_pid; - shmseg->shm_lpid = shmseg->shm_nattch = 0; - shmseg->shm_atime = shmseg->shm_dtime = 0; - shmseg->shm_ctime = time_second; + shmseg->u.shm_segsz = uap->size; + shmseg->u.shm_cpid = td->td_proc->p_pid; + shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0; + shmseg->u.shm_atime = shmseg->u.shm_dtime = 0; + shmseg->u.shm_ctime = time_second; shm_committed += btoc(size); shm_nused++; - if (shmseg->shm_perm.mode & SHMSEG_WANTED) { + if (shmseg->u.shm_perm.mode & SHMSEG_WANTED) { /* * Somebody else wanted this key while we were asleep. Wake * them up now. */ - shmseg->shm_perm.mode &= ~SHMSEG_WANTED; + shmseg->u.shm_perm.mode &= ~SHMSEG_WANTED; wakeup(shmseg); } td->td_retval[0] = shmid; @@ -813,7 +813,7 @@ shmfork_myhook(p1, p2) p2->p_vmspace->vm_shm = shmmap_s; for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) if (shmmap_s->shmid != -1) - shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; + shmsegs[IPCID_TO_IX(shmmap_s->shmid)].u.shm_nattch++; mtx_unlock(&Giant); } @@ -839,7 +839,7 @@ static void shmrealloc(void) { int i; - struct shmid_ds *newsegs; + struct shmid_kernel *newsegs; if (shmalloced >= shminfo.shmmni) return; @@ -850,8 +850,8 @@ shmrealloc(void) for (i = 0; i < shmalloced; i++) bcopy(&shmsegs[i], &newsegs[i], sizeof(newsegs[0])); for (; i < shminfo.shmmni; i++) { - shmsegs[i].shm_perm.mode = SHMSEG_FREE; - shmsegs[i].shm_perm.seq = 0; + shmsegs[i].u.shm_perm.mode = SHMSEG_FREE; + shmsegs[i].u.shm_perm.seq = 0; } free(shmsegs, M_SHM); shmsegs = newsegs; @@ -879,8 +879,8 @@ shminit() if (shmsegs == NULL) panic("cannot allocate initial memory for sysvshm"); for (i = 0; i < shmalloced; i++) { - shmsegs[i].shm_perm.mode = SHMSEG_FREE; - shmsegs[i].shm_perm.seq = 0; + shmsegs[i].u.shm_perm.mode = SHMSEG_FREE; + shmsegs[i].u.shm_perm.seq = 0; } shm_last_free = 0; shm_nused = 0; diff --git a/sys/sys/msg.h b/sys/sys/msg.h index fa058e1..53d1047 100644 --- a/sys/sys/msg.h +++ b/sys/sys/msg.h @@ -100,6 +100,15 @@ struct mymsg { #ifdef _KERNEL +struct msg { + struct msg *msg_next; /* next msg in the chain */ + long msg_type; /* type of this message */ + /* >0 -> type of this message */ + /* 0 -> free header */ + u_short msg_ts; /* size of this message */ + short msg_spot; /* location of start of msg in buffer */ +}; + /* * Based on the configuration parameters described in an SVR2 (yes, two) * config(1m) man page. |