Whamcloud - gitweb
LU-4482 grant: don't use cache data in osd_statfs()
[fs/lustre-release.git] / lustre / ofd / ofd_grant.c
index 9194f74..7fa1e4a 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 
 #include "ofd_internal.h"
 
-#define OFD_GRANT_CHUNK (2ULL * DT_MAX_BRW_SIZE)
-#define OFD_GRANT_CHUNK_EXP(rexp) (2ULL * exp_brw_size((rexp)))
-#define OFD_GRANT_SHRINK_LIMIT(rexp) (16ULL * OFD_GRANT_CHUNK_EXP((rexp)))
+/* At least enough to send a couple of 1MB RPCs, even if not max sized */
+#define OFD_GRANT_CHUNK                        (2ULL * DT_MAX_BRW_SIZE)
+
+/* Clients typically hold 2x their max_rpcs_in_flight of grant space */
+#define OFD_GRANT_SHRINK_LIMIT(exp)    (2ULL * 8 * exp_max_brw_size(exp))
 
 static inline obd_size ofd_grant_from_cli(struct obd_export *exp,
                                          struct ofd_device *ofd, obd_size val)
@@ -68,15 +70,17 @@ static inline obd_size ofd_grant_to_cli(struct obd_export *exp,
 static inline obd_size ofd_grant_chunk(struct obd_export *exp,
                                       struct ofd_device *ofd)
 {
-       if (exp && ofd_obd(ofd)->obd_self_export == exp)
+       if (ofd_obd(ofd)->obd_self_export == exp)
                /* Grant enough space to handle a big precreate request */
-               return OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace;
+               return OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2;
 
-       if (exp && ofd_grant_compat(exp, ofd))
+       if (ofd_grant_compat(exp, ofd))
                /* Try to grant enough space to send a full-size RPC */
-               return exp_brw_size(exp) <<
+               return exp_max_brw_size(exp) <<
                       (ofd->ofd_blockbits - COMPAT_BSIZE_SHIFT);
-       return OFD_GRANT_CHUNK;
+
+       /* Try to return enough to send two full RPCs, if needed */
+       return exp_max_brw_size(exp) * 2;
 }
 
 /**
@@ -202,7 +206,8 @@ static void ofd_grant_statfs(const struct lu_env *env, struct obd_export *exp,
 
        rc = ofd_statfs_internal(env, ofd, osfs, max_age, from_cache);
        if (unlikely(rc)) {
-               *from_cache = 0;
+               if (from_cache)
+                       *from_cache = 0;
                return;
        }
 
@@ -229,7 +234,7 @@ static obd_size ofd_grant_space_left(struct obd_export *exp)
        obd_size                 unstable;
 
        ENTRY;
-       LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock);
+       LASSERT(spin_is_locked(&ofd->ofd_grant_lock));
 
        spin_lock(&ofd->ofd_osfs_lock);
        /* get available space from cached statfs data */
@@ -245,10 +250,11 @@ static obd_size ofd_grant_space_left(struct obd_export *exp)
                            D_ERROR : D_CACHE;
 
                CDEBUG_LIMIT(mask, "%s: cli %s/%p left "LPU64" < tot_grant "
-                            LPU64" unstable "LPU64" pending "LPU64"\n",
+                            LPU64" unstable "LPU64" pending "LPU64" "
+                            "dirty "LPU64"\n",
                             obd->obd_name, exp->exp_client_uuid.uuid, exp,
                             left, tot_granted, unstable,
-                            ofd->ofd_tot_pending);
+                            ofd->ofd_tot_pending, ofd->ofd_tot_dirty);
                RETURN(0);
        }
 
@@ -293,7 +299,7 @@ static void ofd_grant_incoming(const struct lu_env *env, struct obd_export *exp,
        long                             dirty, dropped, grant_chunk;
        ENTRY;
 
-       LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock);
+       LASSERT(spin_is_locked(&ofd->ofd_grant_lock));
 
        if ((oa->o_valid & (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) !=
                                        (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) {
@@ -371,7 +377,7 @@ static void ofd_grant_shrink(struct obd_export *exp,
        struct obd_device               *obd = exp->exp_obd;
        long                             grant_shrink;
 
-       LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock);
+       LASSERT(spin_is_locked(&ofd->ofd_grant_lock));
        LASSERT(exp);
        if (left_space >= ofd->ofd_tot_granted_clients *
                          OFD_GRANT_SHRINK_LIMIT(exp))
@@ -452,7 +458,7 @@ static void ofd_grant_check(const struct lu_env *env, struct obd_export *exp,
 
        ENTRY;
 
-       LASSERT_SPIN_LOCKED(&ofd->ofd_grant_lock);
+       LASSERT(spin_is_locked(&ofd->ofd_grant_lock));
 
        if ((oa->o_valid & OBD_MD_FLFLAGS) &&
            (oa->o_flags & OBD_FL_RECOV_RESEND)) {
@@ -581,9 +587,11 @@ static void ofd_grant_check(const struct lu_env *env, struct obd_export *exp,
  * \param curgrant - is the current grant claimed by the client
  * \param want - is how much grant space the client would like to have
  * \param left - is the remaining free space with granted space taken out
+ * \param conservative - is how server grants, if true, a certain amount, else
+ *        server will grant as client requested.
  */
 static long ofd_grant(struct obd_export *exp, obd_size curgrant,
-                     obd_size want, obd_size left)
+                     obd_size want, obd_size left, bool conservative)
 {
        struct obd_device               *obd = exp->exp_obd;
        struct ofd_device               *ofd = ofd_exp(exp);
@@ -604,8 +612,8 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant,
 
        /* client not supporting OBD_CONNECT_GRANT_PARAM works with a 4KB block
         * size while the reality is different */
-       curgrant    = ofd_grant_from_cli(exp, ofd, curgrant);
-       want    = ofd_grant_from_cli(exp, ofd, want);
+       curgrant = ofd_grant_from_cli(exp, ofd, curgrant);
+       want = ofd_grant_from_cli(exp, ofd, want);
        grant_chunk = ofd_grant_chunk(exp, ofd);
 
        /* Grant some fraction of the client's requested grant space so that
@@ -620,20 +628,23 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant,
        if (curgrant >= want || curgrant >= fed->fed_grant + grant_chunk)
                   RETURN(0);
 
-       if (!obd->obd_recovering)
+       if (obd->obd_recovering)
+               conservative = false;
+
+       if (conservative)
                /* don't grant more than 1/8th of the remaining free space in
                 * one chunk */
                left >>= 3;
        grant = min(want, left);
-       /* align grant on block size */
-       grant &= ~((1ULL << ofd->ofd_blockbits) - 1);
+       /* round grant upt to the next block size */
+       grant = (grant + (1 << ofd->ofd_blockbits) - 1) &
+               ~((1ULL << ofd->ofd_blockbits) - 1);
 
        if (!grant)
                RETURN(0);
 
-       /* Allow >OFD_GRANT_CHUNK_EXP size when clients reconnect due to a
-        * server reboot. */
-       if ((grant > grant_chunk) && (!obd->obd_recovering))
+       /* Limit to ofd_grant_chunk() if not reconnect/recovery */
+       if ((grant > grant_chunk) && conservative)
                grant = grant_chunk;
 
        ofd->ofd_tot_granted += grant;
@@ -666,9 +677,12 @@ static long ofd_grant(struct obd_export *exp, obd_size curgrant,
  * \param env - is the lu environment provided by the caller
  * \param exp - is the client's export which is reconnecting
  * \param want - is how much the client would like to get
+ * \param conservative - is how server grants to client, if true server will
+ *        only grant certain amount, else server will grant client requested
+ *        amount.
  */
 long ofd_grant_connect(const struct lu_env *env, struct obd_export *exp,
-                      obd_size want)
+                      obd_size want, bool conservative)
 {
        struct ofd_device               *ofd = ofd_exp(exp);
        struct filter_export_data       *fed = &exp->exp_filter_data;
@@ -700,7 +714,7 @@ refresh:
        }
 
        ofd_grant(exp, ofd_grant_to_cli(exp, ofd, (obd_size)fed->fed_grant),
-                 want, left);
+                 want, left, conservative);
 
        /* return to client its current grant */
        grant = ofd_grant_to_cli(exp, ofd, (obd_size)fed->fed_grant);
@@ -859,8 +873,7 @@ refresh:
        /* When close to free space exhaustion, trigger a sync to force
         * writeback cache to consume required space immediately and release as
         * much space as possible. */
-       if (!obd->obd_recovering && force != 2 &&
-           left < ofd_grant_chunk(NULL, ofd)) {
+       if (!obd->obd_recovering && force != 2 && left < OFD_GRANT_CHUNK) {
                bool from_grant = true;
                int  i;
 
@@ -900,7 +913,8 @@ refresh:
                ofd_grant_shrink(exp, oa, left);
        else
                /* grant more space back to the client if possible */
-               oa->o_grant = ofd_grant(exp, oa->o_grant, oa->o_undirty, left);
+               oa->o_grant = ofd_grant(exp, oa->o_grant, oa->o_undirty, left,
+                                       true);
        spin_unlock(&ofd->ofd_grant_lock);
 }
 
@@ -920,7 +934,6 @@ int ofd_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr)
        struct filter_export_data       *fed = &exp->exp_filter_data;
        obd_size                         left = 0;
        unsigned long                    wanted;
-
        ENTRY;
 
        info->fti_used = 0;
@@ -983,9 +996,14 @@ int ofd_grant_create(const struct lu_env *env, struct obd_export *exp, int *nr)
        fed->fed_pending += info->fti_used;
        ofd->ofd_tot_pending += info->fti_used;
 
-       /* grant more space (twice as much as needed for this request) for
-        * precreate purpose if possible */
-       ofd_grant(exp, fed->fed_grant, wanted * 2, left);
+       /* grant more space for precreate purpose if possible. */
+       wanted = OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2;
+       if (wanted > fed->fed_grant) {
+               /* always try to book enough space to handle a large precreate
+                * request */
+               wanted -= fed->fed_grant;
+               ofd_grant(exp, fed->fed_grant, wanted, left, false);
+       }
        spin_unlock(&ofd->ofd_grant_lock);
        RETURN(0);
 }