Whamcloud - gitweb
LU-12616 obclass: fix MDS start/stop race
[fs/lustre-release.git] / lustre / osc / osc_cache.c
index ea721ba..431df82 100644 (file)
@@ -584,6 +584,7 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext)
                         * osc_cache_truncate_start(). */
                        osc_extent_state_set(ext, OES_TRUNC);
                        ext->oe_trunc_pending = 0;
+                       osc_object_unlock(obj);
                } else {
                        int grant = 0;
 
@@ -596,8 +597,6 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext)
                                grant += cli->cl_grant_extent_tax;
                        if (osc_extent_merge(env, ext, next_extent(ext)) == 0)
                                grant += cli->cl_grant_extent_tax;
-                       if (grant > 0)
-                               osc_unreserve_grant(cli, 0, grant);
 
                        if (ext->oe_urgent)
                                list_move_tail(&ext->oe_link,
@@ -606,8 +605,10 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext)
                                list_move_tail(&ext->oe_link,
                                               &obj->oo_full_exts);
                        }
+                       osc_object_unlock(obj);
+                       if (grant > 0)
+                               osc_unreserve_grant(cli, 0, grant);
                }
-               osc_object_unlock(obj);
 
                osc_io_unplug_async(env, cli, obj);
        }
@@ -1470,13 +1471,20 @@ static void __osc_unreserve_grant(struct client_obd *cli,
        }
 }
 
-static void osc_unreserve_grant(struct client_obd *cli,
-                               unsigned int reserved, unsigned int unused)
+static void osc_unreserve_grant_nolock(struct client_obd *cli,
+                                      unsigned int reserved,
+                                      unsigned int unused)
 {
-       spin_lock(&cli->cl_loi_list_lock);
        __osc_unreserve_grant(cli, reserved, unused);
        if (unused > 0)
                osc_wake_cache_waiters(cli);
+}
+
+static void osc_unreserve_grant(struct client_obd *cli,
+                               unsigned int reserved, unsigned int unused)
+{
+       spin_lock(&cli->cl_loi_list_lock);
+       osc_unreserve_grant_nolock(cli, reserved, unused);
        spin_unlock(&cli->cl_loi_list_lock);
 }
 
@@ -2432,7 +2440,6 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
                /* it doesn't need any grant to dirty this page */
                spin_lock(&cli->cl_loi_list_lock);
                rc = osc_enter_cache_try(cli, oap, grants, 0);
-               spin_unlock(&cli->cl_loi_list_lock);
                if (rc == 0) { /* try failed */
                        grants = 0;
                        need_release = 1;
@@ -2446,10 +2453,11 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
                        } else {
                                OSC_EXTENT_DUMP(D_CACHE, ext,
                                                "expanded for %lu.\n", index);
-                               osc_unreserve_grant(cli, grants, tmp);
+                               osc_unreserve_grant_nolock(cli, grants, tmp);
                                grants = 0;
                        }
                }
+               spin_unlock(&cli->cl_loi_list_lock);
                rc = 0;
        } else if (ext != NULL) {
                /* index is located outside of active extent */
@@ -3029,10 +3037,25 @@ int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj,
                                        list_move_tail(&ext->oe_link, list);
                                unplug = true;
                        } else {
+                               struct client_obd *cli = osc_cli(obj);
+                               int pcc_bits = cli->cl_chunkbits - PAGE_SHIFT;
+                               pgoff_t align_by = (1 << pcc_bits);
+                               pgoff_t a_start = round_down(start, align_by);
+                               pgoff_t a_end = round_up(end, align_by);
+
+                               /* overflow case */
+                               if (end && !a_end)
+                                       a_end = CL_PAGE_EOF;
                                /* the only discarder is lock cancelling, so
-                                * [start, end] must contain this extent */
-                               EASSERT(ext->oe_start >= start &&
-                                       ext->oe_end <= end, ext);
+                                * [start, end], aligned by chunk size, must
+                                * contain this extent */
+                               LASSERTF(ext->oe_start >= a_start &&
+                                        ext->oe_end <= a_end,
+                                        "ext [%lu, %lu] reg [%lu, %lu] "
+                                        "orig [%lu %lu] align %lu bits "
+                                        "%d\n", ext->oe_start, ext->oe_end,
+                                        a_start, a_end, start, end,
+                                        align_by, pcc_bits);
                                osc_extent_state_set(ext, OES_LOCKING);
                                ext->oe_owner = current;
                                list_move_tail(&ext->oe_link,