[PATCH] [2/6] kfifo: Make kfifo_in atomic

From: Andi Kleen
Date: Sun Dec 27 2009 - 16:03:36 EST



Right now kfifo_in allows copying in less than the input
amount. This is unfortunately not a good idea on any
record oriented users: if the size of the kfifo is not
a multiple of the record (and that can easily happen due
to the power-of-two requirement) then when the FIFO fills
up partial records could be put in. Such a condition would
be fatal for any record consumer who would get permanently
desynchronized. In fact I doubt unless the input
is a totally boundary less data stream I doubt anything
could handle this.

Change kfifo_in() to always put in everything or nothing.

The return value is now always 0 or the full length.

Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>

---
kernel/kfifo.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

Index: linux/kernel/kfifo.c
===================================================================
--- linux.orig/kernel/kfifo.c
+++ linux/kernel/kfifo.c
@@ -228,9 +228,8 @@ EXPORT_SYMBOL(__kfifo_in_n);
* @from: the data to be added.
* @len: the length of the data to be added.
*
- * This function copies at most @len bytes from the @from buffer into
- * the FIFO depending on the free space, and returns the number of
- * bytes copied.
+ * This function copies @len bytes from the @from buffer into
+ * the FIFO and returns 0 if there is not enough space.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these functions.
@@ -238,8 +237,8 @@ EXPORT_SYMBOL(__kfifo_in_n);
unsigned int kfifo_in(struct kfifo *fifo, const void *from,
unsigned int len)
{
- len = min(kfifo_avail(fifo), len);
-
+ if (kfifo_avail(fifo) < len)
+ return 0;
__kfifo_in_data(fifo, from, len, 0);
__kfifo_add_in(fifo, len);
return len;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/