aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-04-12 01:53:32 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:45:16 -0500
commit695d08fa94ce5bb8d9880e260445fbcf50fa41b4 (patch)
treedda7776d2ad2db3414a9377ae485c6e33575804d /drivers/block/drbd/drbd_nl.c
parentcd1d9950f69b46d88002b39652ed0cf3608d008b (diff)
drbd: rcu_read_[un]lock() for all idr accesses that do not sleep
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.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index f08fb6f49cd8..60c171b17156 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -372,12 +372,14 @@ static enum drbd_fencing_p highest_fencing_policy(struct drbd_tconn *tconn)
372 struct drbd_conf *mdev; 372 struct drbd_conf *mdev;
373 int vnr; 373 int vnr;
374 374
375 rcu_read_lock();
375 idr_for_each_entry(&tconn->volumes, mdev, vnr) { 376 idr_for_each_entry(&tconn->volumes, mdev, vnr) {
376 if (get_ldev_if_state(mdev, D_CONSISTENT)) { 377 if (get_ldev_if_state(mdev, D_CONSISTENT)) {
377 fp = max_t(enum drbd_fencing_p, fp, mdev->ldev->dc.fencing); 378 fp = max_t(enum drbd_fencing_p, fp, mdev->ldev->dc.fencing);
378 put_ldev(mdev); 379 put_ldev(mdev);
379 } 380 }
380 } 381 }
382 rcu_read_unlock();
381 383
382 return fp; 384 return fp;
383} 385}
@@ -1624,29 +1626,41 @@ out:
1624static bool conn_resync_running(struct drbd_tconn *tconn) 1626static bool conn_resync_running(struct drbd_tconn *tconn)
1625{ 1627{
1626 struct drbd_conf *mdev; 1628 struct drbd_conf *mdev;
1629 bool rv = false;
1627 int vnr; 1630 int vnr;
1628 1631
1632 rcu_read_lock();
1629 idr_for_each_entry(&tconn->volumes, mdev, vnr) { 1633 idr_for_each_entry(&tconn->volumes, mdev, vnr) {
1630 if (mdev->state.conn == C_SYNC_SOURCE || 1634 if (mdev->state.conn == C_SYNC_SOURCE ||
1631 mdev->state.conn == C_SYNC_TARGET || 1635 mdev->state.conn == C_SYNC_TARGET ||
1632 mdev->state.conn == C_PAUSED_SYNC_S || 1636 mdev->state.conn == C_PAUSED_SYNC_S ||
1633 mdev->state.conn == C_PAUSED_SYNC_T) 1637 mdev->state.conn == C_PAUSED_SYNC_T) {
1634 return true; 1638 rv = true;
1639 break;
1640 }
1635 } 1641 }
1636 return false; 1642 rcu_read_unlock();
1643
1644 return rv;
1637} 1645}
1638 1646
1639static bool conn_ov_running(struct drbd_tconn *tconn) 1647static bool conn_ov_running(struct drbd_tconn *tconn)
1640{ 1648{
1641 struct drbd_conf *mdev; 1649 struct drbd_conf *mdev;
1650 bool rv = false;
1642 int vnr; 1651 int vnr;
1643 1652
1653 rcu_read_lock();
1644 idr_for_each_entry(&tconn->volumes, mdev, vnr) { 1654 idr_for_each_entry(&tconn->volumes, mdev, vnr) {
1645 if (mdev->state.conn == C_VERIFY_S || 1655 if (mdev->state.conn == C_VERIFY_S ||
1646 mdev->state.conn == C_VERIFY_T) 1656 mdev->state.conn == C_VERIFY_T) {
1647 return true; 1657 rv = true;
1658 break;
1659 }
1648 } 1660 }
1649 return false; 1661 rcu_read_unlock();
1662
1663 return rv;
1650} 1664}
1651 1665
1652int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) 1666int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
@@ -1858,26 +1872,28 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
1858 goto fail; 1872 goto fail;
1859 } 1873 }
1860 1874
1875 rcu_read_lock();
1861 idr_for_each_entry(&tconn->volumes, mdev, i) { 1876 idr_for_each_entry(&tconn->volumes, mdev, i) {
1862 if (get_ldev(mdev)) { 1877 if (get_ldev(mdev)) {
1863 enum drbd_fencing_p fp = mdev->ldev->dc.fencing; 1878 enum drbd_fencing_p fp = mdev->ldev->dc.fencing;
1864 put_ldev(mdev); 1879 put_ldev(mdev);
1865 if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH) { 1880 if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH) {
1866 retcode = ERR_STONITH_AND_PROT_A; 1881 retcode = ERR_STONITH_AND_PROT_A;
1867 goto fail; 1882 goto fail_rcu_unlock;
1868 } 1883 }
1869 } 1884 }
1870 if (mdev->state.role == R_PRIMARY && new_conf->want_lose) { 1885 if (mdev->state.role == R_PRIMARY && new_conf->want_lose) {
1871 retcode = ERR_DISCARD; 1886 retcode = ERR_DISCARD;
1872 goto fail; 1887 goto fail_rcu_unlock;
1873 } 1888 }
1874 if (!mdev->bitmap) { 1889 if (!mdev->bitmap) {
1875 if(drbd_bm_init(mdev)) { 1890 if(drbd_bm_init(mdev)) {
1876 retcode = ERR_NOMEM; 1891 retcode = ERR_NOMEM;
1877 goto fail; 1892 goto fail_rcu_unlock;
1878 } 1893 }
1879 } 1894 }
1880 } 1895 }
1896 rcu_read_unlock();
1881 1897
1882 if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A) { 1898 if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A) {
1883 retcode = ERR_CONG_NOT_PROTO_A; 1899 retcode = ERR_CONG_NOT_PROTO_A;
@@ -1991,15 +2007,19 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
1991 retcode = _conn_request_state(tconn, NS(conn, C_UNCONNECTED), CS_VERBOSE); 2007 retcode = _conn_request_state(tconn, NS(conn, C_UNCONNECTED), CS_VERBOSE);
1992 spin_unlock_irq(&tconn->req_lock); 2008 spin_unlock_irq(&tconn->req_lock);
1993 2009
2010 rcu_read_lock();
1994 idr_for_each_entry(&tconn->volumes, mdev, i) { 2011 idr_for_each_entry(&tconn->volumes, mdev, i) {
1995 mdev->send_cnt = 0; 2012 mdev->send_cnt = 0;
1996 mdev->recv_cnt = 0; 2013 mdev->recv_cnt = 0;
1997 kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE); 2014 kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
1998 } 2015 }
2016 rcu_read_unlock();
1999 conn_reconfig_done(tconn); 2017 conn_reconfig_done(tconn);
2000 drbd_adm_finish(info, retcode); 2018 drbd_adm_finish(info, retcode);
2001 return 0; 2019 return 0;
2002 2020
2021fail_rcu_unlock:
2022 rcu_read_unlock();
2003fail: 2023fail:
2004 kfree(int_dig_in); 2024 kfree(int_dig_in);
2005 kfree(int_dig_vv); 2025 kfree(int_dig_vv);
@@ -2562,8 +2582,6 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
2562 2582
2563 /* synchronize with drbd_new_tconn/drbd_free_tconn */ 2583 /* synchronize with drbd_new_tconn/drbd_free_tconn */
2564 mutex_lock(&drbd_cfg_mutex); 2584 mutex_lock(&drbd_cfg_mutex);
2565 /* synchronize with drbd_delete_device */
2566 rcu_read_lock();
2567next_tconn: 2585next_tconn:
2568 /* revalidate iterator position */ 2586 /* revalidate iterator position */
2569 list_for_each_entry(tmp, &drbd_tconns, all_tconn) { 2587 list_for_each_entry(tmp, &drbd_tconns, all_tconn) {
@@ -2624,7 +2642,6 @@ next_tconn:
2624 } 2642 }
2625 2643
2626out: 2644out:
2627 rcu_read_unlock();
2628 mutex_unlock(&drbd_cfg_mutex); 2645 mutex_unlock(&drbd_cfg_mutex);
2629 /* where to start the next iteration */ 2646 /* where to start the next iteration */
2630 cb->args[0] = (long)pos; 2647 cb->args[0] = (long)pos;