Whamcloud - gitweb
LU-6179 llite: Implement ladvise lockahead
[fs/lustre-release.git] / lustre / osc / osc_request.c
index 5526814..5f259e9 100644 (file)
@@ -100,7 +100,7 @@ struct osc_enqueue_args {
        void                    *oa_cookie;
        struct ost_lvb          *oa_lvb;
        struct lustre_handle    oa_lockh;
-       unsigned int            oa_agl:1;
+       bool                    oa_speculative;
 };
 
 static void osc_release_ppga(struct brw_page **ppga, size_t count);
@@ -2035,7 +2035,7 @@ static int osc_set_lock_data(struct ldlm_lock *lock, void *data)
 static int osc_enqueue_fini(struct ptlrpc_request *req,
                            osc_enqueue_upcall_f upcall, void *cookie,
                            struct lustre_handle *lockh, enum ldlm_mode mode,
-                           __u64 *flags, int agl, int errcode)
+                           __u64 *flags, bool speculative, int errcode)
 {
        bool intent = *flags & LDLM_FL_HAS_INTENT;
        int rc;
@@ -2052,7 +2052,7 @@ static int osc_enqueue_fini(struct ptlrpc_request *req,
                        ptlrpc_status_ntoh(rep->lock_policy_res1);
                if (rep->lock_policy_res1)
                        errcode = rep->lock_policy_res1;
-               if (!agl)
+               if (!speculative)
                        *flags |= LDLM_FL_LVB_READY;
        } else if (errcode == ELDLM_OK) {
                *flags |= LDLM_FL_LVB_READY;
@@ -2102,7 +2102,7 @@ static int osc_enqueue_interpret(const struct lu_env *env,
        /* Let CP AST to grant the lock first. */
        OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 1);
 
-       if (aa->oa_agl) {
+       if (aa->oa_speculative) {
                LASSERT(aa->oa_lvb == NULL);
                LASSERT(aa->oa_flags == NULL);
                aa->oa_flags = &flags;
@@ -2114,7 +2114,7 @@ static int osc_enqueue_interpret(const struct lu_env *env,
                                   lockh, rc);
        /* Complete osc stuff. */
        rc = osc_enqueue_fini(req, aa->oa_upcall, aa->oa_cookie, lockh, mode,
-                             aa->oa_flags, aa->oa_agl, rc);
+                             aa->oa_flags, aa->oa_speculative, rc);
 
         OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_CANCEL_RACE, 10);
 
@@ -2137,7 +2137,8 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
                     struct ost_lvb *lvb, int kms_valid,
                     osc_enqueue_upcall_f upcall, void *cookie,
                     struct ldlm_enqueue_info *einfo,
-                    struct ptlrpc_request_set *rqset, int async, int agl)
+                    struct ptlrpc_request_set *rqset, int async,
+                    bool speculative)
 {
        struct obd_device *obd = exp->exp_obd;
        struct lustre_handle lockh = { 0 };
@@ -2153,14 +2154,14 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
        policy->l_extent.start -= policy->l_extent.start & ~PAGE_MASK;
        policy->l_extent.end |= ~PAGE_MASK;
 
-        /*
-         * kms is not valid when either object is completely fresh (so that no
-         * locks are cached), or object was evicted. In the latter case cached
-         * lock cannot be used, because it would prime inode state with
-         * potentially stale LVB.
-         */
-        if (!kms_valid)
-                goto no_match;
+       /*
+        * kms is not valid when either object is completely fresh (so that no
+        * locks are cached), or object was evicted. In the latter case cached
+        * lock cannot be used, because it would prime inode state with
+        * potentially stale LVB.
+        */
+       if (!kms_valid)
+               goto no_match;
 
         /* Next, search for already existing extent locks that will cover us */
         /* If we're trying to read, we also search for an existing PW lock.  The
@@ -2177,7 +2178,10 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
         mode = einfo->ei_mode;
         if (einfo->ei_mode == LCK_PR)
                 mode |= LCK_PW;
-       if (agl == 0)
+       /* Normal lock requests must wait for the LVB to be ready before
+        * matching a lock; speculative lock requests do not need to,
+        * because they will not actually use the lock. */
+       if (!speculative)
                match_flags |= LDLM_FL_LVB_READY;
        if (intent != 0)
                match_flags |= LDLM_FL_BLOCK_GRANTED;
@@ -2190,13 +2194,22 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
                        RETURN(ELDLM_OK);
 
                matched = ldlm_handle2lock(&lockh);
-               if (agl) {
-                       /* AGL enqueues DLM locks speculatively. Therefore if
-                        * it already exists a DLM lock, it wll just inform the
-                        * caller to cancel the AGL process for this stripe. */
+               if (speculative) {
+                       /* This DLM lock request is speculative, and does not
+                        * have an associated IO request. Therefore if there
+                        * is already a DLM lock, it wll just inform the
+                        * caller to cancel the request for this stripe.*/
+                       lock_res_and_lock(matched);
+                       if (ldlm_extent_equal(&policy->l_extent,
+                           &matched->l_policy_data.l_extent))
+                               rc = -EEXIST;
+                       else
+                               rc = -ECANCELED;
+                       unlock_res_and_lock(matched);
+
                        ldlm_lock_decref(&lockh, mode);
                        LDLM_LOCK_PUT(matched);
-                       RETURN(-ECANCELED);
+                       RETURN(rc);
                } else if (osc_set_lock_data(matched, einfo->ei_cbdata)) {
                        *flags |= LDLM_FL_LVB_READY;
 
@@ -2243,20 +2256,20 @@ no_match:
                        struct osc_enqueue_args *aa;
                        CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args));
                        aa = ptlrpc_req_async_args(req);
-                       aa->oa_exp    = exp;
-                       aa->oa_mode   = einfo->ei_mode;
-                       aa->oa_type   = einfo->ei_type;
+                       aa->oa_exp         = exp;
+                       aa->oa_mode        = einfo->ei_mode;
+                       aa->oa_type        = einfo->ei_type;
                        lustre_handle_copy(&aa->oa_lockh, &lockh);
-                       aa->oa_upcall = upcall;
-                       aa->oa_cookie = cookie;
-                       aa->oa_agl    = !!agl;
-                       if (!agl) {
+                       aa->oa_upcall      = upcall;
+                       aa->oa_cookie      = cookie;
+                       aa->oa_speculative = speculative;
+                       if (!speculative) {
                                aa->oa_flags  = flags;
                                aa->oa_lvb    = lvb;
                        } else {
-                               /* AGL is essentially to enqueue an DLM lock
-                                * in advance, so we don't care about the
-                                * result of AGL enqueue. */
+                               /* speculative locks are essentially to enqueue
+                                * a DLM lock  in advance, so we don't care
+                                * about the result of the enqueue. */
                                aa->oa_lvb    = NULL;
                                aa->oa_flags  = NULL;
                        }
@@ -2274,7 +2287,7 @@ no_match:
        }
 
        rc = osc_enqueue_fini(req, upcall, cookie, &lockh, einfo->ei_mode,
-                             flags, agl, rc);
+                             flags, speculative, rc);
        if (intent)
                ptlrpc_req_finished(req);