Commit c334f752 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] posix message queues: code move

From: Manfred Spraul <manfred@colorfullife.com>

cleanup of sysv ipc as a preparation for posix message queues:

- replace !CONFIG_SYSVIPC wrappers for copy_semundo and exit_sem with
  static inline wrappers.  Now the whole ipc/util.c file is only used if
  CONFIG_SYSVIPC is set, use makefile magic instead of #ifdef.

- remove the prototypes for copy_semundo and exit_sem from kernel/fork.c

- they belong into a header file.

- create a new msgutil.c with the helper functions for message queues.

- cleanup the helper functions: run Lindent, add __user tags.
parent 00d1b0e9
......@@ -74,9 +74,6 @@ struct msg_msg {
/* the actual message follows immediately */
};
#define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg))
#define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg))
/* one msq_queue structure for each present queue on the system */
struct msg_queue {
struct kern_ipc_perm q_perm;
......
......@@ -134,7 +134,22 @@ struct sysv_sem {
struct sem_undo_list *undo_list;
};
void exit_sem(struct task_struct *p);
#ifdef CONFIG_SYSVIPC
extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
extern void exit_sem(struct task_struct *tsk);
#else
static inline int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
{
return 0;
}
static inline void exit_sem(struct task_struct *tsk)
{
return;
}
#endif
#endif /* __KERNEL__ */
......
......@@ -2,7 +2,5 @@
# Makefile for the linux ipc.
#
obj-y := util.o
obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
obj-$(CONFIG_SYSVIPC) += msg.o sem.o shm.o
obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
......@@ -51,11 +51,6 @@ struct msg_sender {
struct task_struct* tsk;
};
struct msg_msgseg {
struct msg_msgseg* next;
/* the next part of the message follows immediately */
};
#define SEARCH_ANY 1
#define SEARCH_EQUAL 2
#define SEARCH_NOTEQUAL 3
......@@ -129,106 +124,6 @@ static int newque (key_t key, int msgflg)
return msg_buildid(id,msq->q_perm.seq);
}
static void free_msg(struct msg_msg* msg)
{
struct msg_msgseg* seg;
security_msg_msg_free(msg);
seg = msg->next;
kfree(msg);
while(seg != NULL) {
struct msg_msgseg* tmp = seg->next;
kfree(seg);
seg = tmp;
}
}
static struct msg_msg* load_msg(void* src, int len)
{
struct msg_msg* msg;
struct msg_msgseg** pseg;
int err;
int alen;
alen = len;
if(alen > DATALEN_MSG)
alen = DATALEN_MSG;
msg = (struct msg_msg *) kmalloc (sizeof(*msg) + alen, GFP_KERNEL);
if(msg==NULL)
return ERR_PTR(-ENOMEM);
msg->next = NULL;
msg->security = NULL;
if (copy_from_user(msg+1, src, alen)) {
err = -EFAULT;
goto out_err;
}
len -= alen;
src = ((char*)src)+alen;
pseg = &msg->next;
while(len > 0) {
struct msg_msgseg* seg;
alen = len;
if(alen > DATALEN_SEG)
alen = DATALEN_SEG;
seg = (struct msg_msgseg *) kmalloc (sizeof(*seg) + alen, GFP_KERNEL);
if(seg==NULL) {
err=-ENOMEM;
goto out_err;
}
*pseg = seg;
seg->next = NULL;
if(copy_from_user (seg+1, src, alen)) {
err = -EFAULT;
goto out_err;
}
pseg = &seg->next;
len -= alen;
src = ((char*)src)+alen;
}
err = security_msg_msg_alloc(msg);
if (err)
goto out_err;
return msg;
out_err:
free_msg(msg);
return ERR_PTR(err);
}
static int store_msg(void* dest, struct msg_msg* msg, int len)
{
int alen;
struct msg_msgseg *seg;
alen = len;
if(alen > DATALEN_MSG)
alen = DATALEN_MSG;
if(copy_to_user (dest, msg+1, alen))
return -1;
len -= alen;
dest = ((char*)dest)+alen;
seg = msg->next;
while(len > 0) {
alen = len;
if(alen > DATALEN_SEG)
alen = DATALEN_SEG;
if(copy_to_user (dest, seg+1, alen))
return -1;
len -= alen;
dest = ((char*)dest)+alen;
seg=seg->next;
}
return 0;
}
static inline void ss_add(struct msg_queue* msq, struct msg_sender* mss)
{
mss->tsk=current;
......
/*
* linux/ipc/util.c
* Copyright (C) 1999, 2004 Manfred Spraul
*
* This file is released under GNU General Public Licence version 2 or
* (at your option) any later version.
*
* See the file COPYING for more details.
*/
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/ipc.h>
#include <asm/uaccess.h>
#include "util.h"
struct msg_msgseg {
struct msg_msgseg* next;
/* the next part of the message follows immediately */
};
#define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg))
#define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg))
struct msg_msg *load_msg(void __user *src, int len)
{
struct msg_msg *msg;
struct msg_msgseg **pseg;
int err;
int alen;
alen = len;
if (alen > DATALEN_MSG)
alen = DATALEN_MSG;
msg = (struct msg_msg *)kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
if (msg == NULL)
return ERR_PTR(-ENOMEM);
msg->next = NULL;
msg->security = NULL;
if (copy_from_user(msg + 1, src, alen)) {
err = -EFAULT;
goto out_err;
}
len -= alen;
src = ((char *)src) + alen;
pseg = &msg->next;
while (len > 0) {
struct msg_msgseg *seg;
alen = len;
if (alen > DATALEN_SEG)
alen = DATALEN_SEG;
seg = (struct msg_msgseg *)kmalloc(sizeof(*seg) + alen,
GFP_KERNEL);
if (seg == NULL) {
err = -ENOMEM;
goto out_err;
}
*pseg = seg;
seg->next = NULL;
if (copy_from_user(seg + 1, src, alen)) {
err = -EFAULT;
goto out_err;
}
pseg = &seg->next;
len -= alen;
src = ((char *)src) + alen;
}
err = security_msg_msg_alloc(msg);
if (err)
goto out_err;
return msg;
out_err:
free_msg(msg);
return ERR_PTR(err);
}
int store_msg(void __user *dest, struct msg_msg *msg, int len)
{
int alen;
struct msg_msgseg *seg;
alen = len;
if (alen > DATALEN_MSG)
alen = DATALEN_MSG;
if (copy_to_user(dest, msg + 1, alen))
return -1;
len -= alen;
dest = ((char *)dest) + alen;
seg = msg->next;
while (len > 0) {
alen = len;
if (alen > DATALEN_SEG)
alen = DATALEN_SEG;
if (copy_to_user(dest, seg + 1, alen))
return -1;
len -= alen;
dest = ((char *)dest) + alen;
seg = seg->next;
}
return 0;
}
void free_msg(struct msg_msg *msg)
{
struct msg_msgseg *seg;
security_msg_msg_free(msg);
seg = msg->next;
kfree(msg);
while (seg != NULL) {
struct msg_msgseg *tmp = seg->next;
kfree(seg);
seg = tmp;
}
}
......@@ -25,8 +25,6 @@
#include <linux/rcupdate.h>
#include <linux/workqueue.h>
#if defined(CONFIG_SYSVIPC)
#include "util.h"
/**
......@@ -531,20 +529,3 @@ int ipc_parse_version (int *cmd)
}
#endif /* __ia64__ */
#else
/*
* Dummy functions when SYSV IPC isn't configured
*/
int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
{
return 0;
}
void exit_sem(struct task_struct *tsk)
{
return;
}
#endif /* CONFIG_SYSVIPC */
......@@ -4,6 +4,10 @@
*
* ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
*/
#ifndef _IPC_UTIL_H
#define _IPC_UTIL_H
#define USHRT_MAX 0xffff
#define SEQ_MULTIPLIER (IPCMNI)
......@@ -62,3 +66,9 @@ void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
#else
int ipc_parse_version (int *cmd);
#endif
extern void free_msg(struct msg_msg *msg);
extern struct msg_msg *load_msg(void __user *src, int len);
extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
#endif
......@@ -21,6 +21,7 @@
#include <linux/completion.h>
#include <linux/namespace.h>
#include <linux/personality.h>
#include <linux/sem.h>
#include <linux/file.h>
#include <linux/binfmts.h>
#include <linux/mman.h>
......@@ -39,9 +40,6 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
extern void exit_sem(struct task_struct *tsk);
/* The idle threads do not count..
* Protected by write_lock_irq(&tasklist_lock)
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment