Whamcloud - gitweb
LU-14826 mdt: getattr_name("..") under striped directory
[fs/lustre-release.git] / lustre / lmv / lmv_obd.c
index 5236e44..717e410 100644 (file)
@@ -1461,9 +1461,11 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
 
 static struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 *mdt)
 {
-       struct lu_tgt_desc *tgt;
+       struct lu_tgt_desc *tgt, *cur = NULL;
+       __u64 total_avail = 0;
        __u64 total_weight = 0;
        __u64 cur_weight = 0;
+       int total_usable = 0;
        __u64 rand;
        int rc;
 
@@ -1482,13 +1484,29 @@ static struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 *mdt)
                GOTO(unlock, tgt = ERR_PTR(rc));
 
        lmv_foreach_tgt(lmv, tgt) {
-               tgt->ltd_qos.ltq_usable = 0;
-               if (!tgt->ltd_exp || !tgt->ltd_active)
+               if (!tgt->ltd_exp || !tgt->ltd_active) {
+                       tgt->ltd_qos.ltq_usable = 0;
                        continue;
+               }
 
                tgt->ltd_qos.ltq_usable = 1;
                lu_tgt_qos_weight_calc(tgt);
+               if (tgt->ltd_index == *mdt)
+                       cur = tgt;
+               total_avail += tgt->ltd_qos.ltq_avail;
                total_weight += tgt->ltd_qos.ltq_weight;
+               total_usable++;
+       }
+
+       /* if current MDT has above-average space, within range of the QOS
+        * threshold, stay on the same MDT to avoid creating needless remote
+        * MDT directories.
+        */
+       rand = total_avail * (256 - lmv->lmv_qos.lq_threshold_rr) /
+               (total_usable * 256);
+       if (cur && cur->ltd_qos.ltq_avail >= rand) {
+               tgt = cur;
+               GOTO(unlock, rc = 0);
        }
 
        rand = lu_prandom_u64_max(total_weight);
@@ -1958,7 +1976,11 @@ lmv_getattr_name(struct obd_export *exp,struct md_op_data *op_data,
        ENTRY;
 
 retry:
-       tgt = lmv_locate_tgt(lmv, op_data);
+       if (op_data->op_namelen == 2 &&
+           op_data->op_name[0] == '.' && op_data->op_name[1] == '.')
+               tgt = lmv_fid2tgt(lmv, &op_data->op_fid1);
+       else
+               tgt = lmv_locate_tgt(lmv, op_data);
        if (IS_ERR(tgt))
                RETURN(PTR_ERR(tgt));
 
@@ -3410,7 +3432,7 @@ lmv_lock_match(struct obd_export *exp, __u64 flags,
 }
 
 static int
-lmv_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req,
+lmv_get_lustre_md(struct obd_export *exp, struct req_capsule *pill,
                  struct obd_export *dt_exp, struct obd_export *md_exp,
                  struct lustre_md *md)
 {
@@ -3420,7 +3442,7 @@ lmv_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req,
        if (!tgt || !tgt->ltd_exp)
                return -EINVAL;
 
-       return md_get_lustre_md(tgt->ltd_exp, req, dt_exp, md_exp, md);
+       return md_get_lustre_md(tgt->ltd_exp, pill, dt_exp, md_exp, md);
 }
 
 static int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
@@ -3478,9 +3500,9 @@ static int lmv_clear_open_replay_data(struct obd_export *exp,
 }
 
 static int lmv_intent_getattr_async(struct obd_export *exp,
-                                   struct md_enqueue_info *minfo)
+                                   struct md_op_item *item)
 {
-       struct md_op_data *op_data = &minfo->mi_data;
+       struct md_op_data *op_data = &item->mop_data;
        struct obd_device *obd = exp->exp_obd;
        struct lmv_obd *lmv = &obd->u.lmv;
        struct lmv_tgt_desc *ptgt;
@@ -3507,7 +3529,7 @@ static int lmv_intent_getattr_async(struct obd_export *exp,
        if (ctgt != ptgt)
                RETURN(-EREMOTE);
 
-       rc = md_intent_getattr_async(ptgt->ltd_exp, minfo);
+       rc = md_intent_getattr_async(ptgt->ltd_exp, item);
 
        RETURN(rc);
 }