+ obd_ping(req->rq_export);
+ return req_capsule_server_pack(&req->rq_pill);
+}
+
+void target_committed_to_req(struct ptlrpc_request *req)
+{
+ struct obd_export *exp = req->rq_export;
+
+ if (!exp->exp_obd->obd_no_transno && req->rq_repmsg != NULL)
+ lustre_msg_set_last_committed(req->rq_repmsg,
+ exp->exp_last_committed);
+ else
+ DEBUG_REQ(D_IOCTL, req, "not sending last_committed update (%d/"
+ "%d)", exp->exp_obd->obd_no_transno,
+ req->rq_repmsg == NULL);
+
+ CDEBUG(D_INFO, "last_committed "LPU64", transno "LPU64", xid "LPU64"\n",
+ exp->exp_last_committed, req->rq_transno, req->rq_xid);
+}
+EXPORT_SYMBOL(target_committed_to_req);
+
+int target_handle_qc_callback(struct ptlrpc_request *req)
+{
+ struct obd_quotactl *oqctl;
+ struct client_obd *cli = &req->rq_export->exp_obd->u.cli;
+
+ oqctl = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL);
+ if (oqctl == NULL) {
+ CERROR("Can't unpack obd_quotactl\n");
+ RETURN(-EPROTO);
+ }
+
+ cli->cl_qchk_stat = oqctl->qc_stat;
+
+ return 0;
+}
+
+#ifdef HAVE_QUOTA_SUPPORT
+int target_handle_dqacq_callback(struct ptlrpc_request *req)
+{
+#ifdef __KERNEL__
+ struct obd_device *obd = req->rq_export->exp_obd;
+ struct obd_device *master_obd;
+ struct obd_device_target *obt;
+ struct lustre_quota_ctxt *qctxt;
+ struct qunit_data *qdata = NULL;
+ int rc = 0;
+ ENTRY;
+
+ if (OBD_FAIL_CHECK(OBD_FAIL_MDS_DROP_QUOTA_REQ))
+ RETURN(rc);
+
+ rc = req_capsule_server_pack(&req->rq_pill);
+ if (rc) {
+ CERROR("packing reply failed!: rc = %d\n", rc);
+ RETURN(rc);
+ }
+
+ LASSERT(req->rq_export);
+
+ qdata = quota_get_qdata(req, QUOTA_REQUEST, QUOTA_EXPORT);
+ if (IS_ERR(qdata)) {
+ rc = PTR_ERR(qdata);
+ CDEBUG(D_ERROR, "Can't unpack qunit_data(rc: %d)\n", rc);
+ req->rq_status = rc;
+ GOTO(out, rc);
+ }
+
+ /* we use the observer */
+ if (!obd->obd_observer || !obd->obd_observer->obd_observer) {
+ CERROR("Can't find the observer, it is recovering\n");
+ req->rq_status = -EAGAIN;
+ GOTO(out, rc);
+ }
+
+ master_obd = obd->obd_observer->obd_observer;
+ obt = &master_obd->u.obt;
+ qctxt = &obt->obt_qctxt;
+
+ if (!qctxt->lqc_setup || !qctxt->lqc_valid) {
+ /* quota_type has not been processed yet, return EAGAIN
+ * until we know whether or not quotas are supposed to
+ * be enabled */
+ CDEBUG(D_QUOTA, "quota_type not processed yet, return "
+ "-EAGAIN\n");
+ req->rq_status = -EAGAIN;
+ GOTO(out, rc);
+ }
+
+ down_read(&obt->obt_rwsem);
+ if (qctxt->lqc_lqs_hash == NULL) {
+ up_read(&obt->obt_rwsem);
+ /* quota_type has not been processed yet, return EAGAIN
+ * until we know whether or not quotas are supposed to
+ * be enabled */
+ CDEBUG(D_QUOTA, "quota_ctxt is not ready yet, return "
+ "-EAGAIN\n");
+ req->rq_status = -EAGAIN;
+ GOTO(out, rc);
+ }
+
+ LASSERT(qctxt->lqc_handler);
+ rc = qctxt->lqc_handler(master_obd, qdata,
+ lustre_msg_get_opc(req->rq_reqmsg));
+ up_read(&obt->obt_rwsem);
+ if (rc && rc != -EDQUOT)
+ CDEBUG(rc == -EBUSY ? D_QUOTA : D_ERROR,
+ "dqacq/dqrel failed! (rc:%d)\n", rc);
+ req->rq_status = rc;
+
+ rc = quota_copy_qdata(req, qdata, QUOTA_REPLY, QUOTA_EXPORT);
+ if (rc < 0) {
+ CERROR("Can't pack qunit_data(rc: %d)\n", rc);
+ GOTO(out, rc);
+ }
+
+ /* Block the quota req. b=14840 */
+ OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_BLOCK_QUOTA_REQ, obd_timeout);
+ EXIT;
+
+out:
+ rc = ptlrpc_reply(req);
+ return rc;
+#else
+ return 0;
+#endif /* !__KERNEL__ */
+}
+#endif /* HAVE_QUOTA_SUPPORT */
+
+ldlm_mode_t lck_compat_array[] = {
+ [LCK_EX] LCK_COMPAT_EX,
+ [LCK_PW] LCK_COMPAT_PW,
+ [LCK_PR] LCK_COMPAT_PR,
+ [LCK_CW] LCK_COMPAT_CW,
+ [LCK_CR] LCK_COMPAT_CR,
+ [LCK_NL] LCK_COMPAT_NL,
+ [LCK_GROUP] LCK_COMPAT_GROUP,
+ [LCK_COS] LCK_COMPAT_COS,
+};
+
+/**
+ * Rather arbitrary mapping from LDLM error codes to errno values. This should
+ * not escape to the user level.
+ */
+int ldlm_error2errno(ldlm_error_t error)
+{
+ int result;
+
+ switch (error) {
+ case ELDLM_OK:
+ result = 0;
+ break;
+ case ELDLM_LOCK_CHANGED:
+ result = -ESTALE;
+ break;
+ case ELDLM_LOCK_ABORTED:
+ result = -ENAVAIL;
+ break;
+ case ELDLM_LOCK_REPLACED:
+ result = -ESRCH;
+ break;
+ case ELDLM_NO_LOCK_DATA:
+ result = -ENOENT;
+ break;
+ case ELDLM_NAMESPACE_EXISTS:
+ result = -EEXIST;
+ break;
+ case ELDLM_BAD_NAMESPACE:
+ result = -EBADF;
+ break;
+ default:
+ if (((int)error) < 0) /* cast to signed type */
+ result = error; /* as ldlm_error_t can be unsigned */
+ else {
+ CERROR("Invalid DLM result code: %i\n", error);
+ result = -EPROTO;
+ }
+ }
+ return result;