diff options
author | Ross Zwisler <ross.zwisler@linux.intel.com> | 2016-01-22 18:10:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-22 20:02:18 -0500 |
commit | eab95db69d334745d3034072f4a7204084136c88 (patch) | |
tree | 3d54065f19a096d64caaf90793ceec9d527060a2 /fs | |
parent | 5eb88dca9ce4546bdfca6e5defcd50fbe8ea8411 (diff) |
dax: never rely on bh.b_dev being set by get_block()
Previously in DAX we assumed that calls to get_block() would set
bh.b_bdev, and we would then use that value even in error cases for
debugging. This caused a NULL pointer dereference in __dax_dbg() which
was fixed by a previous commit, but that commit only changed the one
place where we were hitting an error.
Instead, update dax.c so that we always initialize bh.b_bdev as best we
can based on the information that DAX has. get_block() may or may not
update to a new value, but this at least lets us get something helpful
from bh.b_bdev for error messages and not have to worry about whether it
was set by get_block() or not.
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reported-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dax.c | 3 |
1 files changed, 3 insertions, 0 deletions
@@ -246,6 +246,7 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode, | |||
246 | loff_t end = pos + iov_iter_count(iter); | 246 | loff_t end = pos + iov_iter_count(iter); |
247 | 247 | ||
248 | memset(&bh, 0, sizeof(bh)); | 248 | memset(&bh, 0, sizeof(bh)); |
249 | bh.b_bdev = inode->i_sb->s_bdev; | ||
249 | 250 | ||
250 | if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) { | 251 | if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) { |
251 | struct address_space *mapping = inode->i_mapping; | 252 | struct address_space *mapping = inode->i_mapping; |
@@ -607,6 +608,7 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
607 | 608 | ||
608 | memset(&bh, 0, sizeof(bh)); | 609 | memset(&bh, 0, sizeof(bh)); |
609 | block = (sector_t)vmf->pgoff << (PAGE_SHIFT - blkbits); | 610 | block = (sector_t)vmf->pgoff << (PAGE_SHIFT - blkbits); |
611 | bh.b_bdev = inode->i_sb->s_bdev; | ||
610 | bh.b_size = PAGE_SIZE; | 612 | bh.b_size = PAGE_SIZE; |
611 | 613 | ||
612 | repeat: | 614 | repeat: |
@@ -1078,6 +1080,7 @@ int dax_zero_page_range(struct inode *inode, loff_t from, unsigned length, | |||
1078 | BUG_ON((offset + length) > PAGE_CACHE_SIZE); | 1080 | BUG_ON((offset + length) > PAGE_CACHE_SIZE); |
1079 | 1081 | ||
1080 | memset(&bh, 0, sizeof(bh)); | 1082 | memset(&bh, 0, sizeof(bh)); |
1083 | bh.b_bdev = inode->i_sb->s_bdev; | ||
1081 | bh.b_size = PAGE_CACHE_SIZE; | 1084 | bh.b_size = PAGE_CACHE_SIZE; |
1082 | err = get_block(inode, index, &bh, 0); | 1085 | err = get_block(inode, index, &bh, 0); |
1083 | if (err < 0) | 1086 | if (err < 0) |