+extern int osd_trans_declare_op2rb[];
+extern int ldiskfs_track_declares_assert;
+
+static inline void osd_trans_declare_op(const struct lu_env *env,
+ struct osd_thandle *oh,
+ unsigned int op, int credits)
+{
+ struct osd_thread_info *oti = osd_oti_get(env);
+
+ LASSERT(oh->ot_handle == NULL);
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert)) {
+ LASSERT(op < OSD_OT_MAX);
+ } else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ }
+ } else {
+ oti->oti_declare_ops[op]++;
+ oti->oti_declare_ops_cred[op] += credits;
+ }
+ oh->ot_credits += credits;
+}
+
+static inline void osd_trans_exec_op(const struct lu_env *env,
+ struct thandle *th, unsigned int op)
+{
+ struct osd_thread_info *oti = osd_oti_get(env);
+ struct osd_thandle *oh = container_of(th, struct osd_thandle,
+ ot_super);
+ unsigned int rb;
+
+ LASSERT(oh->ot_handle != NULL);
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERT(op < OSD_OT_MAX);
+ else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
+
+ if (likely(!oti->oti_rollback && oti->oti_declare_ops[op] > 0)) {
+ oti->oti_declare_ops[op]--;
+ oti->oti_declare_ops_rb[op]++;
+ } else {
+ /* all future updates are considered rollback */
+ oti->oti_rollback = true;
+ rb = osd_trans_declare_op2rb[op];
+ if (unlikely(rb >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERTF(rb < OSD_OT_MAX, "rb = %u\n", rb);
+ else {
+ CWARN("%s: Invalid rollback index %d\n",
+ osd_name(oti->oti_dev), rb);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
+ if (unlikely(oti->oti_declare_ops_rb[rb] == 0)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERTF(oti->oti_declare_ops_rb[rb] > 0,
+ "rb = %u\n", rb);
+ else {
+ CWARN("%s: Overflow in tracking declares for "
+ "index, rb = %d\n",
+ osd_name(oti->oti_dev), rb);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
+ oti->oti_declare_ops_rb[rb]--;
+ }
+}
+
+static inline void osd_trans_declare_rb(const struct lu_env *env,
+ struct thandle *th, unsigned int op)
+{
+ struct osd_thread_info *oti = osd_oti_get(env);
+ struct osd_thandle *oh = container_of(th, struct osd_thandle,
+ ot_super);
+
+ LASSERT(oh->ot_handle != NULL);
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERT(op < OSD_OT_MAX);
+ else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ }
+
+ } else {
+ oti->oti_declare_ops_rb[op]++;
+ }
+}
+