aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ceph/osd_client.h1
-rw-r--r--net/ceph/osd_client.c29
2 files changed, 28 insertions, 2 deletions
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 8f47625a0661..4fb6a8938957 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -138,6 +138,7 @@ struct ceph_osd_request {
138 __le64 *r_request_pool; 138 __le64 *r_request_pool;
139 void *r_request_pgid; 139 void *r_request_pgid;
140 __le32 *r_request_attempts; 140 __le32 *r_request_attempts;
141 bool r_paused;
141 struct ceph_eversion *r_request_reassert_version; 142 struct ceph_eversion *r_request_reassert_version;
142 143
143 int r_result; 144 int r_result;
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index a17eaae820f8..1ad9866dc707 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -1232,6 +1232,22 @@ void ceph_osdc_set_request_linger(struct ceph_osd_client *osdc,
1232EXPORT_SYMBOL(ceph_osdc_set_request_linger); 1232EXPORT_SYMBOL(ceph_osdc_set_request_linger);
1233 1233
1234/* 1234/*
1235 * Returns whether a request should be blocked from being sent
1236 * based on the current osdmap and osd_client settings.
1237 *
1238 * Caller should hold map_sem for read.
1239 */
1240static bool __req_should_be_paused(struct ceph_osd_client *osdc,
1241 struct ceph_osd_request *req)
1242{
1243 bool pauserd = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSERD);
1244 bool pausewr = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSEWR) ||
1245 ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL);
1246 return (req->r_flags & CEPH_OSD_FLAG_READ && pauserd) ||
1247 (req->r_flags & CEPH_OSD_FLAG_WRITE && pausewr);
1248}
1249
1250/*
1235 * Pick an osd (the first 'up' osd in the pg), allocate the osd struct 1251 * Pick an osd (the first 'up' osd in the pg), allocate the osd struct
1236 * (as needed), and set the request r_osd appropriately. If there is 1252 * (as needed), and set the request r_osd appropriately. If there is
1237 * no up osd, set r_osd to NULL. Move the request to the appropriate list 1253 * no up osd, set r_osd to NULL. Move the request to the appropriate list
@@ -1248,6 +1264,7 @@ static int __map_request(struct ceph_osd_client *osdc,
1248 int acting[CEPH_PG_MAX_SIZE]; 1264 int acting[CEPH_PG_MAX_SIZE];
1249 int o = -1, num = 0; 1265 int o = -1, num = 0;
1250 int err; 1266 int err;
1267 bool was_paused;
1251 1268
1252 dout("map_request %p tid %lld\n", req, req->r_tid); 1269 dout("map_request %p tid %lld\n", req, req->r_tid);
1253 err = ceph_calc_ceph_pg(&pgid, req->r_oid, osdc->osdmap, 1270 err = ceph_calc_ceph_pg(&pgid, req->r_oid, osdc->osdmap,
@@ -1264,12 +1281,18 @@ static int __map_request(struct ceph_osd_client *osdc,
1264 num = err; 1281 num = err;
1265 } 1282 }
1266 1283
1284 was_paused = req->r_paused;
1285 req->r_paused = __req_should_be_paused(osdc, req);
1286 if (was_paused && !req->r_paused)
1287 force_resend = 1;
1288
1267 if ((!force_resend && 1289 if ((!force_resend &&
1268 req->r_osd && req->r_osd->o_osd == o && 1290 req->r_osd && req->r_osd->o_osd == o &&
1269 req->r_sent >= req->r_osd->o_incarnation && 1291 req->r_sent >= req->r_osd->o_incarnation &&
1270 req->r_num_pg_osds == num && 1292 req->r_num_pg_osds == num &&
1271 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) || 1293 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
1272 (req->r_osd == NULL && o == -1)) 1294 (req->r_osd == NULL && o == -1) ||
1295 req->r_paused)
1273 return 0; /* no change */ 1296 return 0; /* no change */
1274 1297
1275 dout("map_request tid %llu pgid %lld.%x osd%d (was osd%d)\n", 1298 dout("map_request tid %llu pgid %lld.%x osd%d (was osd%d)\n",
@@ -1811,7 +1834,9 @@ done:
1811 * we find out when we are no longer full and stop returning 1834 * we find out when we are no longer full and stop returning
1812 * ENOSPC. 1835 * ENOSPC.
1813 */ 1836 */
1814 if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL)) 1837 if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL) ||
1838 ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSERD) ||
1839 ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSEWR))
1815 ceph_monc_request_next_osdmap(&osdc->client->monc); 1840 ceph_monc_request_next_osdmap(&osdc->client->monc);
1816 1841
1817 mutex_lock(&osdc->request_mutex); 1842 mutex_lock(&osdc->request_mutex);