/** * Set threshold for "same space on all OSTs" rule. * * This sets the maximum percentage difference of free space between the most * full and most empty OST in the currently available OSTs. If this percentage * is exceeded, use the QoS allocator to select OSTs based on their available * space so that more full OSTs are chosen less often, otherwise use the * round-robin allocator for efficiency and performance. * \param[in] file proc file * \param[in] buffer string containing percentage difference of free space * \param[in] count @buffer length * \param[in] off unused for single entry * * \retval @count on success * \retval negative error code if failed */ static ssize_t lod_qos_thresholdrr_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; struct obd_device *dev = m->private; struct lod_device *lod; int rc; __s64 val; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '%'); if (rc) return rc; if (val > 100 || val < 0) return -EINVAL; lod->lod_qos.lq_threshold_rr = (val << 8) / 100; lod->lod_qos.lq_dirty = 1; return count; }
/** * Set default number of stripes. * * \param[in] file proc file * \param[in] buffer string containing the default number of stripes * for new files * \param[in] count @buffer length * \param[in] off unused for single entry * * \retval @count on success * \retval negative error code otherwise */ static ssize_t lod_stripecount_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; struct obd_device *dev = m->private; struct lod_device *lod; int rc; __s64 val; __u32 stripe_count; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); rc = lprocfs_str_to_s64(buffer, count, &val); if (rc) return rc; if (val < 0) return -ERANGE; stripe_count = val; lod_fix_desc_stripe_count(&stripe_count); lod->lod_desc.ld_default_stripe_count = stripe_count; return count; }
/** * Show expiration period used to refresh cached statfs data, which * is used to implement QoS/RR striping allocation algorithm. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_qos_maxage_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, "%u Sec\n", lod->lod_desc.ld_qos_maxage); }
/** * Show QoS priority parameter. * * The printed value is a percentage value (0-100%) indicating the priority * of free space compared to performance. 0% means select OSTs equally * regardless of their free space, 100% means select OSTs only by their free * space even if it results in very imbalanced load on the OSTs. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_qos_priofree_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev); LASSERT(lod != NULL); return seq_printf(m, "%d%%\n", (lod->lod_qos.lq_prio_free * 100 + 255) >> 8); }
/** * Show number of active targets. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_activeobd_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, "%u\n", lod->lod_desc.ld_active_tgt_count); }
/** * Show default striping pattern (LOV_PATTERN_*). * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_stripetype_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, "%u\n", lod->lod_desc.ld_pattern); }
/** * Show UUID of LOD device. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_desc_uuid_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); seq_printf(m, "%s\n", lod->lod_desc.ld_uuid.uuid); return 0; }
/** * Show default stripe size. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_stripesize_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, LPU64"\n", lod->lod_desc.ld_default_stripe_size); }
/** * Show threshold for "same space on all OSTs" rule. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success * \retval negative error code if failed */ static int lod_qos_thresholdrr_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, "%d%%\n", (lod->lod_qos.lq_threshold_rr * 100 + 255) >> 8); }
/** * Show default number of stripes. * * \param[in] m seq file * \param[in] v unused for single entry * * \retval 0 on success, * \retval negative error code if failed */ static int lod_stripecount_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; struct lod_device *lod; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); return seq_printf(m, "%d\n", (__s16)(lod->lod_desc.ld_default_stripe_count + 1) - 1); }
/** * Set default number of stripes. * * \param[in] file proc file * \param[in] buffer string containing the default number of stripes * for new files * \param[in] count @buffer length * \param[in] off unused for single entry * * \retval @count on success * \retval negative error code otherwise */ static ssize_t lod_stripecount_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; struct obd_device *dev = m->private; struct lod_device *lod; int val, rc; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); rc = lprocfs_write_helper(buffer, count, &val); if (rc) return rc; lod_fix_desc_stripe_count(&val); lod->lod_desc.ld_default_stripe_count = val; return count; }
/** * Set expiration period used to refresh cached statfs data. * * \param[in] file proc file * \param[in] buffer string contains maximum age of statfs data in seconds * \param[in] count @buffer length * \param[in] off unused for single entry * * \retval @count on success * \retval negative error code if failed */ static ssize_t lod_qos_maxage_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; struct obd_device *dev = m->private; struct lustre_cfg_bufs bufs; struct lod_device *lod; struct lu_device *next; struct lustre_cfg *lcfg; char str[32]; unsigned int i; int rc; __s64 val; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); rc = lprocfs_str_to_s64(buffer, count, &val); if (rc) return rc; if (val <= 0) return -EINVAL; lod->lod_desc.ld_qos_maxage = val; /* * propogate the value down to OSPs */ lustre_cfg_bufs_reset(&bufs, NULL); snprintf(str, 32, "%smaxage=%u", PARAM_OSP, (__u32)val); lustre_cfg_bufs_set_string(&bufs, 1, str); lcfg = lustre_cfg_new(LCFG_PARAM, &bufs); if (lcfg == NULL) return -ENOMEM; lod_getref(&lod->lod_ost_descs); lod_foreach_ost(lod, i) { next = &OST_TGT(lod,i)->ltd_ost->dd_lu_dev; rc = next->ld_ops->ldo_process_config(NULL, next, lcfg); if (rc) CERROR("can't set maxage on #%d: %d\n", i, rc); }
/** * Set QoS free space priority parameter. * * Set the relative priority of free OST space compared to OST load when OSTs * are space imbalanced. See lod_qos_priofree_seq_show() for description of * this parameter. See lod_qos_thresholdrr_seq_write() and lq_threshold_rr to * determine what constitutes "space imbalanced" OSTs. * * \param[in] file proc file * \param[in] buffer string which contains the free space priority (0-100) * \param[in] count @buffer length * \param[in] off unused for single entry * * \retval @count on success * \retval negative error code if failed */ static ssize_t lod_qos_priofree_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; struct obd_device *dev = m->private; struct lod_device *lod; int val, rc; LASSERT(dev != NULL); lod = lu2lod_dev(dev->obd_lu_dev); rc = lprocfs_write_helper(buffer, count, &val); if (rc) return rc; if (val > 100) return -EINVAL; lod->lod_qos.lq_prio_free = (val << 8) / 100; lod->lod_qos.lq_dirty = 1; lod->lod_qos.lq_reset = 1; return count; }