aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-07-31 19:45:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:42:48 -0400
commit737449236240e30a7bbe99f4d5586b8ed1416763 (patch)
tree288fbd38b6c0e250901e218037fae64e79a91f7a /mm/swapfile.c
parent192e501b0438bb0e1574179773537f84c4752e25 (diff)
swapfile: avoid dereferencing bd_disk during swap_entry_free for network storage
Commit b3a27d ("swap: Add swap slot free callback to block_device_operations") dereferences p->bdev->bd_disk but this is a NULL dereference if using swap-over-NFS. This patch checks SWP_BLKDEV on the swap_info_struct before dereferencing. With reference to this callback, Christoph Hellwig stated "Please just remove the callback entirely. It has no user outside the staging tree and was added clearly against the rules for that staging tree". This would also be my preference but there was not an obvious way of keeping zram in staging/ happy. Signed-off-by: Xiaotian Feng <dfeng@redhat.com> Signed-off-by: Mel Gorman <mgorman@suse.de> Acked-by: Rik van Riel <riel@redhat.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: David S. Miller <davem@davemloft.net> Cc: Eric B Munson <emunson@mgebm.net> Cc: Eric Paris <eparis@redhat.com> Cc: James Morris <jmorris@namei.org> Cc: Mel Gorman <mgorman@suse.de> Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Neil Brown <neilb@suse.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 7307fc928d7b..63958d60ecb0 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -549,7 +549,6 @@ static unsigned char swap_entry_free(struct swap_info_struct *p,
549 549
550 /* free if no reference */ 550 /* free if no reference */
551 if (!usage) { 551 if (!usage) {
552 struct gendisk *disk = p->bdev->bd_disk;
553 if (offset < p->lowest_bit) 552 if (offset < p->lowest_bit)
554 p->lowest_bit = offset; 553 p->lowest_bit = offset;
555 if (offset > p->highest_bit) 554 if (offset > p->highest_bit)
@@ -560,9 +559,12 @@ static unsigned char swap_entry_free(struct swap_info_struct *p,
560 nr_swap_pages++; 559 nr_swap_pages++;
561 p->inuse_pages--; 560 p->inuse_pages--;
562 frontswap_invalidate_page(p->type, offset); 561 frontswap_invalidate_page(p->type, offset);
563 if ((p->flags & SWP_BLKDEV) && 562 if (p->flags & SWP_BLKDEV) {
564 disk->fops->swap_slot_free_notify) 563 struct gendisk *disk = p->bdev->bd_disk;
565 disk->fops->swap_slot_free_notify(p->bdev, offset); 564 if (disk->fops->swap_slot_free_notify)
565 disk->fops->swap_slot_free_notify(p->bdev,
566 offset);
567 }
566 } 568 }
567 569
568 return usage; 570 return usage;