-struct ost_prolong_data {
- struct obd_export *opd_exp;
- ldlm_policy_data_t opd_policy;
- 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)
-{
- struct ost_prolong_data *opd = data;
-
- LASSERT(lock->l_resource->lr_type == LDLM_EXTENT);
-
- if (lock->l_req_mode != lock->l_granted_mode) {
- /* scan granted locks only */
- return LDLM_ITER_STOP;
- }
-
- if (lock->l_export != opd->opd_exp) {
- /* prolong locks only for given client */
- return LDLM_ITER_CONTINUE;
- }
-
- if (!(lock->l_granted_mode & opd->opd_mode)) {
- /* we aren't interesting in all type of locks */
- return LDLM_ITER_CONTINUE;
- }
-
- if (lock->l_policy_data.l_extent.end < opd->opd_policy.l_extent.start ||
- lock->l_policy_data.l_extent.start > opd->opd_policy.l_extent.end) {
- /* the request doesn't cross the lock, skip it */
- return LDLM_ITER_CONTINUE;
- }
-
- /* Fill the obdo with the matched lock handle.
- * XXX: it is possible in some cases the IO RPC is covered by several
- * locks, even for the write case, so it may need to be a lock list. */
- if (opd->opd_oa && !(opd->opd_oa->o_valid & OBD_MD_FLHANDLE)) {
- opd->opd_oa->o_handle.cookie = lock->l_handle.h_cookie;
- opd->opd_oa->o_valid |= OBD_MD_FLHANDLE;
- }
-
- if (!(lock->l_flags & LDLM_FL_AST_SENT)) {
- /* ignore locks not being cancelled */
- return LDLM_ITER_CONTINUE;
- }
-
- CDEBUG(D_DLMTRACE,"refresh lock: "LPU64"/"LPU64" ("LPU64"->"LPU64")\n",
- lock->l_resource->lr_name.name[0],
- lock->l_resource->lr_name.name[1],
- opd->opd_policy.l_extent.start, opd->opd_policy.l_extent.end);
- /* OK. this is a possible lock the user holds doing I/O
- * let's refresh eviction timer for it */
- ldlm_refresh_waiting_lock(lock, opd->opd_timeout);
- opd->opd_lock_match = 1;
-
- return LDLM_ITER_CONTINUE;
-}
-
-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)
-{
- struct ldlm_res_id res_id;
- int nrbufs = obj->ioo_bufcnt;
- struct ost_prolong_data opd = { 0 };
- ENTRY;
-
- osc_build_res_name(obj->ioo_id, obj->ioo_seq, &res_id);
-
- opd.opd_mode = mode;
- 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_INFO,"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);
-
- if (oa->o_valid & OBD_MD_FLHANDLE) {
- struct ldlm_lock *lock;
-
- lock = ldlm_handle2lock(&oa->o_handle);
- if (lock != NULL) {
- ost_prolong_locks_iter(lock, &opd);
- if (opd.opd_lock_match) {
- LDLM_LOCK_PUT(lock);
- RETURN(1);
- }
-
- /* Check if the lock covers the whole IO region,
- * otherwise iterate through the resource. */
- if (lock->l_policy_data.l_extent.end >=
- opd.opd_policy.l_extent.end &&
- lock->l_policy_data.l_extent.start <=
- opd.opd_policy.l_extent.start) {
- LDLM_LOCK_PUT(lock);
- RETURN(0);
- }
- LDLM_LOCK_PUT(lock);
- }
- }
-
- opd.opd_oa = oa;
- ldlm_resource_iterate(req->rq_export->exp_obd->obd_namespace, &res_id,
- ost_prolong_locks_iter, &opd);
- RETURN(opd.opd_lock_match);
-}
-