]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
LINUX: Detect NULL page during write_begin
authorAndrew Deason <adeason@sinenomine.net>
Thu, 5 Jul 2018 22:16:48 +0000 (17:16 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 27 Jul 2018 12:53:57 +0000 (08:53 -0400)
In afs_linux_write_begin, we call grab_cache_page_write_begin to get a
page to use for writing data when servicing a write into AFS. Under
low-memory conditions, this can return NULL if Linux cannot find a
free page to use. Currently, we always try to reference the page
returned, and so this causes a BUG.

To avoid this, check if grab_cache_page_write_begin returns NULL, and
just return -ENOMEM, like other callers of grab_cache_page_write_begin
do.

Linux's fault injection framework is useful for testing code paths
like these. The following settings made it possible to
somewhat-reliably exercise the relevant code path on a test RHEL7
system:

    # grep ^ /sys/kernel/debug/fail_page_alloc/*
    /sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem:Y
    /sys/kernel/debug/fail_page_alloc/ignore-gfp-wait:N
    /sys/kernel/debug/fail_page_alloc/interval:1
    /sys/kernel/debug/fail_page_alloc/min-order:0
    /sys/kernel/debug/fail_page_alloc/probability:100
    /sys/kernel/debug/fail_page_alloc/space:90
    /sys/kernel/debug/fail_page_alloc/task-filter:Y
    /sys/kernel/debug/fail_page_alloc/times:-1
    [...]

Reviewed-on: https://gerrit.openafs.org/13242
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 89e80c354c404dedc0e5197f99710db0e5e08767)

Change-Id: I37b4d1ebb1b76e435bb1c56a76d7e475f47f33de
Reviewed-on: https://gerrit.openafs.org/13243
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
src/afs/LINUX/osi_vnodeops.c

index 9a070f28f341881c11f6b845662657b9fe65166a..966e98a9d562a7e57ae79e22be0a6e243328c266 100644 (file)
@@ -3082,6 +3082,10 @@ afs_linux_write_begin(struct file *file, struct address_space *mapping,
     int code;
 
     page = grab_cache_page_write_begin(mapping, index, flags);
+    if (!page) {
+        return -ENOMEM;
+    }
+
     *pagep = page;
 
     code = afs_linux_prepare_write(file, page, from, from + len);