- * This design limits the extent to which we can keep a full pipeline of
- * in-flight requests from a single client. This limitation could be
- * overcome by allowing multiple slots per client in the last_rcvd file.
- */
-struct mdc_rpc_lock {
- /** Lock protecting in-flight RPC concurrency. */
- struct mutex rpcl_mutex;
- /** Intent associated with currently executing request. */
- struct lookup_intent *rpcl_it;
- /** Used for MDS/RPC load testing purposes. */
- int rpcl_fakes;
-};
-
-#define MDC_FAKE_RPCL_IT ((void *)0x2c0012bfUL)
-
-static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
-{
- mutex_init(&lck->rpcl_mutex);
- lck->rpcl_it = NULL;
-}
-
-static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
- struct lookup_intent *it)
-{
- ENTRY;
-
- if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
- it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
- return;
-
- /* This would normally block until the existing request finishes.
- * If fail_loc is set it will block until the regular request is
- * done, then set rpcl_it to MDC_FAKE_RPCL_IT. Once that is set
- * it will only be cleared when all fake requests are finished.
- * Only when all fake requests are finished can normal requests
- * be sent, to ensure they are recoverable again. */
- again:
- mutex_lock(&lck->rpcl_mutex);
-
- if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM)) {
- lck->rpcl_it = MDC_FAKE_RPCL_IT;
- lck->rpcl_fakes++;
- mutex_unlock(&lck->rpcl_mutex);
- return;
- }
-
- /* This will only happen when the CFS_FAIL_CHECK() was
- * just turned off but there are still requests in progress.
- * Wait until they finish. It doesn't need to be efficient
- * in this extremely rare case, just have low overhead in
- * the common case when it isn't true. */
- while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) {
- mutex_unlock(&lck->rpcl_mutex);
- schedule_timeout(cfs_time_seconds(1) / 4);
- goto again;
- }
-
- LASSERT(lck->rpcl_it == NULL);
- lck->rpcl_it = it;
-}
-
-static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck,
- struct lookup_intent *it)
-{
- if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
- it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
- goto out;
-
- if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */
- mutex_lock(&lck->rpcl_mutex);
-
- LASSERTF(lck->rpcl_fakes > 0, "%d\n", lck->rpcl_fakes);
- lck->rpcl_fakes--;
-
- if (lck->rpcl_fakes == 0)
- lck->rpcl_it = NULL;
-
- } else {
- LASSERTF(it == lck->rpcl_it, "%p != %p\n", it, lck->rpcl_it);
- lck->rpcl_it = NULL;
- }
-
- mutex_unlock(&lck->rpcl_mutex);
- out:
- EXIT;
-}
-
-/* Update the maximum observed easize and cookiesize. The default easize
- * and cookiesize is initialized to the minimum value but allowed to grow
- * up to a single page in size if required to handle the common case.