summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2012-11-19 10:49:06 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 08:46:49 -0800
commitbd604499e4a60e5e5c279ef1b9b83cd21d614d7c (patch)
treeb5618db814c79c9be8efd69d2055e45f36ddbd2d /fs
parent4899444757a896e3d38650e8fe11b50e2eecc88f (diff)
ceph: Fix infinite loop in __wake_requests
(cherry picked from commit ed75ec2cd19b47efcd292b6e23f58e56f4c5bc34) __wake_requests() will enter infinite loop if we use it to wake requests in the session->s_waiting list. __wake_requests() deletes requests from the list and __do_request() adds requests back to the list. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Signed-off-by: Sage Weil <sage@inktank.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/mds_client.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 1bcf712655d9..0d9864fb33dc 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1876,9 +1876,14 @@ finish:
static void __wake_requests(struct ceph_mds_client *mdsc,
struct list_head *head)
{
- struct ceph_mds_request *req, *nreq;
+ struct ceph_mds_request *req;
+ LIST_HEAD(tmp_list);
+
+ list_splice_init(head, &tmp_list);
- list_for_each_entry_safe(req, nreq, head, r_wait) {
+ while (!list_empty(&tmp_list)) {
+ req = list_entry(tmp_list.next,
+ struct ceph_mds_request, r_wait);
list_del_init(&req->r_wait);
__do_request(mdsc, req);
}