diff -Nru linux-2.4.20/mm/memory.c.orig linux-2.4.20/mm/memory.c --- linux-2.4.20/mm/memory.c.orig 2003-04-01 16:33:48.000000000 -0800 +++ linux-2.4.20/mm/memory.c 2003-04-01 16:41:34.000000000 -0800 @@ -553,6 +553,7 @@ if (err) return err; + iobuf->rw = rw; iobuf->locked = 0; iobuf->offset = va & (PAGE_SIZE-1); iobuf->length = len; @@ -569,11 +570,10 @@ return err; } iobuf->nr_pages = err; - while (pgcount--) { - /* FIXME: flush superflous for rw==READ, - * probably wrong function for rw==WRITE - */ - flush_dcache_page(iobuf->maplist[pgcount]); + /* if rw==WRITE, get updated data before writing them to disk */ + if (rw==WRITE) { + while (pgcount--) + flush_dcache_page(iobuf->maplist[pgcount]); } dprintk ("map_user_kiobuf: end OK\n"); return 0; @@ -628,9 +628,10 @@ if (map) { if (iobuf->locked) UnlockPage(map); - /* FIXME: cache flush missing for rw==READ - * FIXME: call the correct reference counting function - */ + /* if rw==READ, flush dcache before user uses data */ + if (iobuf->rw==READ) { + flush_dcache_page(iobuf->maplist[i]); + } page_cache_release(map); } } diff -Nru linux-2.4.20/include/linux/iobuf.h.orig linux-2.4.20/include/linux/iobuf.h --- linux-2.4.20/include/linux/iobuf.h.orig 2002-11-28 15:53:15.000000000 -0800 +++ linux-2.4.20/include/linux/iobuf.h 2003-04-01 16:34:16.000000000 -0800 @@ -32,6 +32,7 @@ struct kiobuf { + int rw; /* mapped for READ or WRITE */ int nr_pages; /* Pages actually referenced */ int array_len; /* Space in the allocated lists */ int offset; /* Offset to start of valid data */