tools/testing/selftests/ublk/stripe.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/ublk/stripe.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/ublk/stripe.c
Extension
.c
Size
10446 bytes
Lines
397
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct stripe_conf {
	unsigned nr_files;
	unsigned shift;
};

struct stripe {
	loff_t 		start;
	unsigned 	nr_sects;
	int 		seq;

	struct iovec 	*vec;
	unsigned 	nr_vec;
	unsigned 	cap;
};

struct stripe_array {
	struct stripe 	s[NR_STRIPE];
	unsigned 	nr;
	struct iovec 	_vec[];
};

static inline const struct stripe_conf *get_chunk_shift(const struct ublk_queue *q)
{
	return (struct stripe_conf *)q->dev->private_data;
}

static inline unsigned calculate_nr_vec(const struct stripe_conf *conf,
		const struct ublksrv_io_desc *iod)
{
	const unsigned shift = conf->shift - 9;
	const unsigned unit_sects = conf->nr_files << shift;
	loff_t start = iod->start_sector;
	loff_t end = start + iod->nr_sectors;

	return (end / unit_sects) - (start / unit_sects) + 1;
}

static struct stripe_array *alloc_stripe_array(const struct stripe_conf *conf,
		const struct ublksrv_io_desc *iod)
{
	unsigned nr_vecs = calculate_nr_vec(conf, iod);
	unsigned total = nr_vecs * conf->nr_files;
	struct stripe_array *s;
	int i;

	s = malloc(sizeof(*s) + total * sizeof(struct iovec));

	s->nr = 0;
	for (i = 0; i < conf->nr_files; i++) {
		struct stripe *t = &s->s[i];

		t->nr_vec = 0;
		t->vec = &s->_vec[i * nr_vecs];
		t->nr_sects = 0;
		t->cap = nr_vecs;
	}

	return s;
}

static void free_stripe_array(struct stripe_array *s)
{
	free(s);
}

static void calculate_stripe_array(const struct stripe_conf *conf,
		const struct ublksrv_io_desc *iod, struct stripe_array *s, void *base)
{
	const unsigned shift = conf->shift - 9;
	const unsigned chunk_sects = 1 << shift;
	const unsigned unit_sects = conf->nr_files << shift;
	off64_t start = iod->start_sector;
	off64_t end = start + iod->nr_sectors;
	unsigned long done = 0;
	unsigned idx = 0;

	while (start < end) {
		unsigned nr_sects = chunk_sects - (start & (chunk_sects - 1));
		loff_t unit_off = (start / unit_sects) * unit_sects;
		unsigned seq = (start - unit_off) >> shift;
		struct stripe *this = &s->s[idx];
		loff_t stripe_off = (unit_off / conf->nr_files) +
			(start & (chunk_sects - 1));

		if (nr_sects > end - start)
			nr_sects = end - start;
		if (this->nr_sects == 0) {
			this->nr_sects = nr_sects;
			this->start = stripe_off;
			this->seq = seq;

Annotation

Implementation Notes