diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2015-05-15 05:02:17 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-06-25 04:49:29 -0400 |
commit | a319bf56a617354e62cf5f774d2ca4e1a8a3bff3 (patch) | |
tree | cf54ed20b02c8488a342f54fd573eb57df964a3c | |
parent | d50c97b566c5bbf990eff472e9feaa58fdebdd33 (diff) |
libceph: store timeouts in jiffies, verify user input
There are currently three libceph-level timeouts that the user can
specify on mount: mount_timeout, osd_idle_ttl and osdkeepalive. All of
these are in seconds and no checking is done on user input: negative
values are accepted, we multiply them all by HZ which may or may not
overflow, arbitrarily large jiffies then get added together, etc.
There is also a bug in the way mount_timeout=0 is handled. It's
supposed to mean "infinite timeout", but that's not how wait.h APIs
treat it and so __ceph_open_session() for example will busy loop
without much chance of being interrupted if none of ceph-mons are
there.
Fix all this by verifying user input, storing timeouts capped by
msecs_to_jiffies() in jiffies and using the new ceph_timeout_jiffies()
helper for all user-specified waits to handle infinite timeouts
correctly.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Alex Elder <elder@linaro.org>
-rw-r--r-- | drivers/block/rbd.c | 5 | ||||
-rw-r--r-- | fs/ceph/dir.c | 4 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 12 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 2 | ||||
-rw-r--r-- | fs/ceph/super.c | 2 | ||||
-rw-r--r-- | include/linux/ceph/libceph.h | 17 | ||||
-rw-r--r-- | net/ceph/ceph_common.c | 41 | ||||
-rw-r--r-- | net/ceph/mon_client.c | 11 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 15 |
9 files changed, 71 insertions, 38 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 349115ae3bc2..992683b6b299 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -4963,8 +4963,8 @@ out_err: | |||
4963 | */ | 4963 | */ |
4964 | static int rbd_add_get_pool_id(struct rbd_client *rbdc, const char *pool_name) | 4964 | static int rbd_add_get_pool_id(struct rbd_client *rbdc, const char *pool_name) |
4965 | { | 4965 | { |
4966 | struct ceph_options *opts = rbdc->client->options; | ||
4966 | u64 newest_epoch; | 4967 | u64 newest_epoch; |
4967 | unsigned long timeout = rbdc->client->options->mount_timeout * HZ; | ||
4968 | int tries = 0; | 4968 | int tries = 0; |
4969 | int ret; | 4969 | int ret; |
4970 | 4970 | ||
@@ -4979,7 +4979,8 @@ again: | |||
4979 | if (rbdc->client->osdc.osdmap->epoch < newest_epoch) { | 4979 | if (rbdc->client->osdc.osdmap->epoch < newest_epoch) { |
4980 | ceph_monc_request_next_osdmap(&rbdc->client->monc); | 4980 | ceph_monc_request_next_osdmap(&rbdc->client->monc); |
4981 | (void) ceph_monc_wait_osdmap(&rbdc->client->monc, | 4981 | (void) ceph_monc_wait_osdmap(&rbdc->client->monc, |
4982 | newest_epoch, timeout); | 4982 | newest_epoch, |
4983 | opts->mount_timeout); | ||
4983 | goto again; | 4984 | goto again; |
4984 | } else { | 4985 | } else { |
4985 | /* the osdmap we have is new enough */ | 4986 | /* the osdmap we have is new enough */ |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 4248307fea90..173dd4b58c71 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1259,8 +1259,8 @@ static int ceph_dir_fsync(struct file *file, loff_t start, loff_t end, | |||
1259 | inode, req->r_tid, last_tid); | 1259 | inode, req->r_tid, last_tid); |
1260 | if (req->r_timeout) { | 1260 | if (req->r_timeout) { |
1261 | unsigned long time_left = wait_for_completion_timeout( | 1261 | unsigned long time_left = wait_for_completion_timeout( |
1262 | &req->r_safe_completion, | 1262 | &req->r_safe_completion, |
1263 | req->r_timeout); | 1263 | ceph_timeout_jiffies(req->r_timeout)); |
1264 | if (time_left > 0) | 1264 | if (time_left > 0) |
1265 | ret = 0; | 1265 | ret = 0; |
1266 | else | 1266 | else |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 69a36f40517f..0b0e0a9a81c0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2268,7 +2268,8 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, | |||
2268 | dout("do_request waiting\n"); | 2268 | dout("do_request waiting\n"); |
2269 | if (req->r_timeout) { | 2269 | if (req->r_timeout) { |
2270 | err = (long)wait_for_completion_killable_timeout( | 2270 | err = (long)wait_for_completion_killable_timeout( |
2271 | &req->r_completion, req->r_timeout); | 2271 | &req->r_completion, |
2272 | ceph_timeout_jiffies(req->r_timeout)); | ||
2272 | if (err == 0) | 2273 | if (err == 0) |
2273 | err = -EIO; | 2274 | err = -EIO; |
2274 | } else if (req->r_wait_for_completion) { | 2275 | } else if (req->r_wait_for_completion) { |
@@ -3424,8 +3425,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) | |||
3424 | */ | 3425 | */ |
3425 | static void wait_requests(struct ceph_mds_client *mdsc) | 3426 | static void wait_requests(struct ceph_mds_client *mdsc) |
3426 | { | 3427 | { |
3428 | struct ceph_options *opts = mdsc->fsc->client->options; | ||
3427 | struct ceph_mds_request *req; | 3429 | struct ceph_mds_request *req; |
3428 | struct ceph_fs_client *fsc = mdsc->fsc; | ||
3429 | 3430 | ||
3430 | mutex_lock(&mdsc->mutex); | 3431 | mutex_lock(&mdsc->mutex); |
3431 | if (__get_oldest_req(mdsc)) { | 3432 | if (__get_oldest_req(mdsc)) { |
@@ -3433,7 +3434,7 @@ static void wait_requests(struct ceph_mds_client *mdsc) | |||
3433 | 3434 | ||
3434 | dout("wait_requests waiting for requests\n"); | 3435 | dout("wait_requests waiting for requests\n"); |
3435 | wait_for_completion_timeout(&mdsc->safe_umount_waiters, | 3436 | wait_for_completion_timeout(&mdsc->safe_umount_waiters, |
3436 | fsc->client->options->mount_timeout * HZ); | 3437 | ceph_timeout_jiffies(opts->mount_timeout)); |
3437 | 3438 | ||
3438 | /* tear down remaining requests */ | 3439 | /* tear down remaining requests */ |
3439 | mutex_lock(&mdsc->mutex); | 3440 | mutex_lock(&mdsc->mutex); |
@@ -3556,10 +3557,9 @@ static bool done_closing_sessions(struct ceph_mds_client *mdsc) | |||
3556 | */ | 3557 | */ |
3557 | void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | 3558 | void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) |
3558 | { | 3559 | { |
3560 | struct ceph_options *opts = mdsc->fsc->client->options; | ||
3559 | struct ceph_mds_session *session; | 3561 | struct ceph_mds_session *session; |
3560 | int i; | 3562 | int i; |
3561 | struct ceph_fs_client *fsc = mdsc->fsc; | ||
3562 | unsigned long timeout = fsc->client->options->mount_timeout * HZ; | ||
3563 | 3563 | ||
3564 | dout("close_sessions\n"); | 3564 | dout("close_sessions\n"); |
3565 | 3565 | ||
@@ -3580,7 +3580,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3580 | 3580 | ||
3581 | dout("waiting for sessions to close\n"); | 3581 | dout("waiting for sessions to close\n"); |
3582 | wait_event_timeout(mdsc->session_close_wq, done_closing_sessions(mdsc), | 3582 | wait_event_timeout(mdsc->session_close_wq, done_closing_sessions(mdsc), |
3583 | timeout); | 3583 | ceph_timeout_jiffies(opts->mount_timeout)); |
3584 | 3584 | ||
3585 | /* tear down remaining sessions */ | 3585 | /* tear down remaining sessions */ |
3586 | mutex_lock(&mdsc->mutex); | 3586 | mutex_lock(&mdsc->mutex); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 2ef799961ebb..509d6822e9b1 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -227,7 +227,7 @@ struct ceph_mds_request { | |||
227 | int r_err; | 227 | int r_err; |
228 | bool r_aborted; | 228 | bool r_aborted; |
229 | 229 | ||
230 | unsigned long r_timeout; /* optional. jiffies */ | 230 | unsigned long r_timeout; /* optional. jiffies, 0 is "wait forever" */ |
231 | unsigned long r_started; /* start time to measure timeout against */ | 231 | unsigned long r_started; /* start time to measure timeout against */ |
232 | unsigned long r_request_started; /* start time for mds request only, | 232 | unsigned long r_request_started; /* start time for mds request only, |
233 | used to measure lease durations */ | 233 | used to measure lease durations */ |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 9a5350030af8..edeb83c43112 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -742,7 +742,7 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, | |||
742 | req->r_ino1.ino = CEPH_INO_ROOT; | 742 | req->r_ino1.ino = CEPH_INO_ROOT; |
743 | req->r_ino1.snap = CEPH_NOSNAP; | 743 | req->r_ino1.snap = CEPH_NOSNAP; |
744 | req->r_started = started; | 744 | req->r_started = started; |
745 | req->r_timeout = fsc->client->options->mount_timeout * HZ; | 745 | req->r_timeout = fsc->client->options->mount_timeout; |
746 | req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); | 746 | req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); |
747 | req->r_num_caps = 2; | 747 | req->r_num_caps = 2; |
748 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 748 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 85ae9a889a3f..d73a569f9bf5 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h | |||
@@ -43,9 +43,9 @@ struct ceph_options { | |||
43 | int flags; | 43 | int flags; |
44 | struct ceph_fsid fsid; | 44 | struct ceph_fsid fsid; |
45 | struct ceph_entity_addr my_addr; | 45 | struct ceph_entity_addr my_addr; |
46 | int mount_timeout; | 46 | unsigned long mount_timeout; /* jiffies */ |
47 | int osd_idle_ttl; | 47 | unsigned long osd_idle_ttl; /* jiffies */ |
48 | int osd_keepalive_timeout; | 48 | unsigned long osd_keepalive_timeout; /* jiffies */ |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * any type that can't be simply compared or doesn't need need | 51 | * any type that can't be simply compared or doesn't need need |
@@ -63,9 +63,9 @@ struct ceph_options { | |||
63 | /* | 63 | /* |
64 | * defaults | 64 | * defaults |
65 | */ | 65 | */ |
66 | #define CEPH_MOUNT_TIMEOUT_DEFAULT 60 | 66 | #define CEPH_MOUNT_TIMEOUT_DEFAULT msecs_to_jiffies(60 * 1000) |
67 | #define CEPH_OSD_KEEPALIVE_DEFAULT 5 | 67 | #define CEPH_OSD_KEEPALIVE_DEFAULT msecs_to_jiffies(5 * 1000) |
68 | #define CEPH_OSD_IDLE_TTL_DEFAULT 60 | 68 | #define CEPH_OSD_IDLE_TTL_DEFAULT msecs_to_jiffies(60 * 1000) |
69 | 69 | ||
70 | #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) | 70 | #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) |
71 | #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024) | 71 | #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024) |
@@ -93,6 +93,11 @@ enum { | |||
93 | CEPH_MOUNT_SHUTDOWN, | 93 | CEPH_MOUNT_SHUTDOWN, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static inline unsigned long ceph_timeout_jiffies(unsigned long timeout) | ||
97 | { | ||
98 | return timeout ?: MAX_SCHEDULE_TIMEOUT; | ||
99 | } | ||
100 | |||
96 | struct ceph_mds_client; | 101 | struct ceph_mds_client; |
97 | 102 | ||
98 | /* | 103 | /* |
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 79e8f71aef5b..a80e91c2c9a3 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c | |||
@@ -352,8 +352,8 @@ ceph_parse_options(char *options, const char *dev_name, | |||
352 | /* start with defaults */ | 352 | /* start with defaults */ |
353 | opt->flags = CEPH_OPT_DEFAULT; | 353 | opt->flags = CEPH_OPT_DEFAULT; |
354 | opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT; | 354 | opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT; |
355 | opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */ | 355 | opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; |
356 | opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; /* seconds */ | 356 | opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; |
357 | 357 | ||
358 | /* get mon ip(s) */ | 358 | /* get mon ip(s) */ |
359 | /* ip1[:port1][,ip2[:port2]...] */ | 359 | /* ip1[:port1][,ip2[:port2]...] */ |
@@ -439,13 +439,32 @@ ceph_parse_options(char *options, const char *dev_name, | |||
439 | pr_warn("ignoring deprecated osdtimeout option\n"); | 439 | pr_warn("ignoring deprecated osdtimeout option\n"); |
440 | break; | 440 | break; |
441 | case Opt_osdkeepalivetimeout: | 441 | case Opt_osdkeepalivetimeout: |
442 | opt->osd_keepalive_timeout = intval; | 442 | /* 0 isn't well defined right now, reject it */ |
443 | if (intval < 1 || intval > INT_MAX / 1000) { | ||
444 | pr_err("osdkeepalive out of range\n"); | ||
445 | err = -EINVAL; | ||
446 | goto out; | ||
447 | } | ||
448 | opt->osd_keepalive_timeout = | ||
449 | msecs_to_jiffies(intval * 1000); | ||
443 | break; | 450 | break; |
444 | case Opt_osd_idle_ttl: | 451 | case Opt_osd_idle_ttl: |
445 | opt->osd_idle_ttl = intval; | 452 | /* 0 isn't well defined right now, reject it */ |
453 | if (intval < 1 || intval > INT_MAX / 1000) { | ||
454 | pr_err("osd_idle_ttl out of range\n"); | ||
455 | err = -EINVAL; | ||
456 | goto out; | ||
457 | } | ||
458 | opt->osd_idle_ttl = msecs_to_jiffies(intval * 1000); | ||
446 | break; | 459 | break; |
447 | case Opt_mount_timeout: | 460 | case Opt_mount_timeout: |
448 | opt->mount_timeout = intval; | 461 | /* 0 is "wait forever" (i.e. infinite timeout) */ |
462 | if (intval < 0 || intval > INT_MAX / 1000) { | ||
463 | pr_err("mount_timeout out of range\n"); | ||
464 | err = -EINVAL; | ||
465 | goto out; | ||
466 | } | ||
467 | opt->mount_timeout = msecs_to_jiffies(intval * 1000); | ||
449 | break; | 468 | break; |
450 | 469 | ||
451 | case Opt_share: | 470 | case Opt_share: |
@@ -512,12 +531,14 @@ int ceph_print_client_options(struct seq_file *m, struct ceph_client *client) | |||
512 | seq_puts(m, "notcp_nodelay,"); | 531 | seq_puts(m, "notcp_nodelay,"); |
513 | 532 | ||
514 | if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) | 533 | if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) |
515 | seq_printf(m, "mount_timeout=%d,", opt->mount_timeout); | 534 | seq_printf(m, "mount_timeout=%d,", |
535 | jiffies_to_msecs(opt->mount_timeout) / 1000); | ||
516 | if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT) | 536 | if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT) |
517 | seq_printf(m, "osd_idle_ttl=%d,", opt->osd_idle_ttl); | 537 | seq_printf(m, "osd_idle_ttl=%d,", |
538 | jiffies_to_msecs(opt->osd_idle_ttl) / 1000); | ||
518 | if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT) | 539 | if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT) |
519 | seq_printf(m, "osdkeepalivetimeout=%d,", | 540 | seq_printf(m, "osdkeepalivetimeout=%d,", |
520 | opt->osd_keepalive_timeout); | 541 | jiffies_to_msecs(opt->osd_keepalive_timeout) / 1000); |
521 | 542 | ||
522 | /* drop redundant comma */ | 543 | /* drop redundant comma */ |
523 | if (m->count != pos) | 544 | if (m->count != pos) |
@@ -627,7 +648,7 @@ static int have_mon_and_osd_map(struct ceph_client *client) | |||
627 | int __ceph_open_session(struct ceph_client *client, unsigned long started) | 648 | int __ceph_open_session(struct ceph_client *client, unsigned long started) |
628 | { | 649 | { |
629 | int err; | 650 | int err; |
630 | unsigned long timeout = client->options->mount_timeout * HZ; | 651 | unsigned long timeout = client->options->mount_timeout; |
631 | 652 | ||
632 | /* open session, and wait for mon and osd maps */ | 653 | /* open session, and wait for mon and osd maps */ |
633 | err = ceph_monc_open_session(&client->monc); | 654 | err = ceph_monc_open_session(&client->monc); |
@@ -643,7 +664,7 @@ int __ceph_open_session(struct ceph_client *client, unsigned long started) | |||
643 | dout("mount waiting for mon_map\n"); | 664 | dout("mount waiting for mon_map\n"); |
644 | err = wait_event_interruptible_timeout(client->auth_wq, | 665 | err = wait_event_interruptible_timeout(client->auth_wq, |
645 | have_mon_and_osd_map(client) || (client->auth_err < 0), | 666 | have_mon_and_osd_map(client) || (client->auth_err < 0), |
646 | timeout); | 667 | ceph_timeout_jiffies(timeout)); |
647 | if (err == -EINTR || err == -ERESTARTSYS) | 668 | if (err == -EINTR || err == -ERESTARTSYS) |
648 | return err; | 669 | return err; |
649 | if (client->auth_err < 0) | 670 | if (client->auth_err < 0) |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 2b3cf05e87b0..0da3bdc116f7 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
@@ -298,6 +298,12 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) | |||
298 | } | 298 | } |
299 | EXPORT_SYMBOL(ceph_monc_request_next_osdmap); | 299 | EXPORT_SYMBOL(ceph_monc_request_next_osdmap); |
300 | 300 | ||
301 | /* | ||
302 | * Wait for an osdmap with a given epoch. | ||
303 | * | ||
304 | * @epoch: epoch to wait for | ||
305 | * @timeout: in jiffies, 0 means "wait forever" | ||
306 | */ | ||
301 | int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch, | 307 | int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch, |
302 | unsigned long timeout) | 308 | unsigned long timeout) |
303 | { | 309 | { |
@@ -308,11 +314,12 @@ int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch, | |||
308 | while (monc->have_osdmap < epoch) { | 314 | while (monc->have_osdmap < epoch) { |
309 | mutex_unlock(&monc->mutex); | 315 | mutex_unlock(&monc->mutex); |
310 | 316 | ||
311 | if (timeout != 0 && time_after_eq(jiffies, started + timeout)) | 317 | if (timeout && time_after_eq(jiffies, started + timeout)) |
312 | return -ETIMEDOUT; | 318 | return -ETIMEDOUT; |
313 | 319 | ||
314 | ret = wait_event_interruptible_timeout(monc->client->auth_wq, | 320 | ret = wait_event_interruptible_timeout(monc->client->auth_wq, |
315 | monc->have_osdmap >= epoch, timeout); | 321 | monc->have_osdmap >= epoch, |
322 | ceph_timeout_jiffies(timeout)); | ||
316 | if (ret < 0) | 323 | if (ret < 0) |
317 | return ret; | 324 | return ret; |
318 | 325 | ||
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 4cb4fab46e4f..50033677c0fa 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1097,7 +1097,7 @@ static void __move_osd_to_lru(struct ceph_osd_client *osdc, | |||
1097 | BUG_ON(!list_empty(&osd->o_osd_lru)); | 1097 | BUG_ON(!list_empty(&osd->o_osd_lru)); |
1098 | 1098 | ||
1099 | list_add_tail(&osd->o_osd_lru, &osdc->osd_lru); | 1099 | list_add_tail(&osd->o_osd_lru, &osdc->osd_lru); |
1100 | osd->lru_ttl = jiffies + osdc->client->options->osd_idle_ttl * HZ; | 1100 | osd->lru_ttl = jiffies + osdc->client->options->osd_idle_ttl; |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | static void maybe_move_osd_to_lru(struct ceph_osd_client *osdc, | 1103 | static void maybe_move_osd_to_lru(struct ceph_osd_client *osdc, |
@@ -1208,7 +1208,7 @@ static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o) | |||
1208 | static void __schedule_osd_timeout(struct ceph_osd_client *osdc) | 1208 | static void __schedule_osd_timeout(struct ceph_osd_client *osdc) |
1209 | { | 1209 | { |
1210 | schedule_delayed_work(&osdc->timeout_work, | 1210 | schedule_delayed_work(&osdc->timeout_work, |
1211 | osdc->client->options->osd_keepalive_timeout * HZ); | 1211 | osdc->client->options->osd_keepalive_timeout); |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | static void __cancel_osd_timeout(struct ceph_osd_client *osdc) | 1214 | static void __cancel_osd_timeout(struct ceph_osd_client *osdc) |
@@ -1576,10 +1576,9 @@ static void handle_timeout(struct work_struct *work) | |||
1576 | { | 1576 | { |
1577 | struct ceph_osd_client *osdc = | 1577 | struct ceph_osd_client *osdc = |
1578 | container_of(work, struct ceph_osd_client, timeout_work.work); | 1578 | container_of(work, struct ceph_osd_client, timeout_work.work); |
1579 | struct ceph_options *opts = osdc->client->options; | ||
1579 | struct ceph_osd_request *req; | 1580 | struct ceph_osd_request *req; |
1580 | struct ceph_osd *osd; | 1581 | struct ceph_osd *osd; |
1581 | unsigned long keepalive = | ||
1582 | osdc->client->options->osd_keepalive_timeout * HZ; | ||
1583 | struct list_head slow_osds; | 1582 | struct list_head slow_osds; |
1584 | dout("timeout\n"); | 1583 | dout("timeout\n"); |
1585 | down_read(&osdc->map_sem); | 1584 | down_read(&osdc->map_sem); |
@@ -1595,7 +1594,8 @@ static void handle_timeout(struct work_struct *work) | |||
1595 | */ | 1594 | */ |
1596 | INIT_LIST_HEAD(&slow_osds); | 1595 | INIT_LIST_HEAD(&slow_osds); |
1597 | list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) { | 1596 | list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) { |
1598 | if (time_before(jiffies, req->r_stamp + keepalive)) | 1597 | if (time_before(jiffies, |
1598 | req->r_stamp + opts->osd_keepalive_timeout)) | ||
1599 | break; | 1599 | break; |
1600 | 1600 | ||
1601 | osd = req->r_osd; | 1601 | osd = req->r_osd; |
@@ -1622,8 +1622,7 @@ static void handle_osds_timeout(struct work_struct *work) | |||
1622 | struct ceph_osd_client *osdc = | 1622 | struct ceph_osd_client *osdc = |
1623 | container_of(work, struct ceph_osd_client, | 1623 | container_of(work, struct ceph_osd_client, |
1624 | osds_timeout_work.work); | 1624 | osds_timeout_work.work); |
1625 | unsigned long delay = | 1625 | unsigned long delay = osdc->client->options->osd_idle_ttl / 4; |
1626 | osdc->client->options->osd_idle_ttl * HZ >> 2; | ||
1627 | 1626 | ||
1628 | dout("osds timeout\n"); | 1627 | dout("osds timeout\n"); |
1629 | down_read(&osdc->map_sem); | 1628 | down_read(&osdc->map_sem); |
@@ -2628,7 +2627,7 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) | |||
2628 | osdc->event_count = 0; | 2627 | osdc->event_count = 0; |
2629 | 2628 | ||
2630 | schedule_delayed_work(&osdc->osds_timeout_work, | 2629 | schedule_delayed_work(&osdc->osds_timeout_work, |
2631 | round_jiffies_relative(osdc->client->options->osd_idle_ttl * HZ)); | 2630 | round_jiffies_relative(osdc->client->options->osd_idle_ttl)); |
2632 | 2631 | ||
2633 | err = -ENOMEM; | 2632 | err = -ENOMEM; |
2634 | osdc->req_mempool = mempool_create_kmalloc_pool(10, | 2633 | osdc->req_mempool = mempool_create_kmalloc_pool(10, |