+ /*
+ * This check is for lock taken in ofd_destroy_by_fid() that does
+ * not have l_glimpse_ast set. So the logic is: if there is a lock
+ * with no l_glimpse_ast set, this object is being destroyed already.
+ * Hence, if you are grabbing DLM locks on the server, always set
+ * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()).
+ */
+ if (victim_lock->l_glimpse_ast == NULL) {
+ LDLM_DEBUG(victim_lock, "no l_glimpse_ast");
+ arg->no_glimpse_ast = true;
+ GOTO(out_release, rc = INTERVAL_ITER_STOP);
+ }
+
+ /* If NO_EXPANSION is not set, this is an active lock, and we don't need
+ * to glimpse any further once we've glimpsed the client holding this
+ * lock. So set us up to stop. See comment above this function. */
+ if (!(victim_lock->l_flags & LDLM_FL_NO_EXPANSION))
+ rc = INTERVAL_ITER_STOP;
+ else
+ rc = INTERVAL_ITER_CONT;
+
+ /* Check to see if we're already set up to send a glimpse to this
+ * client; if so, don't add this lock to the glimpse list - We need
+ * only glimpse each client once. (And if we know that client holds
+ * an active lock, we can stop glimpsing. So keep the rc set in the
+ * check above.) */
+ list_for_each_entry(gl_work, &arg->gl_list, gl_list) {
+ if (gl_work->gl_lock->l_export == victim_lock->l_export)
+ GOTO(out_release, rc);
+ }
+
+ if (!OBD_FAIL_CHECK(OBD_FAIL_OST_GL_WORK_ALLOC))
+ OBD_SLAB_ALLOC_PTR_GFP(gl_work, ldlm_glimpse_work_kmem,
+ GFP_ATOMIC);
+
+ if (!gl_work) {
+ arg->error = -ENOMEM;
+ GOTO(out_release, rc = INTERVAL_ITER_STOP);
+ }
+
+ /* Populate the gl_work structure. */
+ gl_work->gl_lock = victim_lock;
+ list_add_tail(&gl_work->gl_list, &arg->gl_list);
+ /* There is actually no need for a glimpse descriptor when glimpsing
+ * extent locks */
+ gl_work->gl_desc = NULL;
+ /* This tells ldlm_work_gl_ast_lock this was allocated from a slab and
+ * must be freed in a slab-aware manner. */
+ gl_work->gl_flags = LDLM_GL_WORK_SLAB_ALLOCATED;
+
+ GOTO(out, rc);
+
+out_release:
+ /* If the victim doesn't go on the glimpse list, we must release it */
+ LDLM_LOCK_RELEASE(victim_lock);
+
+out:
+ return rc;
+}