Inject failures into usercopies. Index: linux-2.6/mm/filemap.c =================================================================== --- linux-2.6.orig/mm/filemap.c +++ linux-2.6/mm/filemap.c @@ -107,6 +107,13 @@ generic_file_direct_IO(int rw, struct ki * ->dcache_lock (proc_pid_lookup) */ +static int failcnt; +static int FAIL(int x) +{ + failcnt++; + return (failcnt % x == 0); +} + /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage @@ -2307,6 +2314,7 @@ static ssize_t generic_perform_write_2co goto fs_write_aop_error; if (!src_page) { + int tmp; /* * Must not enter the pagefault handler here, because * we hold the page lock, so we might recursively @@ -2320,9 +2328,17 @@ static ssize_t generic_perform_write_2co * marked dirty and written out to disk, it doesn't * really matter. */ + + tmp = bytes; + if (!segment_eq(get_fs(), KERNEL_DS)) { + if (FAIL(13)) + tmp = tmp / 2; + if (FAIL(17)) + tmp = 0; + } pagefault_disable(); copied = iov_iter_copy_from_user_atomic(page, i, - offset, bytes); + offset, tmp); pagefault_enable(); } else { void *src, *dst; @@ -2394,6 +2410,7 @@ static ssize_t generic_perform_write(str pgoff_t index; /* Pagecache index for current page */ unsigned long offset; /* Offset into pagecache page */ unsigned long bytes; /* Bytes to write to page */ + int tmp; size_t copied; /* Bytes copied from user */ void *fsdata; @@ -2424,8 +2441,16 @@ again: if (unlikely(status)) break; + tmp = bytes; + if (!(flags & AOP_FLAG_UNINTERRUPTIBLE)) { + if (FAIL(13)) + tmp = tmp / 2; + if (FAIL(17)) + tmp = 0; + } + pagefault_disable(); - copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); + copied = iov_iter_copy_from_user_atomic(page, i, offset, tmp); pagefault_enable(); flush_dcache_page(page);