summaryrefslogtreecommitdiff
path: root/src/logic/tpax_queue_vector.c
blob: 092f39f18704a80d89184dd01d183750eafb4729 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**************************************************************/
/*  tpax: a topological pax implementation                    */
/*  Copyright (C) 2020--2024  SysDeer Technologies, LLC       */
/*  Released under GPLv2 and GPLv3; see COPYING.TPAX.         */
/**************************************************************/

#include <stdint.h>
#include <stdlib.h>

#include <tpax/tpax.h>
#include "tpax_driver_impl.h"
#include "tpax_errinfo_impl.h"
#include "tpax_visibility_impl.h"

tpax_hidden int tpax_update_queue_vector(const struct tpax_driver_ctx * dctx)
{
	uintptr_t                       addr;
	struct tpax_driver_ctx_impl *   ictx;
	struct tpax_dirent_buffer *     dentbuf;
	struct tpax_dirent **           direntv;
	struct tpax_dirent *            cdent;
	struct tpax_dirent *            cnext;
	size_t                          arrsize;

	/* driver */
	ictx = tpax_get_driver_ictx(dctx);

	/* vector alloc */
	if (ictx->direntv)
		free(ictx->direntv);

	arrsize = ictx->nqueued + 1;

	if (!(ictx->direntv = calloc(arrsize,sizeof(struct tpax_dirent *))))
		return TPAX_SYSTEM_ERROR(dctx);

	if (ictx->nqueued == 0)
		return 0;

	/* queue vector */
	dentbuf = tpax_get_driver_dirents(dctx);
	cdent   = dentbuf->dbuf;

	for (direntv=ictx->direntv; cdent; direntv++) {
		*direntv = cdent;

		addr  = (uintptr_t)cdent;
		addr += cdent->nsize;
		cnext = (struct tpax_dirent *)addr;

		if (cnext == dentbuf->cdent) {
			dentbuf = dentbuf->next;
			cnext   = dentbuf ? dentbuf->dbuf : 0;
		}

		cdent = cnext;
	}

	return 0;
}