static void shm_rcu_free(struct rcu_head *head) { struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); struct shmid_kernel *shp = ipc_rcu_to_struct(p); security_shm_free(shp); ipc_rcu_free(head); }
static int newque (key_t key, int msgflg) { int id; int retval; struct msg_queue *msq; msq = ipc_rcu_alloc(sizeof(*msq)); if (!msq) return -ENOMEM; msq->q_perm.mode = (msgflg & S_IRWXUGO); msq->q_perm.key = key; msq->q_perm.security = NULL; retval = security_msg_queue_alloc(msq); if (retval) { ipc_rcu_free(msq, sizeof(*msq)); return retval; } id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni); if(id == -1) { security_msg_queue_free(msq); ipc_rcu_free(msq, sizeof(*msq)); return -ENOSPC; } msq->q_stime = msq->q_rtime = 0; msq->q_ctime = get_seconds(); msq->q_cbytes = msq->q_qnum = 0; msq->q_qbytes = msg_ctlmnb; msq->q_lspid = msq->q_lrpid = 0; INIT_LIST_HEAD(&msq->q_messages); INIT_LIST_HEAD(&msq->q_receivers); INIT_LIST_HEAD(&msq->q_senders); msg_unlock(msq); return msg_buildid(id,msq->q_perm.seq); }
/* * freeque() wakes up waiters on the sender and receiver waiting queue, * removes the message queue from message queue ID * array, and cleans up all the messages associated with this queue. * * msg_ids.sem and the spinlock for this message queue is hold * before freeque() is called. msg_ids.sem remains locked on exit. */ static void freeque (struct msg_queue *msq, int id) { struct list_head *tmp; expunge_all(msq,-EIDRM); ss_wakeup(&msq->q_senders,1); msq = msg_rmid(id); msg_unlock(msq); tmp = msq->q_messages.next; while(tmp != &msq->q_messages) { struct msg_msg* msg = list_entry(tmp,struct msg_msg,m_list); tmp = tmp->next; atomic_dec(&msg_hdrs); free_msg(msg); } atomic_sub(msq->q_cbytes, &msg_bytes); security_msg_queue_free(msq); ipc_rcu_free(msq, sizeof(struct msg_queue)); }