diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index 994f2e562948bcce076a756308dadf929bb7ad91..ad03134b49861d45f253a3ff8ee14f27dfa4aa0b 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -697,7 +697,7 @@ int ldlm_handle_cancel(struct ptlrpc_request *req); int ldlm_request_cancel(struct ptlrpc_request *req, struct ldlm_request *dlm_req, int first); int ldlm_del_waiting_lock(struct ldlm_lock *lock); -int ldlm_refresh_waiting_lock(struct ldlm_lock *lock); +int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout); int ldlm_get_ref(void); void ldlm_put_ref(void); int ldlm_init_export(struct obd_export *exp); diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index df3d12051edaf2b44d9a83cbcf55db41aa05d94b..08ea85fa8d63fc57c89e5551d828b549056250fd 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -285,7 +285,8 @@ static void waiting_locks_callback(unsigned long unused) LDLM_LOCK_GET(lock); spin_unlock_bh(&waiting_locks_spinlock); LDLM_DEBUG(lock, "prolong the busy lock"); - ldlm_refresh_waiting_lock(lock); + ldlm_refresh_waiting_lock(lock, + ldlm_get_enq_timeout(lock)); spin_lock_bh(&waiting_locks_spinlock); if (!cont) { @@ -362,7 +363,7 @@ static void waiting_locks_callback(unsigned long unused) * * Called with the namespace lock held. */ -static int __ldlm_add_waiting_lock(struct ldlm_lock *lock) +static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, int seconds) { cfs_time_t timeout; cfs_time_t timeout_rounded; @@ -372,11 +373,9 @@ static int __ldlm_add_waiting_lock(struct ldlm_lock *lock) if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT) || OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT)) - timeout = 2; - else - timeout = ldlm_get_enq_timeout(lock); + seconds = 2; - timeout = cfs_time_shift(timeout); + timeout = cfs_time_shift(seconds); if (likely(cfs_time_after(timeout, lock->l_callback_timeout))) lock->l_callback_timeout = timeout; @@ -411,7 +410,7 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock) return 0; } - ret = __ldlm_add_waiting_lock(lock); + ret = __ldlm_add_waiting_lock(lock, ldlm_get_enq_timeout(lock)); if (ret) /* grab ref on the lock if it has been added to the * waiting list */ @@ -485,7 +484,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock) * * Called with namespace lock held. */ -int ldlm_refresh_waiting_lock(struct ldlm_lock *lock) +int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout) { if (lock->l_export == NULL) { /* We don't have a "waiting locks list" on clients. */ @@ -504,7 +503,7 @@ int ldlm_refresh_waiting_lock(struct ldlm_lock *lock) /* we remove/add the lock to the waiting list, so no needs to * release/take a lock reference */ __ldlm_del_waiting_lock(lock); - __ldlm_add_waiting_lock(lock); + __ldlm_add_waiting_lock(lock, timeout); spin_unlock_bh(&waiting_locks_spinlock); LDLM_DEBUG(lock, "refreshed"); @@ -523,7 +522,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock) RETURN(0); } -int ldlm_refresh_waiting_lock(struct ldlm_lock *lock) +int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout) { RETURN(0); } diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 4e7cee04088d2de912288c97849d5f247e011267..f84d6960d267852fd41ff8836860bcf910ab0a75 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -598,6 +598,7 @@ struct ost_prolong_data { struct obdo *opd_oa; ldlm_mode_t opd_mode; int opd_lock_match; + int opd_timeout; }; static int ost_prolong_locks_iter(struct ldlm_lock *lock, void *data) @@ -642,13 +643,13 @@ static int ost_prolong_locks_iter(struct ldlm_lock *lock, void *data) /* OK. this is a possible lock the user holds doing I/O * let's refresh eviction timer for it */ - ldlm_refresh_waiting_lock(lock); + ldlm_refresh_waiting_lock(lock, opd->opd_timeout); opd->opd_lock_match = 1; return LDLM_ITER_CONTINUE; } -static int ost_rw_prolong_locks(struct obd_export *exp, struct obd_ioobj *obj, +static int ost_rw_prolong_locks(struct ptlrpc_request *req, struct obd_ioobj *obj, struct niobuf_remote *nb, struct obdo *oa, ldlm_mode_t mode) { @@ -659,11 +660,17 @@ static int ost_rw_prolong_locks(struct obd_export *exp, struct obd_ioobj *obj, ENTRY; opd.opd_mode = mode; - opd.opd_exp = exp; + opd.opd_exp = req->rq_export; opd.opd_policy.l_extent.start = nb[0].offset & CFS_PAGE_MASK; opd.opd_policy.l_extent.end = (nb[nrbufs - 1].offset + nb[nrbufs - 1].len - 1) | ~CFS_PAGE_MASK; + /* prolong locks for the current service time of the corresponding + * portal (= OST_IO_PORTAL) */ + opd.opd_timeout = AT_OFF ? obd_timeout / 2 : + max(at_est2timeout(at_get(&req->rq_rqbd-> + rqbd_service->srv_at_estimate)), ldlm_timeout); + CDEBUG(D_DLMTRACE,"refresh locks: "LPU64"/"LPU64" ("LPU64"->"LPU64")\n", res_id.name[0], res_id.name[1], opd.opd_policy.l_extent.start, opd.opd_policy.l_extent.end); @@ -693,7 +700,7 @@ static int ost_rw_prolong_locks(struct obd_export *exp, struct obd_ioobj *obj, } opd.opd_oa = oa; - ldlm_resource_iterate(exp->exp_obd->obd_namespace, &res_id, + ldlm_resource_iterate(req->rq_export->exp_obd->obd_namespace, &res_id, ost_prolong_locks_iter, &opd); RETURN(opd.opd_lock_match); } @@ -798,7 +805,7 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) if (rc != 0) GOTO(out_lock, rc); - ost_rw_prolong_locks(exp, ioo, pp_rnb, &body->oa, LCK_PW | LCK_PR); + ost_rw_prolong_locks(req, ioo, pp_rnb, &body->oa, LCK_PW | LCK_PR); nob = 0; for (i = 0; i < npages; i++) { @@ -1064,7 +1071,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) GOTO(out_lock, rc = -ETIMEDOUT); } - ost_rw_prolong_locks(exp, ioo, pp_rnb, &body->oa, LCK_PW); + ost_rw_prolong_locks(req, ioo, pp_rnb, &body->oa, LCK_PW); /* obd_preprw clobbers oa->valid, so save what we need */ if (body->oa.o_valid & OBD_MD_FLCKSUM) { @@ -1586,10 +1593,10 @@ static int ost_rw_hpreq_check(struct ptlrpc_request *req) mode = LCK_PW; if (opc == OST_READ) mode |= LCK_PR; - RETURN(ost_rw_prolong_locks(req->rq_export, ioo, nb, &body->oa, mode)); + RETURN(ost_rw_prolong_locks(req, ioo, nb, &body->oa, mode)); } -static int ost_punch_prolong_locks(struct obd_export *exp, struct obdo *oa) +static int ost_punch_prolong_locks(struct ptlrpc_request *req, struct obdo *oa) { struct ldlm_res_id res_id = { .name = { oa->o_id } }; struct ost_prolong_data opd = { 0 }; @@ -1600,19 +1607,25 @@ static int ost_punch_prolong_locks(struct obd_export *exp, struct obdo *oa) end = start + oa->o_blocks; opd.opd_mode = LCK_PW; - opd.opd_exp = exp; + opd.opd_exp = req->rq_export; opd.opd_policy.l_extent.start = start & CFS_PAGE_MASK; if (oa->o_blocks == OBD_OBJECT_EOF || end < start) opd.opd_policy.l_extent.end = OBD_OBJECT_EOF; else opd.opd_policy.l_extent.end = end | ~CFS_PAGE_MASK; + /* prolong locks for the current service time of the corresponding + * portal (= OST_IO_PORTAL) */ + opd.opd_timeout = AT_OFF ? obd_timeout / 2 : + max(at_est2timeout(at_get(&req->rq_rqbd-> + rqbd_service->srv_at_estimate)), ldlm_timeout); + CDEBUG(D_DLMTRACE,"refresh locks: "LPU64"/"LPU64" ("LPU64"->"LPU64")\n", res_id.name[0], res_id.name[1], opd.opd_policy.l_extent.start, opd.opd_policy.l_extent.end); opd.opd_oa = oa; - ldlm_resource_iterate(exp->exp_obd->obd_namespace, &res_id, + ldlm_resource_iterate(req->rq_export->exp_obd->obd_namespace, &res_id, ost_prolong_locks_iter, &opd); RETURN(opd.opd_lock_match); } @@ -1641,7 +1654,7 @@ static int ost_punch_hpreq_check(struct ptlrpc_request *req) LASSERT(!(body->oa.o_valid & OBD_MD_FLFLAGS) || !(body->oa.o_flags & OBD_FL_TRUNCLOCK)); - RETURN(ost_punch_prolong_locks(req->rq_export, &body->oa)); + RETURN(ost_punch_prolong_locks(req, &body->oa)); } struct ptlrpc_hpreq_ops ost_hpreq_rw = {