+/*
+ * Calculate timeout value for a target.
+ */
+void server_calc_timeout(struct lustre_sb_info *lsi, struct obd_device *obd)
+{
+ struct lustre_mount_data *lmd;
+ int soft = 0;
+ int hard = 0;
+ int factor = 0;
+ bool has_ir = !!(lsi->lsi_flags & LSI_IR_CAPABLE);
+ int min = OBD_RECOVERY_TIME_MIN;
+
+ LASSERT(lsi->lsi_flags & LSI_SERVER);
+
+ lmd = lsi->lsi_lmd;
+ if (lmd) {
+ soft = lmd->lmd_recovery_time_soft;
+ hard = lmd->lmd_recovery_time_hard;
+ has_ir = has_ir && !(lmd->lmd_flags & LMD_FLG_NOIR);
+ obd->obd_no_ir = !has_ir;
+ }
+
+ if (soft == 0)
+ soft = OBD_RECOVERY_TIME_SOFT;
+ if (hard == 0)
+ hard = OBD_RECOVERY_TIME_HARD;
+
+ /* target may have ir_factor configured. */
+ factor = OBD_IR_FACTOR_DEFAULT;
+ if (obd->obd_recovery_ir_factor)
+ factor = obd->obd_recovery_ir_factor;
+
+ if (has_ir) {
+ int new_soft = soft;
+ int new_hard = hard;
+
+ /* adjust timeout value by imperative recovery */
+
+ new_soft = (soft * factor) / OBD_IR_FACTOR_MAX;
+ new_hard = (hard * factor) / OBD_IR_FACTOR_MAX;
+
+ /* make sure the timeout is not too short */
+ new_soft = max(min, new_soft);
+ new_hard = max(new_soft, new_hard);
+
+ LCONSOLE_INFO("%s: Imperative Recovery enabled, recovery "
+ "window shrunk from %d-%d down to %d-%d\n",
+ obd->obd_name, soft, hard, new_soft, new_hard);
+
+ soft = new_soft;
+ hard = new_hard;
+ }
+
+ /* we're done */
+ obd->obd_recovery_timeout = soft;
+ obd->obd_recovery_time_hard = hard;
+ obd->obd_recovery_ir_factor = factor;
+}
+EXPORT_SYMBOL(server_calc_timeout);
+