/* * Note: this function is only used for testing, it is no safe for production * use. */ static int lprocfs_fid_write_common(const char *buffer, unsigned long count, struct lu_seq_range *range) { struct lu_seq_range tmp; int rc; LASSERT(range != NULL); rc = sscanf(buffer, "[%llx - %llx]\n", (long long unsigned *)&tmp.lsr_start, (long long unsigned *)&tmp.lsr_end); if (rc != 2 || !range_is_sane(&tmp) || range_is_zero(&tmp)) return -EINVAL; *range = tmp; return 0; }
/* * This function implements new seq allocation algorithm using async * updates to seq file on disk. ref bug 18857 for details. * there are four variable to keep track of this process * * lss_space; - available lss_space * lss_lowater_set; - lu_seq_range for all seqs before barrier, i.e. safe to use * lss_hiwater_set; - lu_seq_range after barrier, i.e. allocated but may be * not yet committed * * when lss_lowater_set reaches the end it is replaced with hiwater one and * a write operation is initiated to allocate new hiwater range. * if last seq write opearion is still not commited, current operation is * flaged as sync write op. */ static int range_alloc_set(const struct lu_env *env, struct lu_seq_range *out, struct lu_server_seq *seq) { struct lu_seq_range *space = &seq->lss_space; struct lu_seq_range *loset = &seq->lss_lowater_set; struct lu_seq_range *hiset = &seq->lss_hiwater_set; int rc = 0; if (range_is_zero(loset)) __seq_set_init(env, seq); if (OBD_FAIL_CHECK(OBD_FAIL_SEQ_ALLOC)) /* exhaust set */ loset->lsr_start = loset->lsr_end; if (range_is_exhausted(loset)) { /* reached high water mark. */ struct lu_device *dev = seq->lss_site->ss_lu->ls_top_dev; int obd_num_clients = dev->ld_obd->obd_num_exports; __u64 set_sz; /* calculate new seq width based on number of clients */ set_sz = max(seq->lss_set_width, obd_num_clients * seq->lss_width); set_sz = min(range_space(space), set_sz); /* Switch to hiwater range now */ *loset = *hiset; /* allocate new hiwater range */ range_alloc(hiset, space, set_sz); /* update ondisk seq with new *space */ rc = seq_store_update(env, seq, NULL, seq->lss_need_sync); } LASSERTF(!range_is_exhausted(loset) || range_is_sane(loset), DRANGE"\n", PRANGE(loset)); if (rc == 0) range_alloc(out, loset, seq->lss_width); RETURN(rc); }
/* * Note: this function is only used for testing, it is no safe for production * use. */ static int seq_proc_write_common(struct file *file, const char *buffer, unsigned long count, void *data, struct lu_seq_range *range) { struct lu_seq_range tmp; int rc; ENTRY; LASSERT(range != NULL); rc = sscanf(buffer, "[%llx - %llx]\n", (long long unsigned *)&tmp.lsr_start, (long long unsigned *)&tmp.lsr_end); if (rc != 2 || !range_is_sane(&tmp) || range_is_zero(&tmp)) RETURN(-EINVAL); *range = tmp; RETURN(0); }
int seq_server_init(struct lu_server_seq *seq, struct dt_device *dev, const char *prefix, enum lu_mgr_type type, struct seq_server_site *ss, const struct lu_env *env) { int rc, is_srv = (type == LUSTRE_SEQ_SERVER); ENTRY; LASSERT(dev != NULL); LASSERT(prefix != NULL); LASSERT(ss != NULL); LASSERT(ss->ss_lu != NULL); seq->lss_cli = NULL; seq->lss_type = type; seq->lss_site = ss; range_init(&seq->lss_space); range_init(&seq->lss_lowater_set); range_init(&seq->lss_hiwater_set); seq->lss_set_width = LUSTRE_SEQ_BATCH_WIDTH; mutex_init(&seq->lss_mutex); seq->lss_width = is_srv ? LUSTRE_SEQ_META_WIDTH : LUSTRE_SEQ_SUPER_WIDTH; snprintf(seq->lss_name, sizeof(seq->lss_name), "%s-%s", (is_srv ? "srv" : "ctl"), prefix); rc = seq_store_init(seq, env, dev); if (rc) GOTO(out, rc); /* Request backing store for saved sequence info. */ rc = seq_store_read(seq, env); if (rc == -ENODATA) { /* Nothing is read, init by default value. */ seq->lss_space = is_srv ? LUSTRE_SEQ_ZERO_RANGE: LUSTRE_SEQ_SPACE_RANGE; LASSERT(ss != NULL); seq->lss_space.lsr_index = ss->ss_node_id; LCONSOLE_INFO("%s: No data found " "on store. Initialize space\n", seq->lss_name); rc = seq_store_update(env, seq, NULL, 0); if (rc) { CERROR("%s: Can't write space data, " "rc %d\n", seq->lss_name, rc); } } else if (rc) { CERROR("%s: Can't read space data, rc %d\n", seq->lss_name, rc); GOTO(out, rc); } if (is_srv) { LASSERT(range_is_sane(&seq->lss_space)); } else { LASSERT(!range_is_zero(&seq->lss_space) && range_is_sane(&seq->lss_space)); } rc = seq_server_proc_init(seq); if (rc) GOTO(out, rc); EXIT; out: if (rc) seq_server_fini(seq, env); return rc; }