summaryrefslogtreecommitdiff
path: root/fs/buffer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-01-14 13:17:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-14 13:17:50 -0800
commit6d283dba3721cc43be014b50a1acc2f35860a65a (patch)
tree3cedf3afca0bf3e63ad6b156e5b54b41c625de51 /fs/buffer.c
parent9bbcbad438dbdeb5103466f2b1619f7b11a4a154 (diff)
downloadlinux-3.10-6d283dba3721cc43be014b50a1acc2f35860a65a.tar.gz
linux-3.10-6d283dba3721cc43be014b50a1acc2f35860a65a.tar.bz2
linux-3.10-6d283dba3721cc43be014b50a1acc2f35860a65a.zip
vfs: add missing virtual cache flush after editing partial pages
Andrew Morton pointed this out a month ago, and then I completely forgot about it. If we read a partial last page of a block device, we will zero out the end of the page, but since that page can then be mapped into user space, we should also make sure to flush the cache on architectures that have virtual caches. We have the flush_dcache_page() function for this, so use it. Now, in practice this really never matters, because nobody sane uses virtual caches to begin with, and they largely exist on old broken RISC arhitectures. And even if you did run on one of those obsolete CPU's, the whole "mmap and access the last partial page of a block device" behavior probably doesn't actually exist. The normal IO functions (read/write) will never see the zeroed-out part of the page that migth not be coherent in the cache, because they honor the size of the device. So I'm marking this for stable (3.7 only), but I'm not sure anybody will ever care. Pointed-out-by: Andrew Morton <akpm@linux-foundation.org> Cc: stable@vger.kernel.org # 3.7 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index c017a2dfb90..7a75c3e0fd5 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2935,6 +2935,7 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
void *kaddr = kmap_atomic(bh->b_page);
memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes);
kunmap_atomic(kaddr);
+ flush_dcache_page(bh->b_page);
}
}