--- linux-2.4.26/mm/memory.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.26/mm/memory-2.c 2004-05-11 13:48:10.000000000 +0200 @@ -563,12 +563,19 @@ err = get_user_pages(current, mm, va, pgcount, (rw==READ), 0, iobuf->maplist, NULL); up_read(&mm->mmap_sem); - if (err < 0) { + /* get_user_pages returns the amount of mapped pages, + * which can be less than the amount of requested pages + * in some cases. To avoid surprises downstream, we + * unmap and return an error in those cases. -bjornw + */ + if(err > 0) + iobuf->nr_pages = err; + if (err < pgcount) { + /* unmap depends on nr_pages being set at this point */ unmap_kiobuf(iobuf); dprintk ("map_user_kiobuf: end %d\n", err); - return err; + return err < 0 ? err : -ENOMEM; } - iobuf->nr_pages = err; while (pgcount--) { /* FIXME: flush superflous for rw==READ, * probably wrong function for rw==WRITE