* We will later calculate the clients new grant and return it.
* Caller must hold osfs lock.
*/
-void filter_grant_incoming(struct obd_export *exp, struct obdo *oa)
+void filter_grant_incoming(const struct lu_env *env, struct obd_export *exp,
+ struct obdo *oa)
{
struct filter_export_data *fed;
struct filter_device *ofd = filter_exp(exp);
LASSERT_SPIN_LOCKED(&obd->obd_osfs_lock);
- /* Check if OST supports grants (OBD_MD_FLGRANT) or allocated block
- * flag is set.
- */
if ((oa->o_valid & (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) !=
- (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) {
+ (OBD_MD_FLBLOCKS|OBD_MD_FLGRANT)) {
oa->o_valid &= ~OBD_MD_FLGRANT;
EXIT;
return;
/* Add some margin, since there is a small race if other RPCs arrive
* out-or-order and have already consumed some grant. We want to
- * leave this here in case there is a large error in accounting.
- */
+ * leave this here in case there is a large error in accounting. */
CDEBUG(D_CACHE,
"%s: cli %s/%p reports grant: "LPU64" dropped: %u, local: %lu\n",
obd->obd_name, exp->exp_client_uuid.uuid, exp, oa->o_grant,
/* Update our accounting now so that statfs takes it into account.
* Note that fed_dirty is only approximate and can become incorrect
* if RPCs arrive out-of-order. No important calculations depend
- * on fed_dirty however, but we must check sanity to not assert.
- */
+ * on fed_dirty however, but we must check sanity to not assert. */
if ((long long)oa->o_dirty < 0)
oa->o_dirty = 0;
else if (oa->o_dirty > fed->fed_grant + 4 * FILTER_GRANT_CHUNK)
ofd->ofd_tot_granted -= oa->o_dropped;
fed->fed_grant -= oa->o_dropped;
fed->fed_dirty = oa->o_dirty;
+
+ if (oa->o_flags & OBD_FL_SHRINK_GRANT) {
+ obd_size left_space = filter_grant_space_left(env, exp);
+
+ /*Only if left_space < fo_tot_clients * 32M,
+ *then the grant space could be shrinked */
+ if (left_space < ofd->ofd_tot_granted_clients *
+ FILTER_GRANT_SHRINK_LIMIT) {
+ fed->fed_grant -= oa->o_grant;
+ ofd->ofd_tot_granted -= oa->o_grant;
+ CDEBUG(D_CACHE, "%s: cli %s/%p shrink "LPU64
+ "fed_grant %ld total "LPU64"\n",
+ obd->obd_name, exp->exp_client_uuid.uuid,
+ exp, oa->o_grant, fed->fed_grant,
+ ofd->ofd_tot_granted);
+ oa->o_grant = 0;
+ }
+ }
+
if (fed->fed_dirty < 0 || fed->fed_grant < 0 || fed->fed_pending < 0) {
CERROR("%s: cli %s/%p dirty %ld pend %ld grant %ld\n",
obd->obd_name, exp->exp_client_uuid.uuid, exp,
OBD_INCOMPAT_COMMON_LR)
#define FILTER_GRANT_CHUNK (2ULL * PTLRPC_MAX_BRW_SIZE)
+#define FILTER_GRANT_SHRINK_LIMIT (16ULL * FILTER_GRANT_CHUNK)
#define GRANT_FOR_LLOG 16
#define FILTER_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */
obd_size ofd_tot_dirty;
obd_size ofd_tot_granted;
obd_size ofd_tot_pending;
+ int ofd_tot_granted_clients;
/* filter mod data: filter_device wide values */
int ofd_fmd_max_num; /* per ofd filter_mod_data */
/* filter_grants.c */
void filter_grant_discard(struct obd_export *exp);
void filter_grant_sanity_check(struct obd_device *obd, const char *func);
-void filter_grant_incoming(struct obd_export *exp, struct obdo *oa);
+void filter_grant_incoming(const struct lu_env *env, struct obd_export *exp,
+ struct obdo *oa);
obd_size filter_grant_space_left(const struct lu_env *env,
struct obd_export *exp);
int filter_grant_client_calc(struct obd_export *exp, obd_size *left,
LPU64" left: "LPU64"\n", exp->exp_obd->obd_name,
exp->exp_client_uuid.uuid, exp,
data->ocd_grant, want, left);
+
+ ofd->ofd_tot_granted_clients ++;
}
if (data->ocd_connect_flags & OBD_CONNECT_INDEX) {
RETURN(rc);
}
+/* reverse import is changed, sync all cancels */
+static void filter_revimp_update(struct obd_export *exp)
+{
+ ENTRY;
+
+ LASSERT(exp);
+ class_export_get(exp);
+
+ /* flush any remaining cancel messages out to the target */
+#if 0
+ filter_sync_llogs(exp->exp_obd, exp);
+#endif
+ class_export_put(exp);
+ EXIT;
+}
+
static int filter_init_export(struct obd_export *exp)
{
spin_lock_init(&exp->exp_filter_data.fed_lock);
* UOSS functionality is implemented. */
filter_fmd_cleanup(exp);
+ if (exp->exp_connect_flags & OBD_CONNECT_GRANT_SHRINK) {
+ if (ofd->ofd_tot_granted_clients > 0)
+ ofd->ofd_tot_granted_clients --;
+ }
+
if (!(exp->exp_flags & OBD_OPT_FORCE))
filter_grant_sanity_check(exp->exp_obd, __FUNCTION__);
return rc;
}
+static int filter_adapt_sptlrpc_conf(struct obd_device *obd, int initial)
+{
+ struct filter_obd *filter = &obd->u.filter;
+ struct sptlrpc_rule_set tmp_rset;
+ int rc;
+
+ sptlrpc_rule_set_init(&tmp_rset);
+ rc = sptlrpc_conf_target_get_rules(obd, &tmp_rset, initial);
+ if (rc) {
+ CERROR("obd %s: failed get sptlrpc rules: %d\n",
+ obd->obd_name, rc);
+ return rc;
+ }
+
+ sptlrpc_target_update_exp_flavor(obd, &tmp_rset);
+
+ write_lock(&filter->fo_sptlrpc_lock);
+ sptlrpc_rule_set_free(&filter->fo_sptlrpc_rset);
+ filter->fo_sptlrpc_rset = tmp_rset;
+ write_unlock(&filter->fo_sptlrpc_lock);
+
+ return 0;
+}
+
static int filter_set_info_async(struct obd_export *exp, __u32 keylen,
void *key, __u32 vallen, void *val,
struct ptlrpc_request_set *set)
{
struct filter_device *ofd = filter_exp(exp);
- struct obd_device *obd;
- int rc = 0, group;
+ struct obd_device *obd;
+ int rc = 0;
+ int group;
+ struct lu_env env;
ENTRY;
obd = exp->exp_obd;
RETURN(-EINVAL);
}
+ rc = lu_env_init(&env, LCT_DT_THREAD);
+ if (rc)
+ RETURN(rc);
+
if (KEY_IS(KEY_CAPA_KEY)) {
rc = filter_update_capa_key(ofd, (struct lustre_capa_key *)val);
if (rc)
CERROR("filter update capability key failed: %d\n", rc);
- RETURN(rc);
+ GOTO(out, rc);
+ }
+
+ if (KEY_IS(KEY_REVIMP_UPD)) {
+ filter_revimp_update(exp);
+ lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd);
+ GOTO(out, rc = 0);
+ }
+
+ if (KEY_IS(KEY_SPTLRPC_CONF)) {
+ filter_adapt_sptlrpc_conf(obd, 0);
+ GOTO(out, rc = 0);
+ }
+
+ if (KEY_IS(KEY_GRANT_SHRINK)) {
+ struct ost_body *body = (struct ost_body *)val;
+ /* handle shrink grant */
+ spin_lock(&exp->exp_obd->obd_osfs_lock);
+ filter_grant_incoming(&env, exp, &body->oa);
+ spin_unlock(&exp->exp_obd->obd_osfs_lock);
+ GOTO(out, rc = 0);
}
if (!KEY_IS(KEY_MDS_CONN))
- RETURN(-EINVAL);
+ GOTO(out, rc = -EINVAL);
LCONSOLE_WARN("%s: received MDS connection from %s\n", obd->obd_name,
obd_export_nid2str(exp));
/* setup llog group 1 for interop */
filter_setup_llog_group(exp, obd, FILTER_GROUP_LLOG);
}
-out:
#endif
+out:
+ lu_env_fini(&env);
RETURN(rc);
}