+int mdt_version_get_check(struct mdt_thread_info *info, int index)
+{
+ /** version recovery */
+ struct md_object *mo;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ __u64 curr_version, *pre_versions;
+ ENTRY;
+
+ if (!exp_connect_vbr(req->rq_export))
+ RETURN(0);
+
+ LASSERT(info->mti_mos[index]);
+ if (mdt_object_exists(info->mti_mos[index]) == 0)
+ RETURN(-ESTALE);
+ mo = mdt_object_child(info->mti_mos[index]);
+
+ curr_version = mo_version_get(info->mti_env, mo);
+ CDEBUG(D_INODE, "Version is "LPX64"\n", curr_version);
+ /** VBR: version is checked always because costs nothing */
+ if (lustre_msg_get_transno(req->rq_reqmsg) != 0) {
+ pre_versions = lustre_msg_get_versions(req->rq_reqmsg);
+ LASSERT(index < PTLRPC_NUM_VERSIONS);
+ /** Sanity check for malformed buffers */
+ if (pre_versions == NULL) {
+ CERROR("No versions in request buffer\n");
+ cfs_spin_lock(&req->rq_export->exp_lock);
+ req->rq_export->exp_vbr_failed = 1;
+ cfs_spin_unlock(&req->rq_export->exp_lock);
+ RETURN(-EOVERFLOW);
+ } else if (pre_versions[index] != curr_version) {
+ CDEBUG(D_INODE, "Version mismatch "LPX64" != "LPX64"\n",
+ pre_versions[index], curr_version);
+ cfs_spin_lock(&req->rq_export->exp_lock);
+ req->rq_export->exp_vbr_failed = 1;
+ cfs_spin_unlock(&req->rq_export->exp_lock);
+ RETURN(-EOVERFLOW);
+ }
+ }
+ /** save pre-versions in reply */
+ LASSERT(req->rq_repmsg != NULL);
+ pre_versions = lustre_msg_get_versions(req->rq_repmsg);
+ if (pre_versions)
+ pre_versions[index] = curr_version;
+ RETURN(0);
+}
+