diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2010-02-26 10:53:24 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2010-03-11 09:58:25 -0500 |
commit | 4aa83b7bf122106669346eef40632289f540653f (patch) | |
tree | 677f5e630c645c41eade94d90623e93672e08564 /drivers | |
parent | cf14c2e987ba0a09a7b09be2ecd55af0bc9c17b4 (diff) |
drbd: fix NULL pointer dereference on 4k hard sect size
we still don't support 4k 'physical' sectors 'natively',
but use a read-modify-write workaround.
And we even tried to use the extra page before we allocated it :(
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 4df3b40b1057..d53d36cd0e57 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
941 | 941 | ||
942 | drbd_md_set_sector_offsets(mdev, nbc); | 942 | drbd_md_set_sector_offsets(mdev, nbc); |
943 | 943 | ||
944 | /* allocate a second IO page if logical_block_size != 512 */ | ||
945 | logical_block_size = bdev_logical_block_size(nbc->md_bdev); | ||
946 | if (logical_block_size == 0) | ||
947 | logical_block_size = MD_SECTOR_SIZE; | ||
948 | |||
949 | if (logical_block_size != MD_SECTOR_SIZE) { | ||
950 | if (!mdev->md_io_tmpp) { | ||
951 | struct page *page = alloc_page(GFP_NOIO); | ||
952 | if (!page) | ||
953 | goto force_diskless_dec; | ||
954 | |||
955 | dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", | ||
956 | logical_block_size, MD_SECTOR_SIZE); | ||
957 | dev_warn(DEV, "Workaround engaged (has performance impact).\n"); | ||
958 | |||
959 | mdev->md_io_tmpp = page; | ||
960 | } | ||
961 | } | ||
962 | |||
944 | if (!mdev->bitmap) { | 963 | if (!mdev->bitmap) { |
945 | if (drbd_bm_init(mdev)) { | 964 | if (drbd_bm_init(mdev)) { |
946 | retcode = ERR_NOMEM; | 965 | retcode = ERR_NOMEM; |
@@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
980 | goto force_diskless_dec; | 999 | goto force_diskless_dec; |
981 | } | 1000 | } |
982 | 1001 | ||
983 | /* allocate a second IO page if logical_block_size != 512 */ | ||
984 | logical_block_size = bdev_logical_block_size(nbc->md_bdev); | ||
985 | if (logical_block_size == 0) | ||
986 | logical_block_size = MD_SECTOR_SIZE; | ||
987 | |||
988 | if (logical_block_size != MD_SECTOR_SIZE) { | ||
989 | if (!mdev->md_io_tmpp) { | ||
990 | struct page *page = alloc_page(GFP_NOIO); | ||
991 | if (!page) | ||
992 | goto force_diskless_dec; | ||
993 | |||
994 | dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", | ||
995 | logical_block_size, MD_SECTOR_SIZE); | ||
996 | dev_warn(DEV, "Workaround engaged (has performance impact).\n"); | ||
997 | |||
998 | mdev->md_io_tmpp = page; | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | /* Reset the "barriers don't work" bits here, then force meta data to | 1002 | /* Reset the "barriers don't work" bits here, then force meta data to |
1003 | * be written, to ensure we determine if barriers are supported. */ | 1003 | * be written, to ensure we determine if barriers are supported. */ |
1004 | if (nbc->dc.no_md_flush) | 1004 | if (nbc->dc.no_md_flush) |