aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-08-31 06:00:50 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 12:38:26 -0400
commit0778286a133d2d3f81861a4e5db308e359583006 (patch)
tree14bdfe375481d8954ada1ddaa0bc84fcaba4e23d /drivers/block/drbd/drbd_nl.c
parentd53733893dc43f4ebb5be510863c5debf0f8990b (diff)
drbd: Disable activity log updates when the whole device is out of sync
When the complete device is marked as out of sync, we can disable updates of the on disk AL. Currently AL updates are only disabled if one uses the "invalidate-remote" command on an unconnected, primary device, or when at attach time all bits in the bitmap are set. As of now, AL updated do not get disabled when a all bits becomes set due to application writes to an unconnected DRBD device. While this is a missing feature, it is not considered important, and might get added later. BTW, after initializing a "one legged" DRBD device drbdadm create-md resX drbdadm -- --force primary resX AL updates also get disabled, until the first connect. 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_nl.c')
-rw-r--r--drivers/block/drbd/drbd_nl.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 97fb2c2a7a5..6742652c8ab 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -777,6 +777,29 @@ static void drbd_reconfig_done(struct drbd_conf *mdev)
777 wake_up(&mdev->state_wait); 777 wake_up(&mdev->state_wait);
778} 778}
779 779
780/* Make sure IO is suspended before calling this function(). */
781static void drbd_suspend_al(struct drbd_conf *mdev)
782{
783 int s = 0;
784
785 if (lc_try_lock(mdev->act_log)) {
786 drbd_al_shrink(mdev);
787 lc_unlock(mdev->act_log);
788 } else {
789 dev_warn(DEV, "Failed to lock al in drbd_suspend_al()\n");
790 return;
791 }
792
793 spin_lock_irq(&mdev->req_lock);
794 if (mdev->state.conn < C_CONNECTED)
795 s = !test_and_set_bit(AL_SUSPENDED, &mdev->flags);
796
797 spin_unlock_irq(&mdev->req_lock);
798
799 if (s)
800 dev_info(DEV, "Suspended AL updates\n");
801}
802
780/* does always return 0; 803/* does always return 0;
781 * interesting return code is in reply->ret_code */ 804 * interesting return code is in reply->ret_code */
782static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, 805static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
@@ -1113,6 +1136,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1113 drbd_al_to_on_disk_bm(mdev); 1136 drbd_al_to_on_disk_bm(mdev);
1114 } 1137 }
1115 1138
1139 if (_drbd_bm_total_weight(mdev) == drbd_bm_bits(mdev))
1140 drbd_suspend_al(mdev); /* IO is still suspended here... */
1141
1116 spin_lock_irq(&mdev->req_lock); 1142 spin_lock_irq(&mdev->req_lock);
1117 os = mdev->state; 1143 os = mdev->state;
1118 ns.i = os.i; 1144 ns.i = os.i;
@@ -1792,12 +1818,38 @@ static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
1792 return 0; 1818 return 0;
1793} 1819}
1794 1820
1821static int drbd_bmio_set_susp_al(struct drbd_conf *mdev)
1822{
1823 int rv;
1824
1825 rv = drbd_bmio_set_n_write(mdev);
1826 drbd_suspend_al(mdev);
1827 return rv;
1828}
1829
1795static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, 1830static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1796 struct drbd_nl_cfg_reply *reply) 1831 struct drbd_nl_cfg_reply *reply)
1797{ 1832{
1833 int retcode;
1798 1834
1799 reply->ret_code = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S)); 1835 retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S), CS_ORDERED);
1836
1837 if (retcode < SS_SUCCESS) {
1838 if (retcode == SS_NEED_CONNECTION && mdev->state.role == R_PRIMARY) {
1839 /* The peer will get a resync upon connect anyways. Just make that
1840 into a full resync. */
1841 retcode = drbd_request_state(mdev, NS(pdsk, D_INCONSISTENT));
1842 if (retcode >= SS_SUCCESS) {
1843 /* open coded drbd_bitmap_io() */
1844 if (drbd_bitmap_io(mdev, &drbd_bmio_set_susp_al,
1845 "set_n_write from invalidate_peer"))
1846 retcode = ERR_IO_MD_DISK;
1847 }
1848 } else
1849 retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S));
1850 }
1800 1851
1852 reply->ret_code = retcode;
1801 return 0; 1853 return 0;
1802} 1854}
1803 1855