+void osp_obj_invalidate_cache(struct osp_object *obj)
+{
+ struct osp_xattr_entry *oxe;
+ struct osp_xattr_entry *tmp;
+
+ spin_lock(&obj->opo_lock);
+ list_for_each_entry_safe(oxe, tmp, &obj->opo_xattr_list, oxe_list) {
+ oxe->oxe_ready = 0;
+ list_del_init(&oxe->oxe_list);
+ osp_oac_xattr_put(oxe);
+ }
+ obj->opo_attr.la_valid = 0;
+ spin_unlock(&obj->opo_lock);
+}
+
+/**
+ * Implement OSP layer dt_object_operations::do_invalidate() interface.
+ *
+ * Invalidate attributes cached on the specified MDT/OST object.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] dt pointer to the OSP layer dt_object
+ *
+ * \retval 0 for success
+ * \retval negative error number on failure
+ */
+int osp_invalidate(const struct lu_env *env, struct dt_object *dt)
+{
+ struct osp_object *obj = dt2osp_obj(dt);
+ ENTRY;
+
+ CDEBUG(D_HA, "Invalidate osp_object "DFID"\n",
+ PFID(lu_object_fid(&dt->do_lu)));
+
+ /* serialize attr/EA set vs. invalidation */
+ down_write(&obj->opo_invalidate_sem);
+
+ /* this should invalidate all in-flights */
+ atomic_inc(&obj->opo_invalidate_seq);
+
+ spin_lock(&obj->opo_lock);
+ /* do not mark new objects stale */
+ if (obj->opo_attr.la_valid)
+ obj->opo_stale = 1;
+ obj->opo_non_exist = 0;
+ spin_unlock(&obj->opo_lock);
+
+ osp_obj_invalidate_cache(obj);
+
+ up_write(&obj->opo_invalidate_sem);
+
+ RETURN(0);
+}
+
+bool osp_check_stale(struct dt_object *dt)
+{
+ struct osp_object *obj = dt2osp_obj(dt);
+
+ if (is_ost_obj(&dt->do_lu) && obj->opo_non_exist)
+ return true;
+
+ return obj->opo_stale;
+}
+
+