@@ -1770,46 +1770,39 @@ int lmv_old_layout_lookup(struct lmv_obd *lmv, struct md_op_data *op_data)
return rc;
}
+/* mkdir by QoS upon 'lfs mkdir -i -1'.
+ *
+ * NB, mkdir by QoS only if parent is not striped, this is to avoid remote
+ * directories under striped directory.
+ */
static inline bool lmv_op_user_qos_mkdir(const struct md_op_data *op_data)
{
const struct lmv_user_md *lum = op_data->op_data;
+ if (op_data->op_code != LUSTRE_OPC_MKDIR)
+ return false;
+
+ if (lmv_dir_striped(op_data->op_mea1))
+ return false;
+
return (op_data->op_cli_flags & CLI_SET_MEA) && lum &&
le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC &&
le32_to_cpu(lum->lum_stripe_offset) == LMV_OFFSET_DEFAULT;
}
+/* mkdir by QoS if either ROOT or parent default LMV is space balanced. */
static inline bool lmv_op_default_qos_mkdir(const struct md_op_data *op_data)
{
const struct lmv_stripe_md *lsm = op_data->op_default_mea1;
- return (op_data->op_flags & MF_QOS_MKDIR) ||
- (lsm && lsm->lsm_md_master_mdt_index == LMV_OFFSET_DEFAULT);
-}
-
-/* mkdir by QoS in three cases:
- * 1. ROOT default LMV is space balanced.
- * 2. 'lfs mkdir -i -1'
- * 3. parent default LMV master_mdt_index is -1
- *
- * NB, mkdir by QoS only if parent is not striped, this is to avoid remote
- * directories under striped directory.
- */
-static inline bool lmv_op_qos_mkdir(const struct md_op_data *op_data)
-{
if (op_data->op_code != LUSTRE_OPC_MKDIR)
return false;
if (lmv_dir_striped(op_data->op_mea1))
return false;
- if (lmv_op_user_qos_mkdir(op_data))
- return true;
-
- if (lmv_op_default_qos_mkdir(op_data))
- return true;
-
- return false;
+ return (op_data->op_flags & MF_QOS_MKDIR) ||
+ (lsm && lsm->lsm_md_master_mdt_index == LMV_OFFSET_DEFAULT);
}
/* if parent default LMV is space balanced, and
@@ -1853,6 +1846,38 @@ static inline bool lmv_op_user_specific_mkdir(const struct md_op_data *op_data)
LMV_OFFSET_DEFAULT;
}
+/* locate MDT by space usage */
+static struct lu_tgt_desc *lmv_locate_tgt_by_space(struct lmv_obd *lmv,
+ struct md_op_data *op_data,
+ struct lmv_tgt_desc *tgt)
+{
+ struct lmv_tgt_desc *tmp = tgt;
+
+ tgt = lmv_locate_tgt_qos(lmv, op_data->op_mds, op_data->op_dir_depth);
+ if (tgt == ERR_PTR(-EAGAIN)) {
+ if (ltd_qos_is_balanced(&lmv->lmv_mdt_descs) &&
+ !lmv_op_default_rr_mkdir(op_data) &&
+ !lmv_op_user_qos_mkdir(op_data))
+ /* if not necessary, don't create remote directory. */
+ tgt = tmp;
+ else
+ tgt = lmv_locate_tgt_rr(lmv);
+ }
+
+ /*
+ * only update statfs after QoS mkdir, this means the cached statfs may
+ * be stale, and current mkdir may not follow QoS accurately, but it's
+ * not serious, and avoids periodic statfs when client doesn't mkdir by
+ * QoS.
+ */
+ if (!IS_ERR(tgt)) {
+ op_data->op_mds = tgt->ltd_index;
+ lmv_statfs_check_update(lmv2obd_dev(lmv), tgt);
+ }
+
+ return tgt;
+}
+
int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
const void *data, size_t datalen, umode_t mode, uid_t uid,
gid_t gid, kernel_cap_t cap_effective, u64 rdev,
@@ -1886,6 +1911,12 @@ int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
+ /* the order to apply policy in mkdir:
+ * 1. is "lfs mkdir -i N"? mkdir on MDT N.
+ * 2. is "lfs mkdir -i -1"? mkdir by space usage.
+ * 3. is starting MDT specified in default LMV? mkdir on MDT N.
+ * 4. is default LMV space balanced? mkdir by space usage.
+ */
if (lmv_op_user_specific_mkdir(op_data)) {
struct lmv_user_md *lum = op_data->op_data;
@@ -1893,39 +1924,20 @@ int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
tgt = lmv_tgt(lmv, op_data->op_mds);
if (!tgt)
return -ENODEV;
+ } else if (lmv_op_user_qos_mkdir(op_data)) {
+ tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
} else if (lmv_op_default_specific_mkdir(op_data)) {
op_data->op_mds =
op_data->op_default_mea1->lsm_md_master_mdt_index;
tgt = lmv_tgt(lmv, op_data->op_mds);
if (!tgt)
return -ENODEV;
- } else if (lmv_op_qos_mkdir(op_data)) {
- struct lmv_tgt_desc *tmp = tgt;
-
- tgt = lmv_locate_tgt_qos(lmv, op_data->op_mds,
- op_data->op_dir_depth);
- if (tgt == ERR_PTR(-EAGAIN)) {
- if (ltd_qos_is_balanced(&lmv->lmv_mdt_descs) &&
- !lmv_op_default_rr_mkdir(op_data) &&
- !lmv_op_user_qos_mkdir(op_data))
- /* if it's not necessary, don't create remote
- * directory.
- */
- tgt = tmp;
- else
- tgt = lmv_locate_tgt_rr(lmv);
- }
+ } else if (lmv_op_default_qos_mkdir(op_data)) {
+ tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
-
- op_data->op_mds = tgt->ltd_index;
- /*
- * only update statfs after QoS mkdir, this means the cached
- * statfs may be stale, and current mkdir may not follow QoS
- * accurately, but it's not serious, and avoids periodic statfs
- * when client doesn't mkdir by QoS.
- */
- lmv_statfs_check_update(obd, tgt);
}
retry: