Fix zero_user_segments() with start > end
Subsystems (2)
PATCH v2 1/1 Fix zero_user_segments() with start > end
zero_user_segments() is used from __block_write_begin_int(), for example like the following
zero_user_segments(page, 4096, 1024, 512, 918)
But new zero_user_segments() implements for HIGMEM + TRANSPARENT_HUGEPAGE doesn't handle "start > end" case correctly, and hits BUG_ON(). (we can fix __block_write_begin_int() instead though, it is the old and multiple usage)
Also it calls kmap_atomic() unnecessary while start == end == 0.
Fixes 0060ef3b4e6d ("mm: support THPs in zero_user_segments")
Cc <[email protected]>
Signed-off-by OGAWA Hirofumi <[email protected]>
--- mm/highmem.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
mm/highmem.c +12 -5
@@ -368,20 +368,24 @@ void zero_user_segments(struct page *pagBUG_ON (end1 >page_size (page) || end2 >page_size (page)); +if (start1 >= end1) + start1 = end1 =0 ; +if (start2 >= end2) + start2 = end2 =0 ; +for (i =0 ; i <compound_nr (page); i++) {void *kaddr =NULL ; -if (start1 <PAGE_SIZE || start2 <PAGE_SIZE ) - kaddr =kmap_atomic (page + i); -if (start1 >=PAGE_SIZE ) { start1 -=PAGE_SIZE ; end1 -=PAGE_SIZE ; }else {unsigned this_end =min_t (unsigned, end1,PAGE_SIZE ); -if (end1 > start1) +if (end1 > start1) { + kaddr =kmap_atomic (page + i);memset (kaddr + start1,0 , this_end - start1); + } end1 -= this_end; start1 =0 ; }
@@ -392,8 +396,11 @@ void zero_user_segments(struct page *pag }else {unsigned this_end =min_t (unsigned, end2,PAGE_SIZE ); -if (end2 > start2) +if (end2 > start2) { +if (!kaddr) + kaddr =kmap_atomic (page + i);memset (kaddr + start2,0 , this_end - start2); + } end2 -= this_end; start2 =0 ; }
_
Signature · 1 line
OGAWA Hirofumi <[email protected]>