* [PATCH] 1/2 POSIX message queues
@ 2003-11-25 11:40 Michal Wronski
2003-11-25 13:29 ` Brian Pawlowski
0 siblings, 1 reply; 3+ messages in thread
From: Michal Wronski @ 2003-11-25 11:40 UTC (permalink / raw)
To: linux-kernel; +Cc: Krzysztof Benedyczak
Here is improved version of mqueues (against 2.6.0-test10).
As suggested it is split into two patches.
The first one moves free/load/store_msg from msg.c to util.c
The second one contains mqueues specific code.
We have applied some fixes and added support for sysctls. Each parameter
is now tunable. Global limit for messages size was removed.
Also there are some changes taken from J. Korty patch to make this code
more arch portable.
New library is available at:
http://www.mat.uni.torun.pl/~wrona/posix_ipc
Regards,
Michal
diff -urN 2.6.0-test10-orig_1/ipc/msg.c 2.6.0-test10-patched_1/ipc/msg.c
--- 2.6.0-test10-orig_1/ipc/msg.c 2003-11-07 17:07:13.000000000 +0100
+++ 2.6.0-test10-patched_1/ipc/msg.c 2003-11-21 17:11:17.000000000 +0100
@@ -51,11 +51,6 @@
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 @@
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;
diff -urN 2.6.0-test10-orig_1/ipc/util.c 2.6.0-test10-patched_1/ipc/util.c
--- 2.6.0-test10-orig_1/ipc/util.c 2003-11-07 17:07:13.000000000 +0100
+++ 2.6.0-test10-patched_1/ipc/util.c 2003-11-21 17:11:17.000000000 +0100
@@ -611,3 +611,107 @@
}
#endif /* CONFIG_SYSVIPC */
+
+#ifdef CONFIG_SYSVIPC
+
+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;
+ }
+}
+
+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);
+}
+
+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;
+}
+
+#endif /* CONFIG_SYSVIPC */
diff -urN 2.6.0-test10-orig_1/ipc/util.h 2.6.0-test10-patched_1/ipc/util.h
--- 2.6.0-test10-orig_1/ipc/util.h 2003-11-07 17:07:13.000000000 +0100
+++ 2.6.0-test10-patched_1/ipc/util.h 2003-11-21 17:11:17.000000000 +0100
@@ -25,6 +25,16 @@
struct kern_ipc_perm* p;
};
+struct msg_msgseg {
+ struct msg_msgseg* next;
+ /* the next part of the message follows immediately */
+};
+
+void free_msg(struct msg_msg* msg);
+struct msg_msg* load_msg(void* src, int len);
+int store_msg(void* dest, struct msg_msg* msg, int len);
+
+
void __init ipc_init_ids(struct ipc_ids* ids, int size);
/* must be called with ids->sem acquired.*/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] 1/2 POSIX message queues
2003-11-25 11:40 [PATCH] 1/2 POSIX message queues Michal Wronski
@ 2003-11-25 13:29 ` Brian Pawlowski
0 siblings, 0 replies; 3+ messages in thread
From: Brian Pawlowski @ 2003-11-25 13:29 UTC (permalink / raw)
To: Michal Wronski; +Cc: linux-kernel, golbi
And in teh end, satisfying Torvalds is all up to Tove.
> Here is improved version of mqueues (against 2.6.0-test10).
> As suggested it is split into two patches.
> The first one moves free/load/store_msg from msg.c to util.c
> The second one contains mqueues specific code.
>
> We have applied some fixes and added support for sysctls. Each parameter
> is now tunable. Global limit for messages size was removed.
> Also there are some changes taken from J. Korty patch to make this code
> more arch portable.
>
> New library is available at:
> http://www.mat.uni.torun.pl/~wrona/posix_ipc
>
> Regards,
> Michal
>
>
>
> diff -urN 2.6.0-test10-orig_1/ipc/msg.c 2.6.0-test10-patched_1/ipc/msg.c
> --- 2.6.0-test10-orig_1/ipc/msg.c 2003-11-07 17:07:13.000000000 +0100
> +++ 2.6.0-test10-patched_1/ipc/msg.c 2003-11-21 17:11:17.000000000 +0100
> @@ -51,11 +51,6 @@
> 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 @@
> 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;
> diff -urN 2.6.0-test10-orig_1/ipc/util.c 2.6.0-test10-patched_1/ipc/util.c
> --- 2.6.0-test10-orig_1/ipc/util.c 2003-11-07 17:07:13.000000000 +0100
> +++ 2.6.0-test10-patched_1/ipc/util.c 2003-11-21 17:11:17.000000000 +0100
> @@ -611,3 +611,107 @@
> }
>
> #endif /* CONFIG_SYSVIPC */
> +
> +#ifdef CONFIG_SYSVIPC
> +
> +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;
> + }
> +}
> +
> +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);
> +}
> +
> +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;
> +}
> +
> +#endif /* CONFIG_SYSVIPC */
> diff -urN 2.6.0-test10-orig_1/ipc/util.h 2.6.0-test10-patched_1/ipc/util.h
> --- 2.6.0-test10-orig_1/ipc/util.h 2003-11-07 17:07:13.000000000 +0100
> +++ 2.6.0-test10-patched_1/ipc/util.h 2003-11-21 17:11:17.000000000 +0100
> @@ -25,6 +25,16 @@
> struct kern_ipc_perm* p;
> };
>
> +struct msg_msgseg {
> + struct msg_msgseg* next;
> + /* the next part of the message follows immediately */
> +};
> +
> +void free_msg(struct msg_msg* msg);
> +struct msg_msg* load_msg(void* src, int len);
> +int store_msg(void* dest, struct msg_msg* msg, int len);
> +
> +
> void __init ipc_init_ids(struct ipc_ids* ids, int size);
>
> /* must be called with ids->sem acquired.*/
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] [1/2] posix message queues
@ 2003-10-03 15:57 Peter Wächtler
0 siblings, 0 replies; 3+ messages in thread
From: Peter Wächtler @ 2003-10-03 15:57 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, torvalds, bo.z.li, manfred
[-- Attachment #1: Type: text/plain, Size: 576 bytes --]
I was made aware that OSDL wants to include a Posix mqueue
implementation for 2.6
The following patchset includes that.
[1/2] splits up ipc/msg.c and ipc/util.c so that code can be shared
between SySV and Posix mqueues
I renamed store_msg/load_msg to put_msg/get_msg for better reading
and removed some signed/unsigned warnings
[2/2] implements the interface in ipc/posixmsg.c through a set of
new syscalls and a new pseudo filesystem msgfs
the implementation passes the posixtestsuite 1.2 and has SIGEV_THREAD
support through userspace (taken from Benedyczak,Wronski)
[-- Attachment #2: Type: text/plain, Size: 7512 bytes --]
diff -X dontdiff -Nur vanilla-2.6.0-test6/ipc/msg.c linux-2.6.0-test6/ipc/msg.c
--- vanilla-2.6.0-test6/ipc/msg.c 2003-09-24 22:41:47.000000000 +0200
+++ linux-2.6.0-test6/ipc/msg.c 2003-10-03 13:28:08.000000000 +0200
@@ -33,29 +33,6 @@
int msg_ctlmnb = MSGMNB;
int msg_ctlmni = MSGMNI;
-/* one msg_receiver structure for each sleeping receiver */
-struct msg_receiver {
- struct list_head r_list;
- struct task_struct* r_tsk;
-
- int r_mode;
- long r_msgtype;
- long r_maxsize;
-
- struct msg_msg* volatile r_msg;
-};
-
-/* one msg_sender for each sleeping sender */
-struct msg_sender {
- struct list_head list;
- 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 +106,6 @@
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;
@@ -657,7 +534,7 @@
if (mtype < 1)
return -EINVAL;
- msg = load_msg(msgp->mtext, msgsz);
+ msg = get_msg(msgp->mtext, msgsz);
if(IS_ERR(msg))
return PTR_ERR(msg);
@@ -810,7 +687,7 @@
out_success:
msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
if (put_user (msg->m_type, &msgp->mtype) ||
- store_msg(msgp->mtext, msg, msgsz)) {
+ put_msg(msgp->mtext, msg, msgsz)) {
msgsz = -EFAULT;
}
free_msg(msg);
diff -X dontdiff -Nur vanilla-2.6.0-test6/ipc/util.c linux-2.6.0-test6/ipc/util.c
--- vanilla-2.6.0-test6/ipc/util.c 2003-09-24 22:41:47.000000000 +0200
+++ linux-2.6.0-test6/ipc/util.c 2003-10-03 14:58:35.000000000 +0200
@@ -85,6 +86,126 @@
}
/**
+ * get_msg - fetches a msg from userspace and copies it into kernel space
+ * @src: user pointer to read from
+ * @len: length of msg
+ *
+ * returns the newly kmalloc'ed address of the message
+ */
+struct msg_msg* get_msg(void* src, int len)
+{
+ struct msg_msg* msg;
+ struct msg_msgseg** pseg;
+ int err;
+ int alen;
+
+ alen = len;
+ if(alen > (int)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 > (int)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);
+}
+
+/**
+ * put_msg - copies a msg to userspace
+ * @dest: user space pointer to destination buffer
+ * @msg: message to copy
+ * @len: length of the buffer
+ *
+ * returns 0 on success and -1 on error
+ */
+int put_msg(void* dest, struct msg_msg* msg, int len)
+{
+ int alen;
+ struct msg_msgseg *seg;
+
+ alen = len;
+ if(alen > (int)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 > (int)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;
+}
+
+/**
+ * free_msg - frees the msg formerly stored by get_msg
+ * @msg: message to free
+ *
+ */
+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;
+ }
+}
+
+/**
* ipc_findkey - find a key in an ipc identifier set
* @ids: Identifier set
* @key: The key to find
@@ -253,7 +374,7 @@
void* ipc_alloc(int size)
{
void* out;
- if(size > PAGE_SIZE)
+ if(size > (int)PAGE_SIZE)
out = vmalloc(size);
else
out = kmalloc(size, GFP_KERNEL);
@@ -271,7 +392,7 @@
void ipc_free(void* ptr, int size)
{
- if(size > PAGE_SIZE)
+ if(size > (int)PAGE_SIZE)
vfree(ptr);
else
kfree(ptr);
@@ -504,7 +625,7 @@
int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
{
- if(uid/SEQ_MULTIPLIER != ipcp->seq)
+ if((unsigned long)uid/SEQ_MULTIPLIER != ipcp->seq)
return 1;
return 0;
}
diff -X dontdiff -Nur vanilla-2.6.0-test6/ipc/util.h linux-2.6.0-test6/ipc/util.h
--- vanilla-2.6.0-test6/ipc/util.h 2003-08-23 01:56:56.000000000 +0200
+++ linux-2.6.0-test6/ipc/util.h 2003-10-01 00:18:39.000000000 +0200
@@ -25,6 +25,32 @@
struct kern_ipc_perm* p;
};
+/* one msg_receiver structure for each sleeping receiver */
+struct msg_receiver {
+ struct list_head r_list;
+ struct task_struct* r_tsk;
+
+ int r_mode;
+ long r_msgtype;
+ long r_maxsize;
+
+ struct msg_msg* volatile r_msg;
+};
+
+/* one msg_sender for each sleeping sender */
+struct msg_sender {
+ struct list_head list;
+ struct task_struct* tsk;
+};
+
+struct msg_msgseg {
+ struct msg_msgseg* next;
+ /* the next part of the message follows immediately */
+};
+struct msg_msg* get_msg(void* src, int len);
+int put_msg(void* dest, struct msg_msg* msg, int len);
+void free_msg(struct msg_msg* msg);
+
void __init ipc_init_ids(struct ipc_ids* ids, int size);
/* must be called with ids->sem acquired.*/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-11-25 13:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-25 11:40 [PATCH] 1/2 POSIX message queues Michal Wronski
2003-11-25 13:29 ` Brian Pawlowski
-- strict thread matches above, loose matches on Subject: below --
2003-10-03 15:57 [PATCH] [1/2] posix " Peter Wächtler
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®