+ * FLR: verify the layout version of object.
+ *
+ * \param[in] env execution environment
+ * \param[in] fo OFD object
+ * \param[in] oa OBDO structure with layout version
+ *
+ * \retval 0 on successful verification
+ * \retval -EINPROGRESS layout version is in transfer
+ * \retval -ESTALE the layout version on client is stale
+ */
+int ofd_verify_layout_version(const struct lu_env *env,
+ struct ofd_object *fo, const struct obdo *oa)
+{
+ __u32 layout_version;
+ int rc;
+ ENTRY;
+
+ if (unlikely(OBD_FAIL_CHECK(OBD_FAIL_OST_SKIP_LV_CHECK)))
+ GOTO(out, rc = 0);
+
+ rc = ofd_object_ff_load(env, fo);
+ if (rc < 0) {
+ if (rc == -ENODATA)
+ rc = -EINPROGRESS;
+ GOTO(out, rc);
+ }
+
+ layout_version = fo->ofo_ff.ff_layout_version;
+ if (oa->o_layout_version >= layout_version &&
+ oa->o_layout_version <= layout_version + fo->ofo_ff.ff_range)
+ GOTO(out, rc = 0);
+
+ /* normal traffic, decide if to return ESTALE or EINPROGRESS */
+ layout_version &= ~LU_LAYOUT_RESYNC;
+
+ /* this update is not legitimate */
+ if ((oa->o_layout_version & ~LU_LAYOUT_RESYNC) <= layout_version)
+ GOTO(out, rc = -ESTALE);
+
+ /* layout version may not be transmitted yet */
+ if ((oa->o_layout_version & ~LU_LAYOUT_RESYNC) > layout_version)
+ GOTO(out, rc = -EINPROGRESS);
+
+ EXIT;
+
+out:
+ CDEBUG(D_INODE, DFID " verify layout version: %u vs. %u/%u, rc: %d\n",
+ PFID(lu_object_fid(&fo->ofo_obj.do_lu)),
+ oa->o_layout_version, fo->ofo_ff.ff_layout_version,
+ fo->ofo_ff.ff_range, rc);
+ return rc;
+
+}
+
+/*
+ * Lazy ATIME update to refresh atime every ofd_atime_diff
+ * seconds so that external scanning tool can see it actual
+ * within that period and be able to identify accessed files
+ */
+static void ofd_handle_atime(const struct lu_env *env, struct ofd_device *ofd,
+ struct ofd_object *fo, time64_t atime)
+{
+ struct lu_attr *la;
+ struct dt_object *o;
+ struct thandle *th;
+ int rc;
+
+ if (ofd->ofd_atime_diff == 0)
+ return;
+
+ la = &ofd_info(env)->fti_attr2;
+ o = ofd_object_child(fo);
+
+ if (unlikely(fo->ofo_atime_ondisk == 0)) {
+ rc = dt_attr_get(env, o, la);
+ if (unlikely(rc))
+ return;
+ LASSERT(la->la_valid & LA_ATIME);
+ if (la->la_atime == 0)
+ la->la_atime = la->la_mtime;
+ fo->ofo_atime_ondisk = la->la_atime;
+ }
+ if (atime - fo->ofo_atime_ondisk < ofd->ofd_atime_diff)
+ return;
+
+ /* atime hasn't been updated too long, update it */
+ fo->ofo_atime_ondisk = atime;
+
+ th = ofd_trans_create(env, ofd);
+ if (IS_ERR(th)) {
+ CERROR("%s: cannot create transaction: rc = %d\n",
+ ofd_name(ofd), (int)PTR_ERR(th));
+ return;
+ }
+
+ la->la_valid = LA_ATIME;
+ rc = dt_declare_attr_set(env, o, la, th);
+ if (rc)
+ GOTO(out_tx, rc);
+
+ rc = dt_trans_start_local(env, ofd->ofd_osd , th);
+ if (rc) {
+ CERROR("%s: cannot start transaction: rc = %d\n",
+ ofd_name(ofd), rc);
+ GOTO(out_tx, rc);
+ }
+
+ ofd_read_lock(env, fo);
+ if (ofd_object_exists(fo)) {
+ la->la_atime = fo->ofo_atime_ondisk;
+ rc = dt_attr_set(env, o, la, th);
+ }
+
+ ofd_read_unlock(env, fo);
+
+out_tx:
+ ofd_trans_stop(env, ofd, th, rc);
+}
+
+/**