aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_int.h
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2010-05-14 11:10:48 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-05-17 20:01:23 -0400
commit45bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5 (patch)
treed95d27ea8e945fcda3427c50a5bc062c804c6eff /drivers/block/drbd/drbd_int.h
parent708d740ed8242b84eefc63df144313a7308c7de5 (diff)
drbd: Allow drbd_epoch_entries to use multiple bios.
This should allow for better performance if the lower level IO stack of the peers differs in limits exposed either via the queue, or via some merge_bvec_fn. 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.h90
1 files changed, 74 insertions, 16 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1bc86ddac38b..4b97f30bb7c6 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -740,18 +740,6 @@ enum epoch_event {
740 EV_CLEANUP = 32, /* used as flag */ 740 EV_CLEANUP = 32, /* used as flag */
741}; 741};
742 742
743struct drbd_epoch_entry {
744 struct drbd_work w;
745 struct drbd_conf *mdev;
746 struct bio *private_bio;
747 struct hlist_node colision;
748 sector_t sector;
749 unsigned int size;
750 unsigned int flags;
751 struct drbd_epoch *epoch;
752 u64 block_id;
753};
754
755struct drbd_wq_barrier { 743struct drbd_wq_barrier {
756 struct drbd_work w; 744 struct drbd_work w;
757 struct completion done; 745 struct completion done;
@@ -762,17 +750,49 @@ struct digest_info {
762 void *digest; 750 void *digest;
763}; 751};
764 752
765/* ee flag bits */ 753struct drbd_epoch_entry {
754 struct drbd_work w;
755 struct hlist_node colision;
756 struct drbd_epoch *epoch;
757 struct drbd_conf *mdev;
758 struct page *pages;
759 atomic_t pending_bios;
760 unsigned int size;
761 /* see comments on ee flag bits below */
762 unsigned long flags;
763 sector_t sector;
764 u64 block_id;
765};
766
767/* ee flag bits.
768 * While corresponding bios are in flight, the only modification will be
769 * set_bit WAS_ERROR, which has to be atomic.
770 * If no bios are in flight yet, or all have been completed,
771 * non-atomic modification to ee->flags is ok.
772 */
766enum { 773enum {
767 __EE_CALL_AL_COMPLETE_IO, 774 __EE_CALL_AL_COMPLETE_IO,
768 __EE_CONFLICT_PENDING,
769 __EE_MAY_SET_IN_SYNC, 775 __EE_MAY_SET_IN_SYNC,
776
777 /* This epoch entry closes an epoch using a barrier.
778 * On sucessful completion, the epoch is released,
779 * and the P_BARRIER_ACK send. */
770 __EE_IS_BARRIER, 780 __EE_IS_BARRIER,
781
782 /* In case a barrier failed,
783 * we need to resubmit without the barrier flag. */
784 __EE_RESUBMITTED,
785
786 /* we may have several bios per epoch entry.
787 * if any of those fail, we set this flag atomically
788 * from the endio callback */
789 __EE_WAS_ERROR,
771}; 790};
772#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) 791#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
773#define EE_CONFLICT_PENDING (1<<__EE_CONFLICT_PENDING)
774#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) 792#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC)
775#define EE_IS_BARRIER (1<<__EE_IS_BARRIER) 793#define EE_IS_BARRIER (1<<__EE_IS_BARRIER)
794#define EE_RESUBMITTED (1<<__EE_RESUBMITTED)
795#define EE_WAS_ERROR (1<<__EE_WAS_ERROR)
776 796
777/* global flag bits */ 797/* global flag bits */
778enum { 798enum {
@@ -1441,7 +1461,8 @@ static inline void ov_oos_print(struct drbd_conf *mdev)
1441} 1461}
1442 1462
1443 1463
1444extern void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); 1464extern void drbd_csum_bio(struct drbd_conf *, struct crypto_hash *, struct bio *, void *);
1465extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *, struct drbd_epoch_entry *, void *);
1445/* worker callbacks */ 1466/* worker callbacks */
1446extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int); 1467extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int);
1447extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int); 1468extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int);
@@ -1465,6 +1486,8 @@ extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int);
1465extern void resync_timer_fn(unsigned long data); 1486extern void resync_timer_fn(unsigned long data);
1466 1487
1467/* drbd_receiver.c */ 1488/* drbd_receiver.c */
1489extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
1490 const unsigned rw, const int fault_type);
1468extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); 1491extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list);
1469extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, 1492extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
1470 u64 id, 1493 u64 id,
@@ -1620,6 +1643,41 @@ void drbd_bcast_ee(struct drbd_conf *mdev,
1620 * inline helper functions 1643 * inline helper functions
1621 *************************/ 1644 *************************/
1622 1645
1646/* see also page_chain_add and friends in drbd_receiver.c */
1647static inline struct page *page_chain_next(struct page *page)
1648{
1649 return (struct page *)page_private(page);
1650}
1651#define page_chain_for_each(page) \
1652 for (; page && ({ prefetch(page_chain_next(page)); 1; }); \
1653 page = page_chain_next(page))
1654#define page_chain_for_each_safe(page, n) \
1655 for (; page && ({ n = page_chain_next(page); 1; }); page = n)
1656
1657static inline int drbd_bio_has_active_page(struct bio *bio)
1658{
1659 struct bio_vec *bvec;
1660 int i;
1661
1662 __bio_for_each_segment(bvec, bio, i, 0) {
1663 if (page_count(bvec->bv_page) > 1)
1664 return 1;
1665 }
1666
1667 return 0;
1668}
1669
1670static inline int drbd_ee_has_active_page(struct drbd_epoch_entry *e)
1671{
1672 struct page *page = e->pages;
1673 page_chain_for_each(page) {
1674 if (page_count(page) > 1)
1675 return 1;
1676 }
1677 return 0;
1678}
1679
1680
1623static inline void drbd_state_lock(struct drbd_conf *mdev) 1681static inline void drbd_state_lock(struct drbd_conf *mdev)
1624{ 1682{
1625 wait_event(mdev->misc_wait, 1683 wait_event(mdev->misc_wait,