drbd: add missing rcu locks around recently introduced idr_for_each

Recent commit
 drbd: Move write_ordering from mdev to tconn
introduced a new idr_for_each loop over all volumes,
but did not take necessary rcu locks or krefs.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
Lars Ellenberg 2011-11-17 14:32:12 +01:00 committed by Philipp Reisner
parent 03d63e1d1e
commit 615e087fbd

View File

@ -1096,22 +1096,30 @@ static void drbd_flush(struct drbd_tconn *tconn)
int vnr; int vnr;
if (tconn->write_ordering >= WO_bdev_flush) { if (tconn->write_ordering >= WO_bdev_flush) {
rcu_read_lock();
idr_for_each_entry(&tconn->volumes, mdev, vnr) { idr_for_each_entry(&tconn->volumes, mdev, vnr) {
if (get_ldev(mdev)) { if (!get_ldev(mdev))
rv = blkdev_issue_flush(mdev->ldev->backing_bdev, GFP_KERNEL, continue;
NULL); kref_get(&mdev->kref);
put_ldev(mdev); rcu_read_unlock();
if (rv) { rv = blkdev_issue_flush(mdev->ldev->backing_bdev,
dev_info(DEV, "local disk flush failed with status %d\n", rv); GFP_NOIO, NULL);
/* would rather check on EOPNOTSUPP, but that is not reliable. if (rv) {
* don't try again for ANY return value != 0 dev_info(DEV, "local disk flush failed with status %d\n", rv);
* if (rv == -EOPNOTSUPP) */ /* would rather check on EOPNOTSUPP, but that is not reliable.
drbd_bump_write_ordering(tconn, WO_drain_io); * don't try again for ANY return value != 0
break; * if (rv == -EOPNOTSUPP) */
} drbd_bump_write_ordering(tconn, WO_drain_io);
} }
put_ldev(mdev);
kref_put(&mdev->kref, &drbd_minor_destroy);
rcu_read_lock();
if (rv)
break;
} }
rcu_read_unlock();
} }
} }