diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2012-11-18 21:49:06 -0500 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-12-13 09:13:07 -0500 |
commit | ed75ec2cd19b47efcd292b6e23f58e56f4c5bc34 (patch) | |
tree | 570f74b490afdbe623785124ec3186ae5a012d53 /fs/ceph | |
parent | 5e62ad30157d0da04cf40c6d1a2f4bc840948b9c (diff) |
ceph: Fix infinite loop in __wake_requests
__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>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/mds_client.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 62d2342eb267..9165eb8309eb 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1876,9 +1876,14 @@ finish: | |||
1876 | static void __wake_requests(struct ceph_mds_client *mdsc, | 1876 | static void __wake_requests(struct ceph_mds_client *mdsc, |
1877 | struct list_head *head) | 1877 | struct list_head *head) |
1878 | { | 1878 | { |
1879 | struct ceph_mds_request *req, *nreq; | 1879 | struct ceph_mds_request *req; |
1880 | LIST_HEAD(tmp_list); | ||
1881 | |||
1882 | list_splice_init(head, &tmp_list); | ||
1880 | 1883 | ||
1881 | list_for_each_entry_safe(req, nreq, head, r_wait) { | 1884 | while (!list_empty(&tmp_list)) { |
1885 | req = list_entry(tmp_list.next, | ||
1886 | struct ceph_mds_request, r_wait); | ||
1882 | list_del_init(&req->r_wait); | 1887 | list_del_init(&req->r_wait); |
1883 | __do_request(mdsc, req); | 1888 | __do_request(mdsc, req); |
1884 | } | 1889 | } |