diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2013-11-22 07:22:13 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-07-10 09:22:20 -0400 |
commit | 8fe39aac0578cbb0abf27e1be70ff581e0c1d836 (patch) | |
tree | 3a3f8c724dec46a06ecf2d490905a3f6fbd80045 /drivers/block/drbd/drbd_int.h | |
parent | e952658020c5150ad4987d313e25e8e2fb38d529 (diff) |
drbd: device->ldev is not guaranteed on an D_ATTACHING disk
Some parts of the code assumed that get_ldev_if_state(device, D_ATTACHING)
is sufficient to access the ldev member of the device object. That was
wrong. ldev may not be there or might be freed at any time if the device
has a disk state of D_ATTACHING.
bm_rw()
Documented that drbd_bm_read() is only called from drbd_adm_attach.
drbd_bm_write() is only called when a reference is held, and it is
documented that a caller has to hold a reference before calling
drbd_bm_write()
drbd_bm_write_page()
Use get_ldev() instead of get_ldev_if_state(device, D_ATTACHING)
drbd_bmio_set_n_write()
No longer use get_ldev_if_state(device, D_ATTACHING). All callers
hold a reference to ldev now.
drbd_bmio_clear_n_write()
All callers where holding a reference of ldev anyways. Remove the
misleading get_ldev_if_state(device, D_ATTACHING)
drbd_reconsider_max_bio_size()
Removed the get_ldev_if_state(device, D_ATTACHING). All callers
now pass a struct drbd_backing_dev* when they have a proper
reference, or a NULL pointer.
Before this fix, the receiver could trigger a NULL pointer
deref when in drbd_reconsider_max_bio_size()
drbd_bump_write_ordering()
Used get_ldev_if_state(device, D_ATTACHING) with the wrong assumption.
Remove it, and allow the caller to pass in a struct drbd_backing_dev*
when the caller knows that accessing this bdev is safe.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 1ef2474e8f11..c87bc8e8fd82 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -984,8 +984,8 @@ extern int drbd_bitmap_io(struct drbd_device *device, | |||
984 | extern int drbd_bitmap_io_from_worker(struct drbd_device *device, | 984 | extern int drbd_bitmap_io_from_worker(struct drbd_device *device, |
985 | int (*io_fn)(struct drbd_device *), | 985 | int (*io_fn)(struct drbd_device *), |
986 | char *why, enum bm_flag flags); | 986 | char *why, enum bm_flag flags); |
987 | extern int drbd_bmio_set_n_write(struct drbd_device *device); | 987 | extern int drbd_bmio_set_n_write(struct drbd_device *device) __must_hold(local); |
988 | extern int drbd_bmio_clear_n_write(struct drbd_device *device); | 988 | extern int drbd_bmio_clear_n_write(struct drbd_device *device) __must_hold(local); |
989 | extern void drbd_ldev_destroy(struct drbd_device *device); | 989 | extern void drbd_ldev_destroy(struct drbd_device *device); |
990 | 990 | ||
991 | /* Meta data layout | 991 | /* Meta data layout |
@@ -1313,7 +1313,7 @@ enum determine_dev_size { | |||
1313 | extern enum determine_dev_size | 1313 | extern enum determine_dev_size |
1314 | drbd_determine_dev_size(struct drbd_device *, enum dds_flags, struct resize_parms *) __must_hold(local); | 1314 | drbd_determine_dev_size(struct drbd_device *, enum dds_flags, struct resize_parms *) __must_hold(local); |
1315 | extern void resync_after_online_grow(struct drbd_device *); | 1315 | extern void resync_after_online_grow(struct drbd_device *); |
1316 | extern void drbd_reconsider_max_bio_size(struct drbd_device *device); | 1316 | extern void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev); |
1317 | extern enum drbd_state_rv drbd_set_role(struct drbd_device *device, | 1317 | extern enum drbd_state_rv drbd_set_role(struct drbd_device *device, |
1318 | enum drbd_role new_role, | 1318 | enum drbd_role new_role, |
1319 | int force); | 1319 | int force); |
@@ -1479,7 +1479,8 @@ static inline void drbd_generic_make_request(struct drbd_device *device, | |||
1479 | generic_make_request(bio); | 1479 | generic_make_request(bio); |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | void drbd_bump_write_ordering(struct drbd_resource *resource, enum write_ordering_e wo); | 1482 | void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backing_dev *bdev, |
1483 | enum write_ordering_e wo); | ||
1483 | 1484 | ||
1484 | /* drbd_proc.c */ | 1485 | /* drbd_proc.c */ |
1485 | extern struct proc_dir_entry *drbd_proc; | 1486 | extern struct proc_dir_entry *drbd_proc; |