int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data, struct lookup_intent *it, struct ptlrpc_request **reqp, ldlm_blocking_callback cb_blocking, __u64 extra_lock_flags) { struct obd_device *obd = exp->exp_obd; int rc; ENTRY; LASSERT(it != NULL); LASSERT(fid_is_sane(&op_data->op_fid1)); CDEBUG(D_INODE, "INTENT LOCK '%s' for "DFID" '%.*s' on "DFID"\n", LL_IT2STR(it), PFID(&op_data->op_fid2), (int)op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1)); rc = lmv_check_connect(obd); if (rc) RETURN(rc); if (it->it_op & (IT_LOOKUP | IT_GETATTR | IT_LAYOUT)) rc = lmv_intent_lookup(exp, op_data, it, reqp, cb_blocking, extra_lock_flags); else if (it->it_op & IT_OPEN) rc = lmv_intent_open(exp, op_data, it, reqp, cb_blocking, extra_lock_flags); else LBUG(); if (rc < 0) { struct lustre_handle lock_handle; if (it->d.lustre.it_lock_mode != 0) { lock_handle.cookie = it->d.lustre.it_lock_handle; ldlm_lock_decref(&lock_handle, it->d.lustre.it_lock_mode); } it->d.lustre.it_lock_handle = 0; it->d.lustre.it_lock_mode = 0; if (it->d.lustre.it_remote_lock_mode != 0) { lock_handle.cookie = it->d.lustre.it_remote_lock_handle; ldlm_lock_decref(&lock_handle, it->d.lustre.it_remote_lock_mode); } it->d.lustre.it_remote_lock_handle = 0; it->d.lustre.it_remote_lock_mode = 0; } RETURN(rc); }
int mdc_dom_lock_match(const struct lu_env *env, struct obd_export *exp, struct ldlm_res_id *res_id, enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, __u64 *flags, void *data, struct lustre_handle *lockh, int unref) { struct obd_device *obd = exp->exp_obd; __u64 lflags = *flags; enum ldlm_mode rc; ENTRY; rc = ldlm_lock_match(obd->obd_namespace, lflags, res_id, type, policy, mode, lockh, unref); if (rc == 0 || lflags & LDLM_FL_TEST_LOCK) RETURN(rc); if (data != NULL) { struct ldlm_lock *lock = ldlm_handle2lock(lockh); LASSERT(lock != NULL); if (!mdc_set_dom_lock_data(env, lock, data)) { ldlm_lock_decref(lockh, rc); rc = 0; } LDLM_LOCK_PUT(lock); } RETURN(rc); }
static int osc_io_read_ahead(const struct lu_env *env, const struct cl_io_slice *ios, pgoff_t start, struct cl_read_ahead *ra) { struct osc_object *osc = cl2osc(ios->cis_obj); struct ldlm_lock *dlmlock; int result = -ENODATA; ENTRY; dlmlock = osc_dlmlock_at_pgoff(env, osc, start, 0); if (dlmlock != NULL) { if (dlmlock->l_req_mode != LCK_PR) { struct lustre_handle lockh; ldlm_lock2handle(dlmlock, &lockh); ldlm_lock_addref(&lockh, LCK_PR); ldlm_lock_decref(&lockh, dlmlock->l_req_mode); } ra->cra_end = cl_index(osc2cl(osc), dlmlock->l_policy_data.l_extent.end); ra->cra_release = osc_read_ahead_release; ra->cra_cbdata = dlmlock; result = 0; } RETURN(result); }
static void mdt_rename_unlock(struct lustre_handle *lh) { ENTRY; LASSERT(lustre_handle_is_used(lh)); ldlm_lock_decref(lh, LCK_EX); EXIT; }
static int llu_dir_do_readpage(struct inode *inode, struct page *page) { struct llu_inode_info *lli = llu_i2info(inode); struct intnl_stat *st = llu_i2stat(inode); struct llu_sb_info *sbi = llu_i2sbi(inode); struct ptlrpc_request *request; struct lustre_handle lockh; struct mdt_body *body; struct lookup_intent it = { .it_op = IT_READDIR }; struct md_op_data op_data = {{ 0 }}; ldlm_policy_data_t policy = { .l_inodebits = { MDS_INODELOCK_UPDATE } }; int rc = 0; ENTRY; llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, 0, LUSTRE_OPC_ANY); rc = md_lock_match(sbi->ll_md_exp, LDLM_FL_BLOCK_GRANTED, &lli->lli_fid, LDLM_IBITS, &policy, LCK_CR, &lockh); if (!rc) { struct ldlm_enqueue_info einfo = { .ei_type = LDLM_IBITS, .ei_mode = LCK_CR, .ei_cb_bl = llu_md_blocking_ast, .ei_cb_cp = ldlm_completion_ast, .ei_cbdata = inode, }; rc = md_enqueue(sbi->ll_md_exp, &einfo, &it, &op_data, &lockh, NULL, 0, NULL, LDLM_FL_CANCEL_ON_BLOCK); request = (struct ptlrpc_request *)it.d.lustre.it_data; if (request) ptlrpc_req_finished(request); if (rc < 0) { CERROR("lock enqueue: err: %d\n", rc); RETURN(rc); } } ldlm_lock_dump_handle(D_OTHER, &lockh); op_data.op_offset = (__u64)hash_x_index(page->index, 0); op_data.op_npages = 1; rc = md_readpage(sbi->ll_md_exp, &op_data, &page, &request); if (!rc) { body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); LASSERT(body != NULL); /* checked by md_readpage() */ if (body->valid & OBD_MD_FLSIZE) st->st_size = body->size; } else { CERROR("read_dir_page(%ld) error %d\n", page->index, rc); } ptlrpc_req_finished(request); EXIT; ldlm_lock_decref(&lockh, LCK_CR); return rc; }
static void osc_read_ahead_release(const struct lu_env *env, void *cbdata) { struct ldlm_lock *dlmlock = cbdata; struct lustre_handle lockh; ldlm_lock2handle(dlmlock, &lockh); ldlm_lock_decref(&lockh, LCK_PR); LDLM_LOCK_PUT(dlmlock); }
/** * Implementation of dt_object_operations::do_object_unlock * * Cancel a lock of a remote object. * * \param[in] env execution environment * \param[in] dt object to be unlocked * \param[in] einfo lock enqueue information * \param[in] policy lock policy * * \retval Only return 0 for now. */ static int osp_md_object_unlock(const struct lu_env *env, struct dt_object *dt, struct ldlm_enqueue_info *einfo, union ldlm_policy_data *policy) { struct lustre_handle *lockh = einfo->ei_cbdata; /* unlock finally */ ldlm_lock_decref(lockh, einfo->ei_mode); return 0; }
void ll_intent_drop_lock(struct lookup_intent *it) { struct lustre_handle *handle; if (it->it_op && it->d.lustre.it_lock_mode) { handle = (struct lustre_handle *)&it->d.lustre.it_lock_handle; CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64 " from it %p\n", handle->cookie, it); ldlm_lock_decref(handle, it->d.lustre.it_lock_mode); /* bug 494: intent_release may be called multiple times, from * this thread and we don't want to double-decref this lock */ it->d.lustre.it_lock_mode = 0; } }
static int lmv_intent_remote(struct obd_export *exp, struct lookup_intent *it, const struct lu_fid *parent_fid, struct ptlrpc_request **reqp, ldlm_blocking_callback cb_blocking, __u64 extra_lock_flags) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct ptlrpc_request *req = NULL; struct lustre_handle plock; struct md_op_data *op_data; struct lmv_tgt_desc *tgt; struct mdt_body *body; int pmode; int rc = 0; ENTRY; body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY); if (body == NULL) RETURN(-EPROTO); LASSERT((body->mbo_valid & OBD_MD_MDS)); /* * Unfortunately, we have to lie to MDC/MDS to retrieve * attributes llite needs and provideproper locking. */ if (it->it_op & IT_LOOKUP) it->it_op = IT_GETATTR; /* * We got LOOKUP lock, but we really need attrs. */ pmode = it->d.lustre.it_lock_mode; if (pmode) { plock.cookie = it->d.lustre.it_lock_handle; it->d.lustre.it_lock_mode = 0; it->d.lustre.it_data = NULL; } LASSERT(fid_is_sane(&body->mbo_fid1)); tgt = lmv_find_target(lmv, &body->mbo_fid1); if (IS_ERR(tgt)) GOTO(out, rc = PTR_ERR(tgt)); OBD_ALLOC_PTR(op_data); if (op_data == NULL) GOTO(out, rc = -ENOMEM); op_data->op_fid1 = body->mbo_fid1; /* Sent the parent FID to the remote MDT */ if (parent_fid != NULL) { /* The parent fid is only for remote open to * check whether the open is from OBF, * see mdt_cross_open */ LASSERT(it->it_op & IT_OPEN); op_data->op_fid2 = *parent_fid; } op_data->op_bias = MDS_CROSS_REF; CDEBUG(D_INODE, "REMOTE_INTENT with fid="DFID" -> mds #%u\n", PFID(&body->mbo_fid1), tgt->ltd_idx); rc = md_intent_lock(tgt->ltd_exp, op_data, it, &req, cb_blocking, extra_lock_flags); if (rc) GOTO(out_free_op_data, rc); /* * LLite needs LOOKUP lock to track dentry revocation in order to * maintain dcache consistency. Thus drop UPDATE|PERM lock here * and put LOOKUP in request. */ if (it->d.lustre.it_lock_mode != 0) { it->d.lustre.it_remote_lock_handle = it->d.lustre.it_lock_handle; it->d.lustre.it_remote_lock_mode = it->d.lustre.it_lock_mode; } if (pmode) { it->d.lustre.it_lock_handle = plock.cookie; it->d.lustre.it_lock_mode = pmode; } EXIT; out_free_op_data: OBD_FREE_PTR(op_data); out: if (rc && pmode) ldlm_lock_decref(&plock, pmode); ptlrpc_req_finished(*reqp); *reqp = req; return rc; }
int lmv_revalidate_slaves(struct obd_export *exp, const struct lmv_stripe_md *lsm, ldlm_blocking_callback cb_blocking, int extra_lock_flags) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct ptlrpc_request *req = NULL; struct mdt_body *body; struct md_op_data *op_data; int i; int rc = 0; ENTRY; /** * revalidate slaves has some problems, temporarily return, * we may not need that */ OBD_ALLOC_PTR(op_data); if (op_data == NULL) RETURN(-ENOMEM); /** * Loop over the stripe information, check validity and update them * from MDS if needed. */ for (i = 0; i < lsm->lsm_md_stripe_count; i++) { struct lu_fid fid; struct lookup_intent it = { .it_op = IT_GETATTR }; struct lustre_handle *lockh = NULL; struct lmv_tgt_desc *tgt = NULL; struct inode *inode; fid = lsm->lsm_md_oinfo[i].lmo_fid; inode = lsm->lsm_md_oinfo[i].lmo_root; /* * Prepare op_data for revalidating. Note that @fid2 shluld be * defined otherwise it will go to server and take new lock * which is not needed here. */ memset(op_data, 0, sizeof(*op_data)); op_data->op_fid1 = fid; op_data->op_fid2 = fid; tgt = lmv_locate_mds(lmv, op_data, &fid); if (IS_ERR(tgt)) GOTO(cleanup, rc = PTR_ERR(tgt)); CDEBUG(D_INODE, "Revalidate slave "DFID" -> mds #%u\n", PFID(&fid), tgt->ltd_idx); if (req != NULL) { ptlrpc_req_finished(req); req = NULL; } rc = md_intent_lock(tgt->ltd_exp, op_data, &it, &req, cb_blocking, extra_lock_flags); if (rc < 0) GOTO(cleanup, rc); lockh = (struct lustre_handle *)&it.d.lustre.it_lock_handle; if (rc > 0 && req == NULL) { /* slave inode is still valid */ CDEBUG(D_INODE, "slave "DFID" is still valid.\n", PFID(&fid)); rc = 0; } else { /* refresh slave from server */ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); if (body == NULL) { if (it.d.lustre.it_lock_mode && lockh) { ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode); it.d.lustre.it_lock_mode = 0; } GOTO(cleanup, rc = -ENOENT); } i_size_write(inode, body->mbo_size); inode->i_blocks = body->mbo_blocks; set_nlink(inode, body->mbo_nlink); LTIME_S(inode->i_atime) = body->mbo_atime; LTIME_S(inode->i_ctime) = body->mbo_ctime; LTIME_S(inode->i_mtime) = body->mbo_mtime; } md_set_lock_data(tgt->ltd_exp, &lockh->cookie, inode, NULL); if (it.d.lustre.it_lock_mode != 0 && lockh != NULL) { ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode); it.d.lustre.it_lock_mode = 0; } } cleanup: if (req != NULL) ptlrpc_req_finished(req); OBD_FREE_PTR(op_data); RETURN(rc); }
static int osc_object_fiemap(const struct lu_env *env, struct cl_object *obj, struct ll_fiemap_info_key *fmkey, struct fiemap *fiemap, size_t *buflen) { struct obd_export *exp = osc_export(cl2osc(obj)); struct ldlm_res_id resid; union ldlm_policy_data policy; struct lustre_handle lockh; enum ldlm_mode mode = LCK_MINMODE; struct ptlrpc_request *req; struct fiemap *reply; char *tmp; int rc; ENTRY; fmkey->lfik_oa.o_oi = cl2osc(obj)->oo_oinfo->loi_oi; if (!(fmkey->lfik_fiemap.fm_flags & FIEMAP_FLAG_SYNC)) goto skip_locking; policy.l_extent.start = fmkey->lfik_fiemap.fm_start & PAGE_MASK; if (OBD_OBJECT_EOF - fmkey->lfik_fiemap.fm_length <= fmkey->lfik_fiemap.fm_start + PAGE_SIZE - 1) policy.l_extent.end = OBD_OBJECT_EOF; else policy.l_extent.end = (fmkey->lfik_fiemap.fm_start + fmkey->lfik_fiemap.fm_length + PAGE_SIZE - 1) & PAGE_MASK; ostid_build_res_name(&fmkey->lfik_oa.o_oi, &resid); mode = ldlm_lock_match(exp->exp_obd->obd_namespace, LDLM_FL_BLOCK_GRANTED | LDLM_FL_LVB_READY, &resid, LDLM_EXTENT, &policy, LCK_PR | LCK_PW, &lockh, 0); if (mode) { /* lock is cached on client */ if (mode != LCK_PR) { ldlm_lock_addref(&lockh, LCK_PR); ldlm_lock_decref(&lockh, LCK_PW); } } else { /* no cached lock, needs acquire lock on server side */ fmkey->lfik_oa.o_valid |= OBD_MD_FLFLAGS; fmkey->lfik_oa.o_flags |= OBD_FL_SRVLOCK; } skip_locking: req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_GET_INFO_FIEMAP); if (req == NULL) GOTO(drop_lock, rc = -ENOMEM); req_capsule_set_size(&req->rq_pill, &RMF_FIEMAP_KEY, RCL_CLIENT, sizeof(*fmkey)); req_capsule_set_size(&req->rq_pill, &RMF_FIEMAP_VAL, RCL_CLIENT, *buflen); req_capsule_set_size(&req->rq_pill, &RMF_FIEMAP_VAL, RCL_SERVER, *buflen); rc = ptlrpc_request_pack(req, LUSTRE_OST_VERSION, OST_GET_INFO); if (rc != 0) { ptlrpc_request_free(req); GOTO(drop_lock, rc); } tmp = req_capsule_client_get(&req->rq_pill, &RMF_FIEMAP_KEY); memcpy(tmp, fmkey, sizeof(*fmkey)); tmp = req_capsule_client_get(&req->rq_pill, &RMF_FIEMAP_VAL); memcpy(tmp, fiemap, *buflen); ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); if (rc != 0) GOTO(fini_req, rc); reply = req_capsule_server_get(&req->rq_pill, &RMF_FIEMAP_VAL); if (reply == NULL) GOTO(fini_req, rc = -EPROTO); memcpy(fiemap, reply, *buflen); fini_req: ptlrpc_req_finished(req); drop_lock: if (mode) ldlm_lock_decref(&lockh, LCK_PR); RETURN(rc); }
/** * Callback function called when an acquire/release request sent to the master * is completed */ static void qsd_req_completion(const struct lu_env *env, struct qsd_qtype_info *qqi, struct quota_body *reqbody, struct quota_body *repbody, struct lustre_handle *lockh, struct lquota_lvb *lvb, void *arg, int ret) { struct lquota_entry *lqe = (struct lquota_entry *)arg; struct qsd_thread_info *qti; int rc; bool adjust = false, cancel = false; ENTRY; LASSERT(qqi != NULL && lqe != NULL); /* environment passed by ptlrpcd is mostly used by CLIO and hasn't the * DT tags set. */ rc = lu_env_refill_by_tags((struct lu_env *)env, LCT_DT_THREAD, 0); if (rc) { LQUOTA_ERROR(lqe, "failed to refill environmnent %d", rc); lqe_write_lock(lqe); /* can't afford to adjust quota space with no suitable lu_env */ GOTO(out_noadjust, rc); } qti = qsd_info(env); lqe_write_lock(lqe); LQUOTA_DEBUG(lqe, "DQACQ returned %d, flags:0x%x", ret, reqbody->qb_flags); /* despite -EDQUOT & -EINPROGRESS errors, the master might still * grant us back quota space to adjust quota overrun */ if (ret != 0 && ret != -EDQUOT && ret != -EINPROGRESS) { if (ret != -ETIMEDOUT && ret != -ENOTCONN && ret != -ESHUTDOWN && ret != -EAGAIN) /* print errors only if return code is unexpected */ LQUOTA_ERROR(lqe, "DQACQ failed with %d, flags:0x%x", ret, reqbody->qb_flags); GOTO(out, ret); } /* Set the lqe_lockh */ if (lustre_handle_is_used(lockh) && !lustre_handle_equal(lockh, &lqe->lqe_lockh)) lustre_handle_copy(&lqe->lqe_lockh, lockh); /* If the replied qb_count is zero, it means master didn't process * the DQACQ since the limit for this ID has been removed, so we * should not update quota entry & slave index copy neither. */ if (repbody != NULL && repbody->qb_count != 0) { LQUOTA_DEBUG(lqe, "DQACQ qb_count:"LPU64, repbody->qb_count); if (req_is_rel(reqbody->qb_flags)) { if (lqe->lqe_granted < repbody->qb_count) { LQUOTA_ERROR(lqe, "can't release more space " "than owned "LPU64"<"LPU64, lqe->lqe_granted, repbody->qb_count); lqe->lqe_granted = 0; } else { lqe->lqe_granted -= repbody->qb_count; } /* Cancel the per-ID lock initiatively when there * isn't any usage & grant, which can avoid master * sending glimpse unnecessarily to this slave on * quota revoking */ if (!lqe->lqe_pending_write && !lqe->lqe_granted && !lqe->lqe_waiting_write && !lqe->lqe_usage) cancel = true; } else { lqe->lqe_granted += repbody->qb_count; } qti->qti_rec.lqr_slv_rec.qsr_granted = lqe->lqe_granted; lqe_write_unlock(lqe); /* Update the slave index file in the dedicated thread. So far, * We don't update the version of slave index copy on DQACQ. * No locking is necessary since nobody can change * lqe->lqe_granted while lqe->lqe_pending_req > 0 */ qsd_upd_schedule(qqi, lqe, &lqe->lqe_id, &qti->qti_rec, 0, false); lqe_write_lock(lqe); } /* extract information from lvb */ if (ret == 0 && lvb != 0) { if (lvb->lvb_id_qunit != 0) qsd_set_qunit(lqe, lvb->lvb_id_qunit); qsd_set_edquot(lqe, !!(lvb->lvb_flags & LQUOTA_FL_EDQUOT)); } else if (repbody != NULL && repbody->qb_qunit != 0) { qsd_set_qunit(lqe, repbody->qb_qunit); } /* turn off pre-acquire if it failed with -EDQUOT. This is done to avoid * flooding the master with acquire request. Pre-acquire will be turned * on again as soon as qunit is modified */ if (req_is_preacq(reqbody->qb_flags) && ret == -EDQUOT) lqe->lqe_nopreacq = true; out: adjust = qsd_adjust_needed(lqe); if (reqbody && req_is_acq(reqbody->qb_flags) && ret != -EDQUOT) { lqe->lqe_acq_rc = ret; lqe->lqe_acq_time = cfs_time_current_64(); } out_noadjust: qsd_request_exit(lqe); lqe_write_unlock(lqe); /* release reference on per-ID lock */ if (lustre_handle_is_used(lockh)) ldlm_lock_decref(lockh, qsd_id_einfo.ei_mode); if (cancel) { qsd_adjust_schedule(lqe, false, true); } else if (adjust) { if (!ret || ret == -EDQUOT) qsd_adjust_schedule(lqe, false, false); else qsd_adjust_schedule(lqe, true, false); } lqe_putref(lqe); if (lvb) OBD_FREE_PTR(lvb); EXIT; }
int lmv_revalidate_slaves(struct obd_export *exp, struct mdt_body *mbody, struct lmv_stripe_md *lsm, ldlm_blocking_callback cb_blocking, int extra_lock_flags) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct mdt_body *body; struct md_op_data *op_data; unsigned long size = 0; unsigned long nlink = 0; obd_time atime = 0; obd_time ctime = 0; obd_time mtime = 0; int i; int rc = 0; ENTRY; /** * revalidate slaves has some problems, temporarily return, * we may not need that */ if (lsm->lsm_md_stripe_count <= 1) RETURN(0); OBD_ALLOC_PTR(op_data); if (op_data == NULL) RETURN(-ENOMEM); /** * Loop over the stripe information, check validity and update them * from MDS if needed. */ for (i = 0; i < lsm->lsm_md_stripe_count; i++) { struct lu_fid fid; struct lookup_intent it = { .it_op = IT_GETATTR }; struct ptlrpc_request *req = NULL; struct lustre_handle *lockh = NULL; struct lmv_tgt_desc *tgt = NULL; struct inode *inode; fid = lsm->lsm_md_oinfo[i].lmo_fid; inode = lsm->lsm_md_oinfo[i].lmo_root; if (i == 0) { if (mbody != NULL) { body = mbody; goto update; } else { goto release_lock; } } /* * Prepare op_data for revalidating. Note that @fid2 shluld be * defined otherwise it will go to server and take new lock * which is not needed here. */ memset(op_data, 0, sizeof(*op_data)); op_data->op_fid1 = fid; op_data->op_fid2 = fid; tgt = lmv_locate_mds(lmv, op_data, &fid); if (IS_ERR(tgt)) GOTO(cleanup, rc = PTR_ERR(tgt)); CDEBUG(D_INODE, "Revalidate slave "DFID" -> mds #%d\n", PFID(&fid), tgt->ltd_idx); rc = md_intent_lock(tgt->ltd_exp, op_data, NULL, 0, &it, 0, &req, cb_blocking, extra_lock_flags); if (rc < 0) GOTO(cleanup, rc); lockh = (struct lustre_handle *)&it.d.lustre.it_lock_handle; if (rc > 0 && req == NULL) { /* slave inode is still valid */ CDEBUG(D_INODE, "slave "DFID" is still valid.\n", PFID(&fid)); rc = 0; } else { /* refresh slave from server */ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); LASSERT(body != NULL); update: if (unlikely(body->nlink < 2)) { CERROR("%s: nlink %d < 2 corrupt stripe %d "DFID ":" DFID"\n", obd->obd_name, body->nlink, i, PFID(&lsm->lsm_md_oinfo[i].lmo_fid), PFID(&lsm->lsm_md_oinfo[0].lmo_fid)); if (req != NULL) ptlrpc_req_finished(req); if (it.d.lustre.it_lock_mode && lockh) { ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode); it.d.lustre.it_lock_mode = 0; } GOTO(cleanup, rc = -EIO); } if (i != 0) md_set_lock_data(tgt->ltd_exp, &lockh->cookie, inode, NULL); i_size_write(inode, body->size); set_nlink(inode, body->nlink); LTIME_S(inode->i_atime) = body->atime; LTIME_S(inode->i_ctime) = body->ctime; LTIME_S(inode->i_mtime) = body->mtime; if (req != NULL) ptlrpc_req_finished(req); } release_lock: size += i_size_read(inode); if (i != 0) nlink += inode->i_nlink - 2; else nlink += inode->i_nlink; atime = LTIME_S(inode->i_atime) > atime ? LTIME_S(inode->i_atime) : atime; ctime = LTIME_S(inode->i_ctime) > ctime ? LTIME_S(inode->i_ctime) : ctime; mtime = LTIME_S(inode->i_mtime) > mtime ? LTIME_S(inode->i_mtime) : mtime; if (it.d.lustre.it_lock_mode != 0 && lockh != NULL) { ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode); it.d.lustre.it_lock_mode = 0; } CDEBUG(D_INODE, "i %d "DFID" size %llu, nlink %u, atime " "%lu, mtime %lu, ctime %lu.\n", i, PFID(&fid), i_size_read(inode), inode->i_nlink, LTIME_S(inode->i_atime), LTIME_S(inode->i_mtime), LTIME_S(inode->i_ctime)); } /* * update attr of master request. */ CDEBUG(D_INODE, "Return refreshed attrs: size = %lu nlink %lu atime " LPU64 "ctime "LPU64" mtime "LPU64" for " DFID"\n", size, nlink, atime, ctime, mtime, PFID(&lsm->lsm_md_oinfo[0].lmo_fid)); if (mbody != NULL) { mbody->atime = atime; mbody->ctime = ctime; mbody->mtime = mtime; } cleanup: OBD_FREE_PTR(op_data); RETURN(rc); }